diff --git a/.github/workflows/sonarcloud-analysis.yml b/.github/workflows/sonarcloud-analysis.yml index 1b0ca65c6..03a3355cc 100644 --- a/.github/workflows/sonarcloud-analysis.yml +++ b/.github/workflows/sonarcloud-analysis.yml @@ -71,9 +71,9 @@ jobs: - name: Set Common Sonar Variables id: sonar_env run: | - echo "##[set-output name=sonar_opts;]$(echo -Dsonar.host.url=https://sonarcloud.io \ + echo "sonar_opts=-Dsonar.host.url=https://sonarcloud.io \ -Dsonar.projectKey=com-pas_compas-sct \ - -Dsonar.organization=com-pas )" + -Dsonar.organization=com-pas" >> $GITHUB_OUTPUT - name: Create custom Maven Settings.xml uses: whelk-io/maven-settings-xml-action@v21 with: diff --git a/docs/QUICK_START.md b/docs/QUICK_START.md index 550e5128b..8a441541f 100644 --- a/docs/QUICK_START.md +++ b/docs/QUICK_START.md @@ -1,4 +1,4 @@ - + # CoMPAS SCT (Substation Configuration Tool) @@ -17,13 +17,13 @@ First you need to add following dependencies to the pom.xml of your repository. org.lfenergy.compas sct-commons - 0.1.0 + 0.2.12 org.lfenergy.compas sct-app - 0.1.0 + 0.2.12 ``` Actually there are 4 packages available: @@ -37,15 +37,20 @@ Actually there are 4 packages available: Now that you have your **compas-sct** dependency set, you can start communicating with Commons SCT services. **sct-commons** provides a collection of services to help you build SCL files for a range of use cases. + Following services provides needed functions compliant with IEC 61850 : -1. **SclService** -2. **SubstationService** +1. **SclEditorService** +2. **SclElementsProviderService** +3. **SubstationService** +4. **ExtRefService** +5. **HmiService** Let's start with a simple **SclService** call ```java -var scl = SclService.initScl(Optional.empty(), "1.0", "1.0"); +SclEditor sclEditorService = new SclEditorService(); +SCL scl = sclEditorService.initScl(UUID.randomUUID(), "1.0", "1.0"); marshaller.marshal(scl.getCurrentElem(), System.out); ``` @@ -78,11 +83,15 @@ Start it by using existing files of type `SSD` and `STD` and running the following : ```java -// ssd : SSD -// std : STD +// ssd : SCL object represent an SSD file +// std : SCL object represent an STD file +SclEditor sclService = new SclEditorService(); +SubstationEditor substationService = new SubstationService(); HeaderDTO headerDTO = new HeaderDTO(UUID.randomUUID(), "1.0", "1.0"); -var scl = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std)); -marshaller.marshal(scl.getCurrentElem(), System.out); + +SclAutomationService sclAutomationService = new SclAutomationService(sclService, substationService); +SCL scl = sclAutomationService.createSCD(ssd, headerDTO, List.of(std)); +marshaller.marshal(scl, System.out); ``` When the command completes, it prints XML output representing completed **SCL** file. Its structure resembles the following: diff --git a/docs/examples/example-app/pom.xml b/docs/examples/example-app/pom.xml index 52bf33115..d255c6df7 100644 --- a/docs/examples/example-app/pom.xml +++ b/docs/examples/example-app/pom.xml @@ -18,9 +18,9 @@ SPDX-License-Identifier: Apache-2.0 UTF-8 - 11 - 11 - 11 + 17 + 17 + 17 @@ -44,13 +44,13 @@ SPDX-License-Identifier: Apache-2.0 org.lfenergy.compas sct-commons - 0.1.0 + 0.2.12 org.lfenergy.compas sct-app - 0.1.0 + 0.2.12 org.junit.jupiter diff --git a/docs/examples/example-app/src/main/java/org/lfenergy/compas/sct/examples/SctAppExample.java b/docs/examples/example-app/src/main/java/org/lfenergy/compas/sct/examples/SctAppExample.java index b0c2bbfcf..63d4f4797 100644 --- a/docs/examples/example-app/src/main/java/org/lfenergy/compas/sct/examples/SctAppExample.java +++ b/docs/examples/example-app/src/main/java/org/lfenergy/compas/sct/examples/SctAppExample.java @@ -1,32 +1,33 @@ -// SPDX-FileCopyrightText: 2022 RTE FRANCE +// SPDX-FileCopyrightText: 2022 2023 RTE FRANCE // // SPDX-License-Identifier: Apache-2.0 package org.lfenergy.compas.sct.examples; import org.lfenergy.compas.scl2007b4.model.SCL; -import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; -import org.lfenergy.compas.sct.commons.scl.SclService; +import org.lfenergy.compas.sct.commons.SclEditorService; +import org.lfenergy.compas.sct.commons.api.SclEditor; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; import javax.xml.bind.Marshaller; -import java.util.Optional; import java.util.UUID; public class SctAppExample { + private static final SclEditor sclEditor = new SclEditorService(); + public static void main( String[] args ) throws JAXBException { - initSclWithSclService(Optional.empty(), "1.0", "1.0"); + initSclWithSclService(UUID.randomUUID(), "1.0", "1.0"); } - public static SclRootAdapter initSclWithSclService(Optional hId, String hVersion, String hRevision) throws JAXBException { - SclRootAdapter scl = SclService.initScl(hId, hVersion, hRevision); - marshaller.marshal(scl.getCurrentElem(), System.out); + public static SCL initSclWithSclService(UUID hId, String hVersion, String hRevision) throws JAXBException { + SCL scl = sclEditor.initScl(hId, hVersion, hRevision); + marshaller.marshal(scl, System.out); return scl; } - private static Marshaller marshaller; + private static final Marshaller marshaller; static{ try { JAXBContext context = JAXBContext.newInstance(SCL.class); diff --git a/docs/examples/example-app/src/test/java/org/lfenergy/compas/sct/examples/SctAppExampleTest.java b/docs/examples/example-app/src/test/java/org/lfenergy/compas/sct/examples/SctAppExampleTest.java index d2fbca3f1..6dc504830 100644 --- a/docs/examples/example-app/src/test/java/org/lfenergy/compas/sct/examples/SctAppExampleTest.java +++ b/docs/examples/example-app/src/test/java/org/lfenergy/compas/sct/examples/SctAppExampleTest.java @@ -10,38 +10,36 @@ import javax.xml.bind.JAXBException; import java.util.List; -import java.util.Optional; import java.util.UUID; -import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.Assertions.assertThat; -public class SctAppExampleTest { +class SctAppExampleTest { @Test - public void initSclWithSclServiceTest() throws JAXBException { + void initSclWithSclServiceTest() throws JAXBException { // Given : Header attributes - Optional headerId = Optional.of(UUID.randomUUID()); + UUID headerId = UUID.randomUUID(); String headerVersion = SclRootAdapter.VERSION; String headerRevision = SclRootAdapter.REVISION; // When: Sct Service - SclRootAdapter scl = SctAppExample - .initSclWithSclService(headerId, headerVersion, headerRevision); + SCL scl = SctAppExample.initSclWithSclService(headerId, headerVersion, headerRevision); // Then - assertNotNull(scl.getCurrentElem().getHeader()); - assertEquals(headerId.get().toString(), scl.getCurrentElem().getHeader().getId()); - assertEquals(headerVersion, scl.getCurrentElem().getHeader().getVersion()); - assertEquals(headerRevision, scl.getCurrentElem().getHeader().getRevision()); - THeader.History history = scl.getCurrentElem().getHeader().getHistory(); - List substations = scl.getCurrentElem().getSubstation(); - TCommunication communication = scl.getCurrentElem().getCommunication(); - List iedList = scl.getCurrentElem().getIED(); - TDataTypeTemplates dataTypeTemplates = scl.getCurrentElem().getDataTypeTemplates(); - assertNull(history); - assertEquals(0, substations.size()); - assertNull(communication); - assertEquals(0, iedList.size()); - assertNull(dataTypeTemplates); + assertThat(scl.getHeader()).isNotNull(); + assertThat(scl.getHeader().getId()).isEqualTo(headerId.toString()); + assertThat(scl.getHeader().getVersion()).isEqualTo(headerVersion); + assertThat(scl.getHeader().getRevision()).isEqualTo(headerRevision); + THeader.History history = scl.getHeader().getHistory(); + List substations = scl.getSubstation(); + TCommunication communication = scl.getCommunication(); + List iedList = scl.getIED(); + TDataTypeTemplates dataTypeTemplates = scl.getDataTypeTemplates(); + assertThat(history).isNull(); + assertThat(substations).isEmpty(); + assertThat(communication).isNull(); + assertThat(iedList).isEmpty(); + assertThat(dataTypeTemplates).isNull(); } } diff --git a/pom.xml b/pom.xml index 8adfb6c6a..65e41b5df 100644 --- a/pom.xml +++ b/pom.xml @@ -44,6 +44,7 @@ 1.4.5 3.22.0 1.18.24 + 5.5.0 2.13.4.1 @@ -78,6 +79,18 @@ ${junit-version} test + + org.mockito + mockito-core + ${mockito.version} + test + + + org.mockito + mockito-junit-jupiter + ${mockito.version} + test + org.lfenergy.compas.core scl-extension diff --git a/sct-app/pom.xml b/sct-app/pom.xml index f2ea2dca7..42afea091 100644 --- a/sct-app/pom.xml +++ b/sct-app/pom.xml @@ -58,6 +58,14 @@ org.assertj assertj-core + + org.mockito + mockito-core + + + org.mockito + mockito-junit-jupiter + 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 234f86698..9046f6966 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 @@ -5,13 +5,14 @@ package org.lfenergy.compas.sct.app; import lombok.NonNull; +import lombok.RequiredArgsConstructor; import org.lfenergy.compas.scl2007b4.model.SCL; +import org.lfenergy.compas.sct.commons.api.SclEditor; +import org.lfenergy.compas.sct.commons.api.SubstationEditor; import org.lfenergy.compas.sct.commons.dto.HeaderDTO; import org.lfenergy.compas.sct.commons.dto.SubNetworkDTO; import org.lfenergy.compas.sct.commons.dto.SubNetworkTypeDTO; import org.lfenergy.compas.sct.commons.exception.ScdException; -import org.lfenergy.compas.sct.commons.scl.SclService; -import org.lfenergy.compas.sct.commons.scl.SubstationService; import java.util.*; @@ -24,8 +25,12 @@ *
  • {@link SclAutomationService#createSCD(SCL, HeaderDTO, List) Adds all elements under the SCL object from given SSD and STD files} * */ +@RequiredArgsConstructor public class SclAutomationService { + private final SclEditor sclEditor; + private final SubstationEditor substationEditor; + /** * Possible Subnetwork and ConnectedAP names which should be used in generated SCD in order a have global coherence * Configuration based on used framework can be used to externalize this datas @@ -34,10 +39,6 @@ public class SclAutomationService { new SubNetworkTypeDTO("RSPACE_PROCESS_NETWORK", SubNetworkDTO.SubnetworkType.MMS.toString(), List.of("PROCESS_AP", "TOTO_AP_GE")), new SubNetworkTypeDTO("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString(), List.of("ADMIN_AP", "TATA_AP_EFFACEC"))); - private SclAutomationService() { - throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); - } - /** * Create an SCD file from specified parameters, it calls all functions defined in the process one by one, every step * return an SCD file which will be used by the next step. @@ -47,15 +48,15 @@ private SclAutomationService() { * @return an SCD object * @throws ScdException */ - public static SCL createSCD(@NonNull SCL ssd, @NonNull HeaderDTO headerDTO, List stds) throws ScdException { - SCL scd = SclService.initScl(headerDTO.getId(), headerDTO.getVersion(), headerDTO.getRevision()); + public SCL createSCD(@NonNull SCL ssd, @NonNull HeaderDTO headerDTO, List stds) throws ScdException { + SCL scd = sclEditor.initScl(headerDTO.getId(), headerDTO.getVersion(), headerDTO.getRevision()); if (!headerDTO.getHistoryItems().isEmpty()) { HeaderDTO.HistoryItem hItem = headerDTO.getHistoryItems().get(0); - SclService.addHistoryItem(scd, hItem.getWho(), hItem.getWhat(), hItem.getWhy()); + sclEditor.addHistoryItem(scd, hItem.getWho(), hItem.getWhat(), hItem.getWhy()); } - SubstationService.addSubstation(scd, ssd); - SclService.importSTDElementsInSCD(scd, stds, SUB_NETWORK_TYPES); - SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scd); + substationEditor.addSubstation(scd, ssd); + sclEditor.importSTDElementsInSCD(scd, stds, SUB_NETWORK_TYPES); + sclEditor.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 new file mode 100644 index 000000000..1a10626f2 --- /dev/null +++ b/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceIntegrationTest.java @@ -0,0 +1,167 @@ +// SPDX-FileCopyrightText: 2023 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.app; + +import org.junit.jupiter.api.BeforeEach; +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.SubstationService; +import org.lfenergy.compas.sct.commons.api.SclEditor; +import org.lfenergy.compas.sct.commons.api.SubstationEditor; +import org.lfenergy.compas.sct.commons.dto.HeaderDTO; +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.LDeviceAdapter; +import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; + +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.*; +import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable; + +class SclAutomationServiceIntegrationTest { + + private SclAutomationService sclAutomationService ; + private static final SclEditor sclEditor = new SclEditorService() ; + private static final SubstationEditor substationEditor = new SubstationService() ; + + private HeaderDTO headerDTO; + + @BeforeEach + void setUp() { + headerDTO = new HeaderDTO(); + headerDTO.setId(UUID.randomUUID()); + headerDTO.setRevision("hRevision"); + headerDTO.setVersion("hVersion"); + sclAutomationService = new SclAutomationService(sclEditor, substationEditor); + } + + @Test + void createSCD_should_return_generatedSCD() { + // Given + SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml"); + SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); + // When + SCL scd = sclAutomationService.createSCD(ssd, headerDTO, List.of(std)); + // Then + assertNotNull(scd.getHeader().getId()); + assertNull(scd.getHeader().getHistory()); + assertEquals(1, scd.getSubstation().size()); + assertEquals(1, scd.getIED().size()); + assertNotNull(scd.getDataTypeTemplates()); + assertEquals(2, scd.getCommunication().getSubNetwork().size()); + assertIsMarshallable(scd); + } + + @Test + void createSCD_With_HItem() { + // Given + HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem(); + historyItem.setWhat("what"); + historyItem.setWho("me"); + historyItem.setWhy("because"); + headerDTO.getHistoryItems().add(historyItem); + SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); + SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml"); + SCL std2 = SclTestMarshaller.getSCLFromFile("/std_2.xml"); + SCL std3 = SclTestMarshaller.getSCLFromFile("/std_3.xml"); + // When + SCL scd = sclAutomationService.createSCD(ssd, headerDTO, List.of(std1, std2, std3)); + // Then + assertNotNull(scd.getHeader().getId()); + assertEquals(1, scd.getHeader().getHistory().getHitem().size()); + assertEquals(1, scd.getSubstation().size()); + assertIsMarshallable(scd); + } + + @Test + void createSCD_With_HItems() { + // Given + HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem(); + historyItem.setWhat("what"); + historyItem.setWho("me"); + historyItem.setWhy("because"); + HeaderDTO.HistoryItem historyItemBis = new HeaderDTO.HistoryItem(); + historyItemBis.setWhat("what Bis"); + historyItemBis.setWho("me bis"); + historyItemBis.setWhy("because bis"); + headerDTO.getHistoryItems().addAll(Arrays.asList(historyItem, historyItemBis)); + SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); + SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml"); + SCL std2 = SclTestMarshaller.getSCLFromFile("/std_2.xml"); + SCL std3 = SclTestMarshaller.getSCLFromFile("/std_3.xml"); + // When + SCL scd = sclAutomationService.createSCD(ssd, headerDTO, List.of(std1, std2, std3)); + // Then + assertNotNull(scd.getHeader().getId()); + assertEquals(1, scd.getHeader().getHistory().getHitem().size()); + assertEquals("what", scd.getHeader().getHistory().getHitem().get(0).getWhat()); + assertIsMarshallable(scd); + } + + @Test + void createSCD_SSD_Without_Substation() { + // Given + SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd_without_substations.xml"); + // When & Then + List stdListEmpty = List.of(); + assertThrows(ScdException.class, + () -> sclAutomationService.createSCD(ssd, headerDTO, stdListEmpty)); + } + + @Test + void createSCD_should_throw_exception_when_null_ssd() { + // Given + HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem(); + historyItem.setWhat("what"); + historyItem.setWho("me"); + historyItem.setWhy("because"); + headerDTO.getHistoryItems().add(historyItem); + SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml"); + List stdList = List.of(std1); + + // When & Then + assertThrows(NullPointerException.class, () -> sclAutomationService.createSCD(null, headerDTO, stdList)); + } + + @Test + void createSCD_should_throw_exception_when_null_headerDTO() { + // Given + SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); + SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml"); + List stdList = List.of(std1); + + // When & Then + assertThrows(NullPointerException.class, () -> sclAutomationService.createSCD(ssd, null, stdList)); + } + + @Test + void createSCD_should_delete_ControlBlocks_DataSet_and_ExtRef_src_attributes() { + // Given + SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml"); + SCL std = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); + // When + SCL scd = sclAutomationService.createSCD(ssd, headerDTO, List.of(std)); + // Then + LN0 ln0 = new SclRootAdapter(scd).streamIEDAdapters() + .findFirst() + .map(iedAdapter -> iedAdapter.findLDeviceAdapterByLdInst("lDeviceInst1").orElseThrow()) + .map(LDeviceAdapter::getLN0Adapter) + .map(SclElementAdapter::getCurrentElem) + .orElseThrow(() -> new RuntimeException("Test shouldn't fail here, please check your XML input file")); + + assertThat(ln0.getDataSet()).isEmpty(); + assertThat(ln0.getInputs().getExtRef()).hasSize(2); + assertFalse(ln0.getInputs().getExtRef().get(0).isSetSrcLDInst()); + assertIsMarshallable(scd); + } + +} 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 1feb4f25e..f9e64e100 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 @@ -1,173 +1,192 @@ -// SPDX-FileCopyrightText: 2021 RTE FRANCE +// SPDX-FileCopyrightText: 2023 RTE FRANCE // // SPDX-License-Identifier: Apache-2.0 package org.lfenergy.compas.sct.app; +import org.apache.commons.beanutils.BeanUtils; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; -import org.lfenergy.compas.scl2007b4.model.LN0; +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.SclEditor; +import org.lfenergy.compas.sct.commons.api.SubstationEditor; import org.lfenergy.compas.sct.commons.dto.HeaderDTO; 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.LDeviceAdapter; -import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.Mockito; +import org.mockito.junit.jupiter.MockitoExtension; -import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; -import java.util.Arrays; import java.util.List; import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; -import static org.assertj.core.api.Assertions.assertThatThrownBy; -import static org.junit.jupiter.api.Assertions.*; +import static org.assertj.core.api.AssertionsForClassTypes.assertThatThrownBy; import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.Mockito.*; +@ExtendWith(MockitoExtension.class) class SclAutomationServiceTest { + @InjectMocks + private SclAutomationService sclAutomationService ; + @Mock + private SclEditor sclEditor; + @Mock + private SubstationEditor substationEditor; + + public static final short RELEASE = 4; + public static final String REVISION = "B"; + public static final String VERSION = "2007"; + private SCL scl; private HeaderDTO headerDTO; @BeforeEach - void init() { + void setUp() { + scl = new SCL(); + scl.setRelease(RELEASE); + scl.setVersion(VERSION); + scl.setRevision(REVISION); + THeader header = new THeader(); + header.setId(UUID.randomUUID().toString()); + scl.setHeader(header); headerDTO = new HeaderDTO(); headerDTO.setId(UUID.randomUUID()); - headerDTO.setRevision("hRevision"); - headerDTO.setVersion("hVersion"); + headerDTO.setRevision("Revision"); + headerDTO.setVersion("Version"); } @Test - void createSCD_should_return_generatedSCD() { + void createSCD_without_headerHistory_should_return_generatedSCD() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { // Given - SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml"); - SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); + SCL ssd = (SCL) BeanUtils.cloneBean(scl); + SCL std = (SCL) BeanUtils.cloneBean(scl); + Mockito.when(sclEditor.initScl(any(UUID.class), anyString(), anyString())).thenReturn((SCL) BeanUtils.cloneBean(scl)); // When - SCL scd = SclAutomationService.createSCD(ssd, headerDTO, List.of(std)); + SCL scd = sclAutomationService.createSCD(ssd, headerDTO, List.of(std)); // Then - assertNotNull(scd.getHeader().getId()); - assertNull(scd.getHeader().getHistory()); - assertEquals(1, scd.getSubstation().size()); - assertEquals(1, scd.getIED().size()); - assertNotNull(scd.getDataTypeTemplates()); - assertEquals(2, scd.getCommunication().getSubNetwork().size()); + assertThat(scd.getHeader()).isNotNull(); + assertThat(scd.getHeader().getHistory()).isNull(); + assertThat(scd.getDataTypeTemplates()).isNull(); + assertThat(scd.getCommunication()).isNull(); + assertThat(scd.getSubstation()).isEmpty(); + assertThat(scd.getIED()).isEmpty(); assertIsMarshallable(scd); + verify(sclEditor, times(1)).initScl(headerDTO.getId(), headerDTO.getVersion(), headerDTO.getRevision()); + 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)); } @Test - void createSCD_With_HItem() { + void createSCD_with_headerHistory_should_return_generatedSCD() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { // Given + SCL ssd = (SCL) BeanUtils.cloneBean(scl); + SCL std = (SCL) BeanUtils.cloneBean(scl); HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem(); - historyItem.setWhat("what"); - historyItem.setWho("me"); - historyItem.setWhy("because"); + historyItem.setWhat("test"); + historyItem.setWho("name"); + historyItem.setWhy("test"); headerDTO.getHistoryItems().add(historyItem); - SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); - SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml"); - SCL std2 = SclTestMarshaller.getSCLFromFile("/std_2.xml"); - SCL std3 = SclTestMarshaller.getSCLFromFile("/std_3.xml"); + when(sclEditor.initScl(any(UUID.class), anyString(), anyString())).thenReturn((SCL) BeanUtils.cloneBean(scl)); + doNothing().when(sclEditor).addHistoryItem(any(SCL.class), anyString(), anyString(), anyString()); // When - SCL scd = SclAutomationService.createSCD(ssd, headerDTO, List.of(std1, std2, std3)); + SCL scd = sclAutomationService.createSCD(ssd, headerDTO, List.of(std)); // Then - assertNotNull(scd.getHeader().getId()); - assertEquals(1, scd.getHeader().getHistory().getHitem().size()); - assertEquals(1, scd.getSubstation().size()); + assertThat(scd.getHeader()).isNotNull(); + assertThat(scd.getHeader().getHistory()).isNull(); + assertThat(scd.getDataTypeTemplates()).isNull(); + assertThat(scd.getCommunication()).isNull(); + assertThat(scd.getSubstation()).isEmpty(); + assertThat(scd.getIED()).isEmpty(); assertIsMarshallable(scd); + verify(sclEditor, times(1)).initScl(headerDTO.getId(), headerDTO.getVersion(), headerDTO.getRevision()); + 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)); } @Test - void createSCD_With_HItems() { + void createSCD_should_throw_exception_when_sclEditor_initScl_Fail() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { // Given - HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem(); - historyItem.setWhat("what"); - historyItem.setWho("me"); - historyItem.setWhy("because"); - HeaderDTO.HistoryItem historyItemBis = new HeaderDTO.HistoryItem(); - historyItemBis.setWhat("what Bis"); - historyItemBis.setWho("me bis"); - historyItemBis.setWhy("because bis"); - headerDTO.getHistoryItems().addAll(Arrays.asList(historyItem, historyItemBis)); - SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); - SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml"); - SCL std2 = SclTestMarshaller.getSCLFromFile("/std_2.xml"); - SCL std3 = SclTestMarshaller.getSCLFromFile("/std_3.xml"); - // When - SCL scd = SclAutomationService.createSCD(ssd, headerDTO, List.of(std1, std2, std3)); - // Then - assertNotNull(scd.getHeader().getId()); - assertEquals(1, scd.getHeader().getHistory().getHitem().size()); - assertEquals("what", scd.getHeader().getHistory().getHitem().get(0).getWhat()); - assertIsMarshallable(scd); + SCL ssd = (SCL) BeanUtils.cloneBean(scl); + SCL std = (SCL) BeanUtils.cloneBean(scl); + doThrow(new ScdException("initScl fail")).when(sclEditor).initScl(any(UUID.class), anyString(), anyString()); + // When Then + assertThatThrownBy(() -> sclAutomationService.createSCD(ssd, headerDTO, List.of(std))) + .isInstanceOf(ScdException.class) + .hasMessage("initScl fail"); } @Test - void createSCD_SSD_Without_Substation() { + void createSCD_should_throw_exception_when_sclEditor_addHistoryItem_Fail() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { // Given - SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd_without_substations.xml"); - // When & Then - List stdListEmpty = List.of(); - assertThrows(ScdException.class, - () -> SclAutomationService.createSCD(ssd, headerDTO, stdListEmpty)); + SCL ssd = (SCL) BeanUtils.cloneBean(scl); + SCL std = (SCL) BeanUtils.cloneBean(scl); + headerDTO.getHistoryItems().add(new HeaderDTO.HistoryItem()); + when(sclEditor.initScl(any(UUID.class), anyString(), anyString())).thenReturn((SCL) BeanUtils.cloneBean(scl)); + doThrow(new ScdException("addHistoryItem fail")).when(sclEditor).addHistoryItem(any(SCL.class), any(), any(), any()); + // When Then + assertThatThrownBy(() -> sclAutomationService.createSCD(ssd, headerDTO, List.of(std))) + .isInstanceOf(ScdException.class) + .hasMessage("addHistoryItem fail"); } @Test - void createSCD_should_throw_exception_when_null_ssd() { + void createSCD_should_throw_exception_when_substationEditor_addSubstation_Fail() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { // Given - HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem(); - historyItem.setWhat("what"); - historyItem.setWho("me"); - historyItem.setWhy("because"); - headerDTO.getHistoryItems().add(historyItem); - SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml"); - List stdList = List.of(std1); - - // When & Then - assertThrows(NullPointerException.class, () -> SclAutomationService.createSCD(null, headerDTO, stdList)); + SCL ssd = (SCL) BeanUtils.cloneBean(scl); + SCL std = (SCL) BeanUtils.cloneBean(scl); + headerDTO.getHistoryItems().add(new HeaderDTO.HistoryItem()); + when(sclEditor.initScl(any(UUID.class), anyString(), anyString())).thenReturn((SCL) BeanUtils.cloneBean(scl)); + doNothing().when(sclEditor).addHistoryItem(any(SCL.class), any(), any(), any()); + doThrow(new ScdException("addSubstation fail")).when(substationEditor).addSubstation(any(SCL.class), any(SCL.class)); + // When Then + assertThatThrownBy(() -> sclAutomationService.createSCD(ssd, headerDTO, List.of(std))) + .isInstanceOf(ScdException.class) + .hasMessage("addSubstation fail"); } @Test - void createSCD_should_throw_exception_when_null_headerDTO() { + void createSCD_should_throw_exception_when_sclEditor_importSTDElementsInSCD_Fail() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { // Given - SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); - SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml"); - List stdList = List.of(std1); - - // When & Then - assertThrows(NullPointerException.class, () -> SclAutomationService.createSCD(ssd, null, stdList)); + SCL ssd = (SCL) BeanUtils.cloneBean(scl); + SCL std = (SCL) BeanUtils.cloneBean(scl); + headerDTO.getHistoryItems().add(new HeaderDTO.HistoryItem()); + when(sclEditor.initScl(any(UUID.class), anyString(), anyString())).thenReturn((SCL) BeanUtils.cloneBean(scl)); + doNothing().when(sclEditor).addHistoryItem(any(SCL.class), any(), any(), any()); + doNothing().when(substationEditor).addSubstation(any(SCL.class), any(SCL.class)); + doThrow(new ScdException("importSTDElementsInSCD fail")) + .when(sclEditor).importSTDElementsInSCD(any(SCL.class), anyList(), anyList()); + // When Then + assertThatThrownBy(() -> sclAutomationService.createSCD(ssd, headerDTO, List.of(std))) + .isInstanceOf(ScdException.class) + .hasMessage("importSTDElementsInSCD fail"); } @Test - void createSCD_should_delete_ControlBlocks_DataSet_and_ExtRef_src_attributes() { + void createSCD_should_throw_exception_when_sclEditor_removeAllControlBlocksAndDatasetsAndExtRefSrcBindings_Fail() throws InvocationTargetException, IllegalAccessException, InstantiationException, NoSuchMethodException { // Given - SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml"); - SCL std = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); - // When - SCL scd = SclAutomationService.createSCD(ssd, headerDTO, List.of(std)); - // Then - LN0 ln0 = new SclRootAdapter(scd).streamIEDAdapters() - .findFirst() - .map(iedAdapter -> iedAdapter.findLDeviceAdapterByLdInst("lDeviceInst1").orElseThrow()) - .map(LDeviceAdapter::getLN0Adapter) - .map(SclElementAdapter::getCurrentElem) - .orElseThrow(() -> new RuntimeException("Test shouldn't fail here, please check your XML input file")); - - assertThat(ln0.getDataSet()).isEmpty(); - assertThat(ln0.getInputs().getExtRef()).hasSize(2); - assertFalse(ln0.getInputs().getExtRef().get(0).isSetSrcLDInst()); - assertIsMarshallable(scd); + SCL ssd = (SCL) BeanUtils.cloneBean(scl); + SCL std = (SCL) BeanUtils.cloneBean(scl); + headerDTO.getHistoryItems().add(new HeaderDTO.HistoryItem()); + when(sclEditor.initScl(any(UUID.class), anyString(), anyString())).thenReturn((SCL) BeanUtils.cloneBean(scl)); + doNothing().when(sclEditor).addHistoryItem(any(SCL.class), any(), any(), any()); + 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 Then + assertThatThrownBy(() -> sclAutomationService.createSCD(ssd, headerDTO, List.of(std))) + .isInstanceOf(ScdException.class) + .hasMessage("removeAllControlBlocksAndDatasetsAndExtRefSrcBindings fail"); } - @Test - void class_should_not_be_instantiable() { - // Given - Constructor[] constructors = SclAutomationService.class.getDeclaredConstructors(); - assertThat(constructors).hasSize(1); - Constructor constructor = constructors[0]; - constructor.setAccessible(true); - // When & Then - assertThatThrownBy(constructor::newInstance) - .isInstanceOf(InvocationTargetException.class) - .getCause().isInstanceOf(UnsupportedOperationException.class); - } } diff --git a/sct-commons/pom.xml b/sct-commons/pom.xml index c95154fb6..b91c97336 100644 --- a/sct-commons/pom.xml +++ b/sct-commons/pom.xml @@ -21,7 +21,6 @@ ${basedir}/${aggregate.report.dir} **/scl2007b4/**/* 5.7.1 - 4.9.0 @@ -70,28 +69,14 @@ junit-jupiter-params test - - org.hamcrest - hamcrest - 2.2 - test - org.mockito mockito-core - ${mockito.version} - test - - - org.mockito - mockito-inline - ${mockito.version} test org.mockito mockito-junit-jupiter - ${mockito.version} test diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefService.java similarity index 72% rename from sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java rename to sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefService.java index 00ccd1b23..1375e8854 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefService.java @@ -2,43 +2,92 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.lfenergy.compas.sct.commons.scl; +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.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.scl.ied.*; import org.lfenergy.compas.sct.commons.util.*; -import org.lfenergy.compas.scl2007b4.model.SCL; -import org.lfenergy.compas.scl2007b4.model.TCompasICDHeader; -import org.lfenergy.compas.scl2007b4.model.TExtRef; -import org.lfenergy.compas.scl2007b4.model.TIED; -import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings; -import org.lfenergy.compas.sct.commons.dto.SclReportItem; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.*; import static org.lfenergy.compas.sct.commons.util.CommonConstants.*; import static org.lfenergy.compas.sct.commons.util.Utils.isExtRefFeedBySameControlBlock; -public final class ExtRefService { +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"; - private static final String MESSAGE_MISSING_IED_NAME_PARAMETER = "IED.name parameter is missing"; + @Override + public void updateExtRefBinders(SCL scd, ExtRefInfo extRefInfo) throws ScdException { + if (extRefInfo.getBindingInfo() == null || extRefInfo.getSignalInfo() == null) { + throw new ScdException("ExtRef Signal and/or Binding information are missing"); + } + String iedName = extRefInfo.getHolderIEDName(); + String ldInst = extRefInfo.getHolderLDInst(); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); + LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst) + .orElseThrow(() -> new ScdException(String.format("Unknown LDevice (%s) in IED (%s)", ldInst, iedName))); + + AbstractLNAdapter abstractLNAdapter = AbstractLNAdapter.builder() + .withLDeviceAdapter(lDeviceAdapter) + .withLnClass(extRefInfo.getHolderLnClass()) + .withLnInst(extRefInfo.getHolderLnInst()) + .withLnPrefix(extRefInfo.getHolderLnPrefix()) + .build(); - private ExtRefService() { - throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); + abstractLNAdapter.updateExtRefBinders(extRefInfo); } - /** - * Updates iedName attribute of all ExtRefs in the Scd. - * - * @return list of encountered errors - */ - public static List updateAllExtRefIedNames(SCL scd) { + @Override + public TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws ScdException { + String iedName = extRefInfo.getHolderIEDName(); + String ldInst = extRefInfo.getHolderLDInst(); + String lnClass = extRefInfo.getHolderLnClass(); + String lnInst = extRefInfo.getHolderLnInst(); + String prefix = extRefInfo.getHolderLnPrefix(); + + ExtRefSignalInfo signalInfo = extRefInfo.getSignalInfo(); + if (signalInfo == null || !signalInfo.isValid()) { + throw new ScdException("Invalid or missing attributes in ExtRef signal info"); + } + ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo(); + if (bindingInfo == null || !bindingInfo.isValid()) { + throw new ScdException(INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO); + } + if (bindingInfo.getIedName().equals(iedName) || TServiceType.POLL.equals(bindingInfo.getServiceType())) { + throw new ScdException("Internal binding can't have control block"); + } + ExtRefSourceInfo sourceInfo = extRefInfo.getSourceInfo(); + if (sourceInfo == null || !sourceInfo.isValid()) { + throw new ScdException(INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO); + } + + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); + LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst); + AbstractLNAdapter anLNAdapter = AbstractLNAdapter.builder() + .withLDeviceAdapter(lDeviceAdapter) + .withLnClass(lnClass) + .withLnInst(lnInst) + .withLnPrefix(prefix) + .build(); + return anLNAdapter.updateExtRefSource(extRefInfo); + } + + @Override + public List updateAllExtRefIedNames(SCL scd) { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); List iedErrors = validateIed(sclRootAdapter); if (!iedErrors.isEmpty()) { @@ -62,13 +111,84 @@ public static List updateAllExtRefIedNames(SCL scd) { .flatMap(List::stream).toList(); } - private static List validateIed(SclRootAdapter sclRootAdapter) { + @Override + public List createDataSetAndControlBlocks(SCL scd) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + Stream lDeviceAdapters = sclRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters); + return createDataSetAndControlBlocks(lDeviceAdapters); + } + + @Override + public List createDataSetAndControlBlocks(SCL scd, String targetIedName) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName); + return createDataSetAndControlBlocks(iedAdapter.streamLDeviceAdapters()); + + } + + @Override + public List createDataSetAndControlBlocks(SCL scd, String targetIedName, String targetLDeviceInst) { + if (StringUtils.isBlank(targetIedName)) { + throw new ScdException("IED.name parameter is missing"); + } + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName); + LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(targetLDeviceInst); + return createDataSetAndControlBlocks(Stream.of(lDeviceAdapter)); + } + + private List createDataSetAndControlBlocks(Stream lDeviceAdapters) { + return lDeviceAdapters + .map(LDeviceAdapter::createDataSetAndControlBlocks) + .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 List manageBindingForLDEPF(SCL scd, ILDEPFSettings settings) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + List sclReportItems = new ArrayList<>(); + sclRootAdapter.streamIEDAdapters() + .filter(iedAdapter -> !iedAdapter.getName().equals(IED_TEST_NAME)) + .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())); + } + } + })) + ); + return sclReportItems; + + } + + private List validateIed(SclRootAdapter sclRootAdapter) { List iedErrors = new ArrayList<>(checkIedCompasIcdHeaderAttributes(sclRootAdapter)); iedErrors.addAll(checkIedUnityOfIcdSystemVersionUuid(sclRootAdapter)); return iedErrors; } - private static List checkIedCompasIcdHeaderAttributes(SclRootAdapter sclRootAdapter) { + private List checkIedCompasIcdHeaderAttributes(SclRootAdapter sclRootAdapter) { return sclRootAdapter.streamIEDAdapters() .map(iedAdapter -> { Optional compasPrivate = iedAdapter.getCompasICDHeader(); @@ -86,9 +206,9 @@ private static List checkIedCompasIcdHeaderAttributes(SclRootAdap .toList(); } - private static List checkIedUnityOfIcdSystemVersionUuid(SclRootAdapter sclRootAdapter) { + private List checkIedUnityOfIcdSystemVersionUuid(SclRootAdapter sclRootAdapter) { Map> systemVersionToIedList = sclRootAdapter.getCurrentElem().getIED().stream() - .collect(Collectors.groupingBy(ied -> PrivateService.extractCompasPrivate(ied, TCompasICDHeader.class) + .collect(Collectors.groupingBy(ied -> PrivateUtils.extractCompasPrivate(ied, TCompasICDHeader.class) .map(TCompasICDHeader::getICDSystemVersionUUID) .orElse(""))); @@ -104,81 +224,7 @@ private static List checkIedUnityOfIcdSystemVersionUuid(SclRootAd .toList(); } - /** - * 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 - * @return list of encountered errors - */ - public static List createDataSetAndControlBlocks(SCL scd) { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - Stream lDeviceAdapters = sclRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters); - return createDataSetAndControlBlocks(lDeviceAdapters); - } - - /** - * 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 - * @return list of encountered errors - */ - public static List createDataSetAndControlBlocks(SCL scd, String targetIedName) { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName); - return createDataSetAndControlBlocks(iedAdapter.streamLDeviceAdapters()); - - } - - /** - * Create All DataSet and ControlBlock for the ExtRef in this 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 - * @return list of encountered errors - */ - public static List createDataSetAndControlBlocks(SCL scd, String targetIedName, String targetLDeviceInst) { - if (StringUtils.isBlank(targetIedName)) { - throw new ScdException(MESSAGE_MISSING_IED_NAME_PARAMETER); - } - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(targetIedName); - LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(targetLDeviceInst); - return createDataSetAndControlBlocks(Stream.of(lDeviceAdapter)); - } - - private static List createDataSetAndControlBlocks(Stream lDeviceAdapters) { - return lDeviceAdapters - .map(LDeviceAdapter::createDataSetAndControlBlocks) - .flatMap(List::stream) - .toList(); - } - - /** - * 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 - */ - public static 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; - } - private static List configureNetworkForControlBlocks(SCL scd, ControlBlockNetworkSettings controlBlockNetworkSettings, + 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()); @@ -194,7 +240,7 @@ private static List configureNetworkForControlBlocks(SCL scd, Con .flatMap(Optional::stream) .toList(); } - private static Optional configureControlBlockNetwork(ControlBlockNetworkSettings controlBlockNetworkSettings, PrimitiveIterator.OfLong appIdIterator, Iterator macAddressIterator, ControlBlockAdapter controlBlockAdapter) { + 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( @@ -236,41 +282,7 @@ public static List filterDuplicatedExtRefs(List tExtRefs) { return filteredList; } - /** - * ExtRef Binding For LDevice (inst=LDEPF) that matching LDEPF configuration - * @param scd SCL - * @param settings ILDEPFSettings - * @return list of encountered errors - */ - public static List manageBindingForLDEPF(SCL scd, ILDEPFSettings settings) { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - List sclReportItems = new ArrayList<>(); - sclRootAdapter.streamIEDAdapters() - .filter(iedAdapter -> !iedAdapter.getName().equals(IED_TEST_NAME)) - .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())); - } - } - })) - ); - return sclReportItems; - - } - - private static void updateLDEPFExtRefBinding(TExtRef extRef, TIED iedSource, LDEPFSettingData setting) { + private void updateLDEPFExtRefBinding(TExtRef extRef, TIED iedSource, LDEPFSettingData setting) { extRef.setIedName(iedSource.getName()); extRef.setLdInst(setting.getLdInst()); extRef.getLnClass().add(setting.getLnClass()); @@ -282,7 +294,7 @@ private static void updateLDEPFExtRefBinding(TExtRef extRef, TIED iedSource, LDE extRef.setDoName(doName); } - private static List updateLDEPFDos(LDeviceAdapter lDeviceAdapter, TExtRef extRef, LDEPFSettingData setting) { + private List updateLDEPFDos(LDeviceAdapter lDeviceAdapter, TExtRef extRef, LDEPFSettingData setting) { List sclReportItems = new ArrayList<>(); List doNameAndDaNameList = List.of( new DoNameAndDaName(CHNUM1_DO_NAME, DU_DA_NAME), @@ -307,7 +319,7 @@ private static List updateLDEPFDos(LDeviceAdapter lDeviceAdapter, return sclReportItems; } - private static Optional updateVal(AbstractLNAdapter lnAdapter, String doName, String daName, TExtRef extRef, LDEPFSettingData setting) { + private Optional updateVal(AbstractLNAdapter lnAdapter, String doName, String daName, TExtRef extRef, LDEPFSettingData setting) { String value = switch (daName) { case DU_DA_NAME -> setting.getChannelShortLabel(); case SETVAL_DA_NAME -> @@ -322,7 +334,7 @@ private static Optional updateVal(AbstractLNAdapter lnAdapter, private record DoNameAndDaName(String doName, String daName) { } - private static String computeDaiValue(AbstractLNAdapter lnAdapter, TExtRef extRef, String daName) { + private String computeDaiValue(AbstractLNAdapter lnAdapter, TExtRef extRef, String daName) { if (LN_PREFIX_B.equals(lnAdapter.getPrefix()) || LN_PREFIX_A.equals(lnAdapter.getPrefix())) { return extRef.getIedName() + extRef.getLdInst() + "/" + diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/HmiService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/HmiService.java similarity index 51% rename from sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/HmiService.java rename to sct-commons/src/main/java/org/lfenergy/compas/sct/commons/HmiService.java index 9b72b2544..ef9477aa8 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/HmiService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/HmiService.java @@ -2,26 +2,20 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.lfenergy.compas.sct.commons.scl; +package org.lfenergy.compas.sct.commons; import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TFCDA; +import org.lfenergy.compas.sct.commons.api.HmiEditor; +import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter; import java.util.List; -public final class HmiService { +public class HmiService implements HmiEditor { - private HmiService() { - throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); - } - - /** - * Create the DataSet and ReportControl Blocks for the HMI with the given FCDAs. - * - * @param fcdas List of FCDA for which we must create the DataSet and ReportControl Blocks - */ - public static void createAllHmiReportControlBlocks(SCL scd, List fcdas) { + @Override + public void createAllHmiReportControlBlocks(SCL scd, List fcdas) { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); sclRootAdapter.streamIEDAdapters() .flatMap(IEDAdapter::streamLDeviceAdapters) 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/SclEditorService.java new file mode 100644 index 000000000..f52cc3b27 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SclEditorService.java @@ -0,0 +1,238 @@ +// SPDX-FileCopyrightText: 2021 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons; + +import lombok.NonNull; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.tuple.Pair; +import org.lfenergy.compas.scl2007b4.model.*; +import org.lfenergy.compas.sct.commons.api.SclEditor; +import org.lfenergy.compas.sct.commons.dto.*; +import org.lfenergy.compas.sct.commons.exception.ScdException; +import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import org.lfenergy.compas.sct.commons.scl.com.CommunicationAdapter; +import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter; +import org.lfenergy.compas.sct.commons.scl.com.SubNetworkAdapter; +import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter; +import org.lfenergy.compas.sct.commons.scl.dtt.LNodeTypeAdapter; +import org.lfenergy.compas.sct.commons.scl.header.HeaderAdapter; +import org.lfenergy.compas.sct.commons.scl.icd.IcdHeader; +import org.lfenergy.compas.sct.commons.scl.ied.*; +import org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter; +import org.lfenergy.compas.sct.commons.util.PrivateUtils; +import org.lfenergy.compas.sct.commons.util.Utils; + +import java.util.*; + +import static org.lfenergy.compas.sct.commons.util.CommonConstants.IED_TEST_NAME; +import static org.lfenergy.compas.sct.commons.util.PrivateEnum.COMPAS_ICDHEADER; + +@Slf4j +public class SclEditorService implements SclEditor { + + @Override + public SCL initScl(final UUID hId, final String hVersion, final String hRevision) throws ScdException { + SclRootAdapter scdAdapter = new SclRootAdapter(hId.toString(), hVersion, hRevision); + scdAdapter.addPrivate(PrivateUtils.createPrivate(TCompasSclFileType.SCD)); + return scdAdapter.getCurrentElem(); + } + + @Override + public void addHistoryItem(SCL scd, String who, String what, String why) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + HeaderAdapter headerAdapter = sclRootAdapter.getHeaderAdapter(); + headerAdapter.addHistoryItem(who, what, why); + } + + @Override + public void updateHeader(@NonNull SCL scd, @NonNull HeaderDTO headerDTO) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + HeaderAdapter headerAdapter = sclRootAdapter.getHeaderAdapter(); + boolean hUpdated = false; + String hVersion = headerDTO.getVersion(); + String hRevision = headerDTO.getRevision(); + if (hVersion != null && !hVersion.equals(headerAdapter.getHeaderVersion())) { + headerAdapter.updateVersion(hVersion); + hUpdated = true; + } + if (hRevision != null && !hRevision.equals(headerAdapter.getHeaderRevision())) { + headerAdapter.updateRevision(hRevision); + hUpdated = true; + } + if (hUpdated && !headerDTO.getHistoryItems().isEmpty()) { + headerAdapter.addHistoryItem( + headerDTO.getHistoryItems().get(0).getWho(), + headerDTO.getHistoryItems().get(0).getWhat(), + headerDTO.getHistoryItems().get(0).getWhy() + ); + } + } + + @Override + public void addIED(SCL scd, String iedName, SCL icd) throws ScdException { + new SclRootAdapter(scd).addIED(icd, iedName); + } + + @Override + public void addSubnetworks(SCL scd, List subNetworks, SCL icd) throws ScdException { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + CommunicationAdapter communicationAdapter; + if (!subNetworks.isEmpty()) { + communicationAdapter = sclRootAdapter.getCommunicationAdapter(true); + for (SubNetworkDTO subNetworkDTO : subNetworks) { + String snName = subNetworkDTO.getName(); + String snType = subNetworkDTO.getType(); + for (ConnectedApDTO accessPoint : subNetworkDTO.getConnectedAPs()) { + String iedName = accessPoint.iedName(); + String apName = accessPoint.apName(); + communicationAdapter.addSubnetwork(snName, snType, iedName, apName); + + Optional subNetworkAdapter = communicationAdapter.getSubnetworkByName(snName); + if (subNetworkAdapter.isPresent()) { + ConnectedAPAdapter connectedAPAdapter = subNetworkAdapter.get().getConnectedAPAdapter(iedName, apName); + connectedAPAdapter.copyAddressAndPhysConnFromIcd(icd); + } + } + } + } + } + + @Override + public void updateDAI(SCL scd, String iedName, String ldInst, DataAttributeRef dataAttributeRef) throws ScdException { + long startTime = System.nanoTime(); + log.info(Utils.entering()); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + DataTypeTemplateAdapter dttAdapter = sclRootAdapter.getDataTypeTemplateAdapter(); + LNodeTypeAdapter lNodeTypeAdapter = dttAdapter.getLNodeTypeAdapterById(dataAttributeRef.getLnType()) + .orElseThrow(() -> new ScdException("Unknown LNodeType : " + dataAttributeRef.getLnType())); + lNodeTypeAdapter.check(dataAttributeRef.getDoName(), dataAttributeRef.getDaName()); + + if (TPredefinedBasicTypeEnum.OBJ_REF == dataAttributeRef.getBType()) { + Long sGroup = dataAttributeRef.getDaName().getDaiValues().keySet().stream().findFirst().orElse(-1L); + String val = sGroup < 0 ? null : dataAttributeRef.getDaName().getDaiValues().get(sGroup); + sclRootAdapter.checkObjRef(val); + } + + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); + LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst) + .orElseThrow(() -> new ScdException(String.format("Unknown LDevice (%s) in IED (%s)", ldInst, iedName))); + + AbstractLNAdapter lnAdapter = AbstractLNAdapter.builder() + .withLDeviceAdapter(lDeviceAdapter) + .withLnClass(dataAttributeRef.getLnClass()) + .withLnInst(dataAttributeRef.getLnInst()) + .withLnPrefix(dataAttributeRef.getPrefix()) + .build(); + + if (TPredefinedCDCEnum.ING == dataAttributeRef.getCdc() || TPredefinedCDCEnum.ASG == dataAttributeRef.getCdc()) { + DAITracker daiTracker = new DAITracker(lnAdapter, dataAttributeRef.getDoName(), dataAttributeRef.getDaName()); + daiTracker.validateBoundedDAI(); + } + lnAdapter.updateDAI(dataAttributeRef); + log.info(Utils.leaving(startTime)); + } + + @Override + public void importSTDElementsInSCD(SCL scd, List stds, List subNetworkTypes) throws ScdException { + + //Check SCD and STD compatibilities + Map mapICDSystemVersionUuidAndSTDFile = PrivateUtils.createMapICDSystemVersionUuidAndSTDFile(stds); + PrivateUtils.checkSTDCorrespondanceWithLNodeCompasICDHeader(mapICDSystemVersionUuidAndSTDFile); + // List all Private and remove duplicated one with same iedName + // For each Private.ICDSystemVersionUUID and Private.iedName find STD File + List iedNamesUsed = new ArrayList<>(); + SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); + PrivateUtils.streamIcdHeaders(scd) + .forEach(icdHeader -> { + if (!iedNamesUsed.contains(icdHeader.getIedName())) { + String iedName = icdHeader.getIedName(); + iedNamesUsed.add(iedName); + String icdSysVerUuid = icdHeader.getIcdSystemVersionUUID(); + if (!mapICDSystemVersionUuidAndSTDFile.containsKey(icdSysVerUuid)) + throw new ScdException("There is no STD file found corresponding to " + icdHeader); + // import /ied /dtt in Scd + SCL std = mapICDSystemVersionUuidAndSTDFile.get(icdSysVerUuid).stdList().get(0); + SclRootAdapter stdRootAdapter = new SclRootAdapter(std); + IEDAdapter stdIedAdapter = new IEDAdapter(stdRootAdapter, std.getIED().get(0)); + Optional optionalTPrivate = stdIedAdapter.getPrivateHeader(COMPAS_ICDHEADER.getPrivateType()); + if (optionalTPrivate.isPresent() && optionalTPrivate.flatMap(PrivateUtils::extractCompasICDHeader).map(IcdHeader::new).get().equals(icdHeader)) { + PrivateUtils.copyCompasICDHeaderFromLNodePrivateIntoSTDPrivate(optionalTPrivate.get(), icdHeader.toTCompasICDHeader()); + } else throw new ScdException("COMPAS-ICDHeader is not the same in Substation and in IED"); + scdRootAdapter.addIED(std, iedName); + + //import connectedAP and rename ConnectedAP/@iedName + TCommunication communication = stdRootAdapter.getCurrentElem().getCommunication(); + List subNetworkDTOSet = SubNetworkDTO.createDefaultSubnetwork(iedName, communication, subNetworkTypes); + addSubnetworks(scdRootAdapter.getCurrentElem(), subNetworkDTOSet, std); + } + }); + } + + @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); + } + + @Override + public List updateLDeviceStatus(SCL scd) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + SubstationAdapter substationAdapter = sclRootAdapter.getSubstationAdapter(); + final List> iedNameLdInstList = substationAdapter.getIedAndLDeviceNamesForLN0FromLNode(); + return sclRootAdapter.streamIEDAdapters() + .flatMap(IEDAdapter::streamLDeviceAdapters) + .map(LDeviceAdapter::getLN0Adapter) + .map(ln0Adapter -> ln0Adapter.updateLDeviceStatus(iedNameLdInstList)) + .flatMap(Optional::stream) + .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); + return sclRootAdapter.streamIEDAdapters() + .flatMap(IEDAdapter::streamLDeviceAdapters) + .map(LDeviceAdapter::getLN0Adapter) + .map(LN0Adapter::updateDoInRef) + .flatMap(List::stream) + .toList(); + } + + @Override + public List manageMonitoringLns(SCL scd) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + return sclRootAdapter.streamIEDAdapters() + .filter(iedAdapter -> !iedAdapter.getName().contains(IED_TEST_NAME)) + .map(IEDAdapter::manageMonitoringLns) + .flatMap(List::stream) + .toList(); + } +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SclElementsProviderService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SclElementsProviderService.java new file mode 100644 index 000000000..51c9f46d4 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SclElementsProviderService.java @@ -0,0 +1,115 @@ +// SPDX-FileCopyrightText: 2021 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons; + +import org.lfenergy.compas.scl2007b4.model.*; +import org.lfenergy.compas.sct.commons.api.SclElementsProvider; +import org.lfenergy.compas.sct.commons.dto.*; +import org.lfenergy.compas.sct.commons.exception.ScdException; +import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import org.lfenergy.compas.sct.commons.scl.com.CommunicationAdapter; +import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter; +import org.lfenergy.compas.sct.commons.scl.dtt.EnumTypeAdapter; +import org.lfenergy.compas.sct.commons.scl.ied.*; + +import java.util.*; +import java.util.stream.Collectors; + +public class SclElementsProviderService implements SclElementsProvider { + + @Override + public List getSubnetwork(SCL scd) throws ScdException { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + CommunicationAdapter communicationAdapter = sclRootAdapter.getCommunicationAdapter(false); + return communicationAdapter.getSubNetworkAdapters().stream() + .map(SubNetworkDTO::from) + .toList(); + } + + @Override + public List getExtRefInfo(SCL scd, String iedName, String ldInst) throws ScdException { + LDeviceAdapter lDeviceAdapter = createLDeviceAdapter(scd, iedName, ldInst); + return lDeviceAdapter.getExtRefInfo(); + } + + @Override + public List getExtRefBinders(SCL scd, String iedName, String ldInst, String lnClass, String lnInst, String prefix, ExtRefSignalInfo signalInfo) throws ScdException { + LDeviceAdapter lDeviceAdapter = createLDeviceAdapter(scd, iedName, ldInst); + AbstractLNAdapter abstractLNAdapter = AbstractLNAdapter.builder() + .withLDeviceAdapter(lDeviceAdapter) + .withLnClass(lnClass) + .withLnInst(lnInst) + .withLnPrefix(prefix) + .build(); + + // check for signal existence + abstractLNAdapter.isExtRefExist(signalInfo); + + // find potential binders for the signalInfo + return lDeviceAdapter.getParentAdapter().getParentAdapter().streamIEDAdapters() + .map(iedAdapter1 -> iedAdapter1.getExtRefBinders(signalInfo)) + .flatMap(Collection::stream) + .sorted() + .toList(); + } + + private LDeviceAdapter createLDeviceAdapter(SCL scd, String iedName, String ldInst) { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); + return iedAdapter.getLDeviceAdapterByLdInst(ldInst); + } + + @Override + public List getExtRefSourceInfo(SCL scd, ExtRefInfo extRefInfo) throws ScdException { + + ExtRefSignalInfo signalInfo = extRefInfo.getSignalInfo(); + if (!signalInfo.isValid()) { + throw new ScdException("Invalid or missing attributes in ExtRef signal info"); + } + ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo(); + if (!bindingInfo.isValid()) { + throw new ScdException("Invalid or missing attributes in ExtRef binding info"); + } + + String iedName = extRefInfo.getHolderIEDName(); + if (bindingInfo.getIedName().equals(iedName)) { + throw new ScdException("Internal binding can't have control block"); + } + + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + + // Get CBs + IEDAdapter srcIEDAdapter = sclRootAdapter.getIEDAdapterByName(bindingInfo.getIedName()); + LDeviceAdapter srcLDeviceAdapter = srcIEDAdapter.findLDeviceAdapterByLdInst(extRefInfo.getBindingInfo().getLdInst()) + .orElseThrow(); + + List> aLNAdapters = srcLDeviceAdapter.getLNAdaptersIncludingLN0(); + + return aLNAdapters.stream() + .map(abstractLNAdapter1 -> abstractLNAdapter1.getControlBlocksForMatchingFCDA(extRefInfo)) + .flatMap(Collection::stream) + .toList(); + } + + @Override + public Set getDAI(SCL scd, String iedName, String ldInst, DataAttributeRef dataAttributeRef, boolean updatable) throws ScdException { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); + LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(ldInst); + return lDeviceAdapter.getDAI(dataAttributeRef, updatable); + } + + @Override + public Set getEnumTypeValues(SCL scd, String idEnum) throws ScdException { + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + DataTypeTemplateAdapter dataTypeTemplateAdapter = sclRootAdapter.getDataTypeTemplateAdapter(); + EnumTypeAdapter enumTypeAdapter = dataTypeTemplateAdapter.getEnumTypeAdapterById(idEnum) + .orElseThrow(() -> new ScdException("Unknown EnumType Id: " + idEnum)); + return enumTypeAdapter.getCurrentElem().getEnumVal().stream() + .map(tEnumVal -> new EnumValDTO(tEnumVal.getOrd(), tEnumVal.getValue())) + .collect(Collectors.toSet()); + } + +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SubstationService.java similarity index 61% rename from sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java rename to sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SubstationService.java index 8e92407dd..1e51e398e 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/SubstationService.java @@ -2,51 +2,23 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.lfenergy.compas.sct.commons.scl; +package org.lfenergy.compas.sct.commons; import lombok.NonNull; import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TBay; import org.lfenergy.compas.scl2007b4.model.TSubstation; import org.lfenergy.compas.scl2007b4.model.TVoltageLevel; +import org.lfenergy.compas.sct.commons.api.SubstationEditor; import org.lfenergy.compas.sct.commons.exception.ScdException; +import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter; import org.lfenergy.compas.sct.commons.scl.sstation.VoltageLevelAdapter; -/** - * A representation of the {@link SubstationService SubstationService}. - *

    - * The following features are supported: - *

    - *
      - *
    • {@link SubstationService#addSubstation(SCL, SCL) Adds the Substation object from given SCL object}
    • - *
    • {@link SubstationService#updateVoltageLevel(SubstationAdapter, TVoltageLevel) Adds the TVoltageLevel element under TSubstation reference object}
    • - *
    • {@link SubstationService#updateBay(VoltageLevelAdapter, TBay) Adds the TBay element under TVoltageLevel reference object}
    • - *
    - * @see org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter - * @see org.lfenergy.compas.sct.commons.scl.sstation.VoltageLevelAdapter - * @see org.lfenergy.compas.sct.commons.scl.sstation.BayAdapter - * @see org.lfenergy.compas.sct.commons.scl.sstation.FunctionAdapter - * @see org.lfenergy.compas.sct.commons.scl.sstation.LNodeAdapter - * @see org.lfenergy.compas.sct.commons.scl.PrivateService - */ -public final class SubstationService { +public class SubstationService implements SubstationEditor { - /** - * Private Controller, should not be instanced - */ - private SubstationService() { - throw new UnsupportedOperationException("This service class cannot be instantiated"); - } - - /** - * Adds or Updates Substation section in SCL - * @param scd SCL file in which Substation should be added/updated - * @param ssd SCL file from which Substation should be copied - * @throws ScdException throws when SCD contents already another Substation, or with different name, or contents - * more than one Substation - */ - public static void addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdException { + @Override + public void addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdException { if (scd.getSubstation().size() > 1) { throw new ScdException(String.format("SCD file must have 0 or 1 Substation, but got %d", scd.getSubstation().size())); } @@ -75,7 +47,7 @@ public static void addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdE * @param vl VoltageLevel to create/update * @throws ScdException throws when unable to create new VoltageLevel section which is not already present in Substation */ - private static void updateVoltageLevel(@NonNull SubstationAdapter scdSubstationAdapter, TVoltageLevel vl) throws ScdException { + private void updateVoltageLevel(@NonNull SubstationAdapter scdSubstationAdapter, TVoltageLevel vl) throws ScdException { if (scdSubstationAdapter.getVoltageLevelAdapter(vl.getName()).isPresent()) { VoltageLevelAdapter scdVoltageLevelAdapter = scdSubstationAdapter.getVoltageLevelAdapter(vl.getName()) .orElseThrow(() -> new ScdException("Unable to create VoltageLevelAdapter")); @@ -92,7 +64,7 @@ private static void updateVoltageLevel(@NonNull SubstationAdapter scdSubstationA * @param scdVoltageLevelAdapter VoltageLevel in which Bay should be created/updated * @param tBay Bay to add */ - private static void updateBay(@NonNull VoltageLevelAdapter scdVoltageLevelAdapter, TBay tBay) { + private void updateBay(@NonNull VoltageLevelAdapter scdVoltageLevelAdapter, TBay tBay) { if (scdVoltageLevelAdapter.getBayAdapter(tBay.getName()).isPresent()) { scdVoltageLevelAdapter.getCurrentElem().getBay() .removeIf(t -> t.getName().equalsIgnoreCase(tBay.getName())); 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 new file mode 100644 index 000000000..f2df603fd --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ExtRefEditor.java @@ -0,0 +1,115 @@ +// SPDX-FileCopyrightText: 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.*; +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 java.util.List; + +/** + * 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 ExtRefEditor#updateExtRefBinders Update the TExtRef reference object for given ExtRefBindingInfo model}
      2. + *
      3. {@link ExtRefEditor#updateExtRefSource Update the TExtRef reference object for given ExtRefSourceInfo model}
      4. + *
      5. {@link ExtRefEditor#updateAllExtRefIedNames Update the iedName attribute in all TExtRef}
      6. + *
      7. {@link ExtRefEditor#createDataSetAndControlBlocks(SCL) Create DataSet and ControlBlock based on the TExtRef}
      8. + *
      9. {@link ExtRefEditor#createDataSetAndControlBlocks(SCL, String) Create DataSet and ControlBlock based on the TExtRef in given IED}
      10. + *
      11. {@link ExtRefEditor#createDataSetAndControlBlocks(SCL, String, String) Create DataSet and ControlBlock based on the TExtRef in given IED and LDevice}
      12. + *
      13. {@link ExtRefEditor#configureNetworkForAllControlBlocks Configure the network for the ControlBlocks}
      14. + *
      15. {@link ExtRefEditor#manageBindingForLDEPF Manage TExtRef Binding For LDevice (inst=LDEPF) within LDEPF configuration}
      16. + *
      + *
    + */ +public interface ExtRefEditor { + + /** + * Updates ExtRef binding data related to given ExtRef (extRefInfo) in given SCL file + * + * @param scd SCL file in which ExtRef to update should be found + * @param extRefInfo ExtRef signal for which we should find possible binders in SCL file + * @throws ScdException throws when mandatory data of ExtRef are missing + */ + void updateExtRefBinders(SCL scd, ExtRefInfo extRefInfo) throws ScdException; + + /** + * Updates ExtRef source binding data's based on given data in extRefInfo + * + * @param scd SCL file in which ExtRef source data's to update should be found + * @param extRefInfo new data for ExtRef source binding data + * @return TExtRef object as update ExtRef with new source binding data + * @throws ScdException throws when mandatory data of ExtRef are missing + */ + TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws ScdException; + + /** + * Updates iedName attribute of all ExtRefs in the Scd. + * + * @return list of encountered errors + */ + 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 + * @return list of encountered errors + */ + List createDataSetAndControlBlocks(SCL scd); + + /** + * 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 + * @return list of encountered errors + */ + List createDataSetAndControlBlocks(SCL scd, String targetIedName); + + /** + * 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 + * @return list of encountered errors + */ + List createDataSetAndControlBlocks(SCL scd, String targetIedName, String targetLDeviceInst); + + /** + * 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 + * @param scd SCL + * @param settings ILDEPFSettings + * @return list of encountered errors + */ + List manageBindingForLDEPF(SCL scd, ILDEPFSettings settings); + +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/HmiEditor.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/HmiEditor.java new file mode 100644 index 000000000..548cac764 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/HmiEditor.java @@ -0,0 +1,26 @@ +// SPDX-FileCopyrightText: 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.TFCDA; +import org.lfenergy.compas.scl2007b4.model.TReportControl; + +import java.util.List; + +/** + * Service class that will be used to manage elements related to the HMI {@link TReportControl Report Control Blocks}. + * + * @see Issue !258 + */ +public interface HmiEditor { + + /** + * Create the DataSet and ReportControl Blocks for the HMI with the given FCDAs. + * + * @param fcdas List of FCDA for which we must create the DataSet and ReportControl Blocks + */ + void createAllHmiReportControlBlocks(SCL scd, List fcdas); +} 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 new file mode 100644 index 000000000..d98582303 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SclEditor.java @@ -0,0 +1,172 @@ +// SPDX-FileCopyrightText: 2023 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons.api; + +import lombok.NonNull; +import org.lfenergy.compas.scl2007b4.model.SCL; +import org.lfenergy.compas.scl2007b4.model.TLNode; +import org.lfenergy.compas.sct.commons.dto.*; +import org.lfenergy.compas.sct.commons.exception.ScdException; + +import java.util.List; +import java.util.UUID; + +/** + * Service class that will be used to create, update or delete elements in {@link SCL SCL} XML Files. + *

    The following features are supported:

    + *
      + *
    • Initialization functions
    • + *
        + *
      1. {@link SclEditor#initScl Initialize the SCL object}
      2. + *
      3. {@link SclEditor#addHistoryItem Adds History object under THeader reference object}
      4. + *
      5. {@link SclEditor#updateHeader Update Header reference object}
      6. + *
      + *
    • IED features
    • + *
        + *
      1. {@link SclEditor#addIED Adds the IED object}
      2. + *
      + *
    • Communication features
    • + *
        + *
      1. {@link SclEditor#addSubnetworks Adds the Subnetwork elements under TCommunication reference object}
      2. + *
      + *
    • DAI features
    • + *
        + *
      1. {@link SclEditor#updateDAI Update the TDAI reference object for given iedName, ldInst and DataAttributeRef model}
      2. + *
      + *
    + * @see ExtRefEditor + * @see SubstationEditor + * @see HmiEditor + */ +public interface SclEditor { + + /** + * Initialise SCD file with Header and Private SCLFileType + * + * @param hId SCL Header ID + * @param hVersion SCL Header Version + * @param hRevision SCL Header Revision + * @return SCL SCD object + * @throws ScdException throws when inconsistance in SCL file + */ + SCL initScl(final UUID hId, final String hVersion, final String hRevision) throws ScdException; + /** + * Adds new HistoryItem in SCL file + * + * @param scd SCL file in which new History should be added + * @param who Who realize the action + * @param what What kind of action is realized + * @param why Why this action is done + */ + void addHistoryItem(SCL scd, String who, String what, String why); + + /** + * Updates Header of SCL file + * + * @param scd SCL file in which Header should be updated + * @param headerDTO Header new values + */ + void updateHeader(@NonNull SCL scd, @NonNull HeaderDTO headerDTO); + + /** + * Adds IED in SCL file (Related DataTypeTemplate of SCL is updated also) + * + * @param scd SCL file in which IED should be added + * @param iedName name of IED to add in SCL + * @param icd ICD containing IED to add and related DataTypeTemplate + * @throws ScdException throws when inconsistency between IED to add and SCL file content + */ + void addIED(SCL scd, String iedName, SCL icd) throws ScdException; + + /** + * Adds new SubNetworks in SCL file from ICD file + * + * @param scd SCL file in which SubNetworks should be added + * @param subNetworks List of SubNetworks DTO contenting SubNetwork and ConnectedAp parameter names + * @param icd ICD file from which SubNetworks functional data are copied from + * @throws ScdException throws when no Communication in SCL and createIfNotExists == false + */ + void addSubnetworks(SCL scd, List subNetworks, SCL icd) throws ScdException; + + /** + * Updates DAI based on given data in dataAttributeRef + * + * @param scd SCL file in which DataTypeTemplate of DAI should be found + * @param iedName name of IED in which DAI is localized + * @param ldInst ldInst of LDevice in which DAI is localized + * @param dataAttributeRef reference summarized DataTypeTemplate related to DAI to update + * @throws ScdException when inconsistency are found in th SCL's + * DataTypeTemplate. Which should normally not happens. + */ + void updateDAI(SCL scd, String iedName, String ldInst, DataAttributeRef dataAttributeRef) throws ScdException; + + /** + * Imports IEDs, DataTypeTemplates and Communication nodes of STD files into SCL (SCD) file + * STD : System Template Definition + * To import STD into SCD, this step are realized + *
      + *
    • Check SCD and STD compatibilities by checking if there is at least one ICD_SYSTEM_VERSION_UUID in + * LNode/Private CompasICDHeader of SCL/Substation/.. not present in IED/Private CompasICDHeader of STD
    • + *
    • List all LNode/Private COMPAS-ICDHeader of SCL/Substation/.. and remove duplicated one with same iedName in order to + * ovoid repetition in actions
    • + *
    • For each Private.ICDSystemVersionUUID and Private.iedName in Substation/ of SCL find corresponding STD File
    • + *
    • import /IED /DataTypeTemplate from that STD file and update IEDName of /IED in SCD file
    • + *
    • import connectedAP and rename ConnectedAP/@iedName in Communication node in SCD file
    • + *
    + * + * @param scd SCL object in which content of STD files are imported + * @param stds list of STD files contenting datas to import into SCD + * @param subNetworkTypes couple of Subnetwork name and possible corresponding ConnectedAP names + * @throws ScdException throws when inconsistency between Substation of SCL content and gien STD files as : + *
      + *
    • ICD_SYSTEM_VERSION_UUID in IED/Private of STD is not present in COMPAS-ICDHeader in Substation/../LNode of SCL
    • + *
    • There are several STD files corresponding to ICD_SYSTEM_VERSION_UUID of COMPAS-ICDHeader in Substation/../LNode of SCL
    • + *
    • There is no STD file found corresponding to COMPAS-ICDHeader in Substation/../LNode of SCL
    • + *
    • COMPAS-ICDHeader is not the same in Substation/../LNode of SCL and in IED/Private of STD
    • + *
    • COMPAS_ICDHEADER in Substation/../LNode of SCL not found in IED/Private of STD
    • + *
    + */ + 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 } + * + * @param scd SCL file for which LDevice should be activated or deactivated + * @return list of encountered errors + */ + 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. + * + * @param scd SCL file for which DOs InRef should be updated with matching ExtRef information + * @return list of encountered errors + */ + List updateDoInRef(SCL scd); + + /** + * Update and/or create Monitoring LNs (LSVS and LGOS) for bound GOOSE and SMV Control Blocks + * + * @param scd SCL file for which LNs (LSVS and LGOS) should be updated and/or created in each LDevice LDSUIED with matching ExtRef information + * @return list of encountered errors + */ + List manageMonitoringLns(SCL scd); + +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SclElementsProvider.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SclElementsProvider.java new file mode 100644 index 000000000..2c69a6fbc --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SclElementsProvider.java @@ -0,0 +1,109 @@ +// SPDX-FileCopyrightText: 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.sct.commons.dto.*; +import org.lfenergy.compas.sct.commons.exception.ScdException; + +import java.util.List; +import java.util.Set; + +/** + * Service class that will be used to retrieve {@link SCL SCL} XML Files. + * The ElementsProvider class needs to be able to find/list entries. + *

    The following features are supported:

    + *
      + *
    • Communication features
    • + *
        + *
      1. {@link SclElementsProvider#getSubnetwork(SCL) Returns list of SubNetworkDTO }
      2. + *
      + *
    • ExtRef features
    • + *
        + *
      1. {@link SclElementsProvider#getExtRefInfo Returns list of ExtRefInfo }
      2. + *
      3. {@link SclElementsProvider#getExtRefBinders Returns list of ExtRefBindingInfo }
      4. + *
      5. {@link SclElementsProvider#getExtRefSourceInfo Returns list of ExtRefSourceInfo }
      6. + *
      + *
    • DAI features
    • + *
        + *
      1. {@link SclElementsProvider#getDAI Returns list of DataAttributeRef }
      2. + *
      + *
    • EnumType features
    • + *
        + *
      1. {@link SclElementsProvider#getEnumTypeValues(SCL, String) Returns Map (ord, enumVal) of TEnumType reference object}
      2. + *
      + *
    + */ +public interface SclElementsProvider { + /** + * Gets list of SCL SubNetworks + * + * @param scd SCL file in which SubNetworks should be found + * @return List of SubNetworkDTO from SCL + * @throws ScdException throws when no Communication in SCL and createIfNotExists == false + */ + List getSubnetwork(SCL scd) throws ScdException; + + /** + * Gets all ExtRef from specific IED/LDevice in SCL file + * + * @param scd SCL file in which ExtRefs should be found + * @param iedName name of IED in which LDevice is localized + * @param ldInst LdInst of LDevice in which all ExtRefs should be found + * @return list of ExtRefInfo from specified parameter SCL/IED/LDevice + * @throws ScdException throws when unknown specified IED or LDevice + */ + List getExtRefInfo(SCL scd, String iedName, String ldInst) throws ScdException; + + /** + * Gets all possible ExtRefs to bind in SCL file with given ExtRef (signalInfo) in SCL file + * + * @param scd SCL file in which ExtRefs should be found + * @param iedName name of IED in which LDevice is localized + * @param ldInst ldInst of LDevice in which LN is localized + * @param lnClass lnClass of LN in which ExtRef signal to find binders is localized + * @param lnInst lnInst of LN in which ExtRef signal to find binders is localized + * @param prefix prefix of LN in which ExtRef signal to find binders is localized + * @param signalInfo ExtRef signal for which we should find possible binders in SCL file binders + * @return list of ExtRefBindingInfo object (containing binding data for each LNode in current SCL file) sorted by {@link ExtRefBindingInfo#compareTo(ExtRefBindingInfo) compareTo} method. + * @throws ScdException throws when ExtRef contains inconsistency data + */ + List getExtRefBinders(SCL scd, String iedName, String ldInst, String lnClass, String lnInst, String prefix, ExtRefSignalInfo signalInfo) throws ScdException; + + /** + * Gets all Control Blocks related to extRefInfo in given SCL file + * + * @param scd SCL file in which ControlBlocks should be found + * @param extRefInfo ExtRef signal for which we should find related ControlBlocks + * @return list of ControlBlock object as ControlBlocks of LNode specified in extRefInfo + * @throws ScdException throws when mandatory data of ExtRef are missing + */ + List getExtRefSourceInfo(SCL scd, ExtRefInfo extRefInfo) throws ScdException; + + /** + * Gets a list of summarized DataTypeTemplate for DataAttribute DA (updatable or not) related to the one given + * in dataAttributeRef + * + * @param scd SCL file in which DataTypeTemplate of DAIs should be found + * @param iedName name of IED in which DAs are localized + * @param ldInst ldInst of LDevice in which DAIs are localized + * @param dataAttributeRef reference summarized DataTypeTemplate related to IED DAIs + * @param updatable true to retrieve DataTypeTemplate's related to only updatable DAIs, false to retrieve all + * @return Set of Data Attribute Reference for DataAttribute (updatable or not) + * @throws ScdException SCD illegal arguments exception, missing mandatory data + */ + Set getDAI(SCL scd, String iedName, String ldInst, DataAttributeRef dataAttributeRef, boolean updatable) throws ScdException; + + /** + * Gets EnumTypes values of ID idEnum from DataTypeTemplate of SCL file + * + * @param scd SCL file in which EnumType should be found + * @param idEnum ID of EnumType for which values are retrieved + * @return list of couple EnumType value and it's order + * @throws ScdException throws when unknown EnumType + */ + Set getEnumTypeValues(SCL scd, String idEnum) throws ScdException; + +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SubstationEditor.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SubstationEditor.java new file mode 100644 index 000000000..1c8260e15 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/SubstationEditor.java @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2023 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons.api; + +import lombok.NonNull; +import org.lfenergy.compas.scl2007b4.model.SCL; +import org.lfenergy.compas.scl2007b4.model.TSubstation; +import org.lfenergy.compas.sct.commons.exception.ScdException; +import org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter; + +/** + * Service class that will be used to create, update or delete elements related to the {@link TSubstation TSubstation} object. + *

    The following features are supported:

    + *
      + *
    • {@link SubstationEditor#addSubstation(SCL, SCL) Adds the Substation object from given SCL object}
    • + *
    + * @see SubstationAdapter + */ +public interface SubstationEditor { + + /** + * Adds or Updates Substation section in SCL + * @param scd SCL file in which Substation should be added/updated + * @param ssd SCL file from which Substation should be copied + * @throws ScdException throws when SCD contents already another Substation, or with different name, or contents + * more than one Substation + */ + void addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdException; + +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/package-info.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/package-info.java new file mode 100644 index 000000000..7d54345d1 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/package-info.java @@ -0,0 +1,8 @@ +// SPDX-FileCopyrightText: 2023 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +/** + *

    commons.api contains interfaces for manipulating SCL Files

    + */ +package org.lfenergy.compas.sct.commons.api; \ No newline at end of file diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/PrivateLinkedToStds.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/PrivateLinkedToStds.java new file mode 100644 index 000000000..962811c21 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/PrivateLinkedToStds.java @@ -0,0 +1,14 @@ +// SPDX-FileCopyrightText: 2023 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons.dto; + +import org.lfenergy.compas.scl2007b4.model.SCL; +import org.lfenergy.compas.scl2007b4.model.TPrivate; + +import java.util.List; + +public record PrivateLinkedToStds(TPrivate tPrivate, List stdList) { + +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java deleted file mode 100644 index 273adc80d..000000000 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java +++ /dev/null @@ -1,606 +0,0 @@ -// SPDX-FileCopyrightText: 2021 RTE FRANCE -// -// SPDX-License-Identifier: Apache-2.0 - -package org.lfenergy.compas.sct.commons.scl; - -import lombok.NonNull; -import lombok.extern.slf4j.Slf4j; -import org.apache.commons.lang3.tuple.Pair; -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.com.CommunicationAdapter; -import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter; -import org.lfenergy.compas.sct.commons.scl.com.SubNetworkAdapter; -import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter; -import org.lfenergy.compas.sct.commons.scl.dtt.EnumTypeAdapter; -import org.lfenergy.compas.sct.commons.scl.dtt.LNodeTypeAdapter; -import org.lfenergy.compas.sct.commons.scl.header.HeaderAdapter; -import org.lfenergy.compas.sct.commons.scl.icd.IcdHeader; -import org.lfenergy.compas.sct.commons.scl.ied.*; -import org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter; -import org.lfenergy.compas.sct.commons.util.Utils; - -import java.util.*; -import java.util.stream.Collectors; - -import static org.lfenergy.compas.sct.commons.util.CommonConstants.IED_TEST_NAME; -import static org.lfenergy.compas.sct.commons.util.PrivateEnum.COMPAS_ICDHEADER; - -/** - * A representation of the {@link SclService SclService}. - *

    - * The following features are supported: - *

    - *
      - *
    • Initialization functions
    • - *
        - *
      1. {@link SclService#initScl(UUID, String, String) Initialize the SCL object}
      2. - *
      3. {@link SclService#addHistoryItem(SCL, String, String, String) Adds History object under THeader reference object}
      4. - *
      5. {@link SclService#updateHeader(SCL, HeaderDTO) Update Header reference object}
      6. - *
      - *
    • IED features
    • - *
        - *
      1. {@link SclService#addIED(SCL, String, SCL) Adds the IED object}
      2. - *
      - *
    • Communication features
    • - *
        - *
      1. {@link SclService#getSubnetwork(SCL) Returns list of SubNetworkDTO }
      2. - *
      3. {@link SclService#addSubnetworks(SCL, List, SCL) Adds the Subnetwork elements under TCommunication reference object}
      4. - *
      - *
    • ExtRef features
    • - *
        - *
      1. {@link SclService#getExtRefInfo Returns list of ExtRefInfo }
      2. - *
      3. {@link SclService#getExtRefBinders Returns list of ExtRefBindingInfo }
      4. - *
      5. {@link SclService#updateExtRefBinders(SCL, ExtRefInfo) Update the TExtRef reference object for given ExtRefBindingInfo model}
      6. - *
      7. {@link SclService#getExtRefSourceInfo Returns list of ExtRefSourceInfo }
      8. - *
      9. {@link SclService#updateExtRefSource(SCL, ExtRefInfo) Update the TExtRef reference object for given ExtRefSourceInfo model}
      10. - *
      - *
    • DAI features
    • - *
        - *
      1. {@link SclService#getDAI Returns list of DataAttributeRef }
      2. - *
      3. {@link SclService#updateDAI(SCL, String, String, DataAttributeRef) - * Update the TDAI reference object for given iedName, ldInst and DataAttributeRef model}
      4. - *
      - *
    • EnumType features
    • - *
        - *
      1. {@link SclService#getEnumTypeValues(SCL, String) Returns Map (ord, enumVal) of TEnumType reference object}
      2. - *
      - * - *
    - * - * @see org.lfenergy.compas.sct.commons.scl.header.HeaderAdapter - * @see org.lfenergy.compas.sct.commons.scl.sstation.SubstationAdapter - * @see org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter - * @see org.lfenergy.compas.sct.commons.scl.com.CommunicationAdapter - * @see org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter - */ -@Slf4j -public class SclService { - - private static final String UNKNOWN_LDEVICE_S_IN_IED_S = "Unknown LDevice (%s) in IED (%s)"; - private static final String INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO = "Invalid or missing attributes in ExtRef binding info"; - - private SclService() { - throw new IllegalStateException("SclService class"); - } - - /** - * Initialise SCD file with Header and Private SCLFileType - * - * @param hId SCL Header ID - * @param hVersion SCL Header Version - * @param hRevision SCL Header Revision - * @return SCL SCD object - * @throws ScdException throws when inconsistance in SCL file - */ - public static SCL initScl(final UUID hId, final String hVersion, final String hRevision) throws ScdException { - SclRootAdapter scdAdapter = new SclRootAdapter(hId.toString(), hVersion, hRevision); - scdAdapter.addPrivate(PrivateService.createPrivate(TCompasSclFileType.SCD)); - return scdAdapter.getCurrentElem(); - } - - /** - * Adds new HistoryItem in SCL file - * - * @param scd SCL file in which new History should be added - * @param who Who realize the action - * @param what What kind of action is realized - * @param why Why this action is done - */ - public static void addHistoryItem(SCL scd, String who, String what, String why) { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - HeaderAdapter headerAdapter = sclRootAdapter.getHeaderAdapter(); - headerAdapter.addHistoryItem(who, what, why); - } - - /** - * Updates Header of SCL file - * - * @param scd SCL file in which Header should be updated - * @param headerDTO Header new values - */ - public static void updateHeader(@NonNull SCL scd, @NonNull HeaderDTO headerDTO) { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - HeaderAdapter headerAdapter = sclRootAdapter.getHeaderAdapter(); - boolean hUpdated = false; - String hVersion = headerDTO.getVersion(); - String hRevision = headerDTO.getRevision(); - if (hVersion != null && !hVersion.equals(headerAdapter.getHeaderVersion())) { - headerAdapter.updateVersion(hVersion); - hUpdated = true; - } - if (hRevision != null && !hRevision.equals(headerAdapter.getHeaderRevision())) { - headerAdapter.updateRevision(hRevision); - hUpdated = true; - } - if (hUpdated && !headerDTO.getHistoryItems().isEmpty()) { - headerAdapter.addHistoryItem( - headerDTO.getHistoryItems().get(0).getWho(), - headerDTO.getHistoryItems().get(0).getWhat(), - headerDTO.getHistoryItems().get(0).getWhy() - ); - } - } - - /** - * Adds IED in SCL file (Related DataTypeTemplate of SCL is updated also) - * - * @param scd SCL file in which IED should be added - * @param iedName name of IED to add in SCL - * @param icd ICD containing IED to add and related DataTypeTemplate - * @throws ScdException throws when inconsistency between IED to add and SCL file content - */ - public static void addIED(SCL scd, String iedName, SCL icd) throws ScdException { - new SclRootAdapter(scd).addIED(icd, iedName); - } - - /** - * Adds new SubNetworks in SCL file from ICD file - * - * @param scd SCL file in which SubNetworks should be added - * @param subNetworks List of SubNetworks DTO contenting SubNetwork and ConnectedAp parameter names - * @param icd ICD file from which SubNetworks functional data are copied from - * @throws ScdException throws when no Communication in SCL and createIfNotExists == false - */ - public static void addSubnetworks(SCL scd, List subNetworks, SCL icd) throws ScdException { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - CommunicationAdapter communicationAdapter; - if (!subNetworks.isEmpty()) { - communicationAdapter = sclRootAdapter.getCommunicationAdapter(true); - for (SubNetworkDTO subNetworkDTO : subNetworks) { - String snName = subNetworkDTO.getName(); - String snType = subNetworkDTO.getType(); - for (ConnectedApDTO accessPoint : subNetworkDTO.getConnectedAPs()) { - String iedName = accessPoint.iedName(); - String apName = accessPoint.apName(); - communicationAdapter.addSubnetwork(snName, snType, iedName, apName); - - Optional subNetworkAdapter = communicationAdapter.getSubnetworkByName(snName); - if (subNetworkAdapter.isPresent()) { - ConnectedAPAdapter connectedAPAdapter = subNetworkAdapter.get().getConnectedAPAdapter(iedName, apName); - connectedAPAdapter.copyAddressAndPhysConnFromIcd(icd); - } - } - } - } - } - - /** - * Gets list of SCL SubNetworks - * - * @param scd SCL file in which SubNetworks should be found - * @return List of SubNetworkDTO from SCL - * @throws ScdException throws when no Communication in SCL and createIfNotExists == false - */ - public static List getSubnetwork(SCL scd) throws ScdException { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - CommunicationAdapter communicationAdapter = sclRootAdapter.getCommunicationAdapter(false); - return communicationAdapter.getSubNetworkAdapters().stream() - .map(SubNetworkDTO::from) - .toList(); - } - - /** - * Gets all ExtRef from specific IED/LDevice in SCL file - * - * @param scd SCL file in which ExtRefs should be found - * @param iedName name of IED in which LDevice is localized - * @param ldInst LdInst of LDevice in which all ExtRefs should be found - * @return list of ExtRefInfo from specified parameter SCL/IED/LDevice - * @throws ScdException throws when unknown specified IED or LDevice - */ - public static List getExtRefInfo(SCL scd, String iedName, String ldInst) throws ScdException { - LDeviceAdapter lDeviceAdapter = createLDeviceAdapter(scd, iedName, ldInst); - return lDeviceAdapter.getExtRefInfo(); - } - - /** - * Create LDevice - * - * @param scd SCL file in which LDevice should be found - * @param iedName name of IED in which LDevice is localized - * @param ldInst LdInst of LDevice for which adapter is created - * @return created LDevice adapter - */ - private static LDeviceAdapter createLDeviceAdapter(SCL scd, String iedName, String ldInst) { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); - return iedAdapter.findLDeviceAdapterByLdInst(ldInst) - .orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName))); - } - - /** - * Gets all possible ExtRefs to bind in SCL file with given ExtRef (signalInfo) in SCL file - * - * @param scd SCL file in which ExtRefs should be found - * @param iedName name of IED in which LDevice is localized - * @param ldInst ldInst of LDevice in which LN is localized - * @param lnClass lnClass of LN in which ExtRef signal to find binders is localized - * @param lnInst lnInst of LN in which ExtRef signal to find binders is localized - * @param prefix prefix of LN in which ExtRef signal to find binders is localized - * @param signalInfo ExtRef signal for which we should find possible binders in SCL file binders - * @return list of ExtRefBindingInfo object (containing binding data for each LNode in current SCL file) sorted by {@link ExtRefBindingInfo#compareTo(ExtRefBindingInfo) compareTo} method. - * @throws ScdException throws when ExtRef contains inconsistency data - */ - public static List getExtRefBinders(SCL scd, String iedName, String ldInst, String lnClass, String lnInst, String prefix, ExtRefSignalInfo signalInfo) throws ScdException { - LDeviceAdapter lDeviceAdapter = createLDeviceAdapter(scd, iedName, ldInst); - AbstractLNAdapter abstractLNAdapter = AbstractLNAdapter.builder() - .withLDeviceAdapter(lDeviceAdapter) - .withLnClass(lnClass) - .withLnInst(lnInst) - .withLnPrefix(prefix) - .build(); - - // check for signal existence - abstractLNAdapter.isExtRefExist(signalInfo); - - // find potential binders for the signalInfo - return lDeviceAdapter.getParentAdapter().getParentAdapter().streamIEDAdapters() - .map(iedAdapter1 -> iedAdapter1.getExtRefBinders(signalInfo)) - .flatMap(Collection::stream) - .sorted() - .toList(); - } - - /** - * Updates ExtRef binding data related to given ExtRef (extRefInfo) in given SCL file - * - * @param scd SCL file in which ExtRef to update should be found - * @param extRefInfo ExtRef signal for which we should find possible binders in SCL file - * @throws ScdException throws when mandatory data of ExtRef are missing - */ - public static void updateExtRefBinders(SCL scd, ExtRefInfo extRefInfo) throws ScdException { - if (extRefInfo.getBindingInfo() == null || extRefInfo.getSignalInfo() == null) { - throw new ScdException("ExtRef Signal and/or Binding information are missing"); - } - String iedName = extRefInfo.getHolderIEDName(); - String ldInst = extRefInfo.getHolderLDInst(); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); - LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst) - .orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName))); - - AbstractLNAdapter abstractLNAdapter = AbstractLNAdapter.builder() - .withLDeviceAdapter(lDeviceAdapter) - .withLnClass(extRefInfo.getHolderLnClass()) - .withLnInst(extRefInfo.getHolderLnInst()) - .withLnPrefix(extRefInfo.getHolderLnPrefix()) - .build(); - - abstractLNAdapter.updateExtRefBinders(extRefInfo); - } - - /** - * Gets all Control Blocks related to extRefInfo in given SCL file - * - * @param scd SCL file in which ControlBlocks should be found - * @param extRefInfo ExtRef signal for which we should find related ControlBlocks - * @return list of ControlBlock object as ControlBlocks of LNode specified in extRefInfo - * @throws ScdException throws when mandatory data of ExtRef are missing - */ - public static List getExtRefSourceInfo(SCL scd, ExtRefInfo extRefInfo) throws ScdException { - - ExtRefSignalInfo signalInfo = extRefInfo.getSignalInfo(); - if (!signalInfo.isValid()) { - throw new ScdException("Invalid or missing attributes in ExtRef signal info"); - } - ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo(); - if (!bindingInfo.isValid()) { - throw new ScdException(INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO); - } - - String iedName = extRefInfo.getHolderIEDName(); - if (bindingInfo.getIedName().equals(iedName)) { - throw new ScdException("Internal binding can't have control block"); - } - - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - - // Get CBs - IEDAdapter srcIEDAdapter = sclRootAdapter.getIEDAdapterByName(bindingInfo.getIedName()); - LDeviceAdapter srcLDeviceAdapter = srcIEDAdapter.findLDeviceAdapterByLdInst(extRefInfo.getBindingInfo().getLdInst()) - .orElseThrow(); - - List> aLNAdapters = srcLDeviceAdapter.getLNAdaptersIncludingLN0(); - - return aLNAdapters.stream() - .map(abstractLNAdapter1 -> abstractLNAdapter1.getControlBlocksForMatchingFCDA(extRefInfo)) - .flatMap(Collection::stream) - .toList(); - - } - - /** - * Updates ExtRef source binding data's based on given data in extRefInfo - * - * @param scd SCL file in which ExtRef source data's to update should be found - * @param extRefInfo new data for ExtRef source binding data - * @return TExtRef object as update ExtRef with new source binding data - * @throws ScdException throws when mandatory data of ExtRef are missing - */ - public static TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws ScdException { - String iedName = extRefInfo.getHolderIEDName(); - String ldInst = extRefInfo.getHolderLDInst(); - String lnClass = extRefInfo.getHolderLnClass(); - String lnInst = extRefInfo.getHolderLnInst(); - String prefix = extRefInfo.getHolderLnPrefix(); - - ExtRefSignalInfo signalInfo = extRefInfo.getSignalInfo(); - if (signalInfo == null || !signalInfo.isValid()) { - throw new ScdException("Invalid or missing attributes in ExtRef signal info"); - } - ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo(); - if (bindingInfo == null || !bindingInfo.isValid()) { - throw new ScdException(INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO); - } - if (bindingInfo.getIedName().equals(iedName) || TServiceType.POLL.equals(bindingInfo.getServiceType())) { - throw new ScdException("Internal binding can't have control block"); - } - ExtRefSourceInfo sourceInfo = extRefInfo.getSourceInfo(); - if (sourceInfo == null || !sourceInfo.isValid()) { - throw new ScdException(INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO); - } - - LDeviceAdapter lDeviceAdapter = createLDeviceAdapter(scd, iedName, ldInst); - AbstractLNAdapter anLNAdapter = AbstractLNAdapter.builder() - .withLDeviceAdapter(lDeviceAdapter) - .withLnClass(lnClass) - .withLnInst(lnInst) - .withLnPrefix(prefix) - .build(); - return anLNAdapter.updateExtRefSource(extRefInfo); - } - - /** - * Gets a list of summarized DataTypeTemplate for DataAttribute DA (updatable or not) related to the one given - * in dataAttributeRef - * - * @param scd SCL file in which DataTypeTemplate of DAIs should be found - * @param iedName name of IED in which DAs are localized - * @param ldInst ldInst of LDevice in which DAIs are localized - * @param dataAttributeRef reference summarized DataTypeTemplate related to IED DAIs - * @param updatable true to retrieve DataTypeTemplate's related to only updatable DAIs, false to retrieve all - * @return Set of Data Attribute Reference for DataAttribute (updatable or not) - * @throws ScdException SCD illegal arguments exception, missing mandatory data - */ - public static Set getDAI(SCL scd, String iedName, String ldInst, DataAttributeRef dataAttributeRef, boolean updatable) throws ScdException { - LDeviceAdapter lDeviceAdapter = createLDeviceAdapter(scd, iedName, ldInst); - return lDeviceAdapter.getDAI(dataAttributeRef, updatable); - } - - /** - * Updates DAI based on given data in dataAttributeRef - * - * @param scd SCL file in which DataTypeTemplate of DAI should be found - * @param iedName name of IED in which DAI is localized - * @param ldInst ldInst of LDevice in which DAI is localized - * @param dataAttributeRef reference summarized DataTypeTemplate related to DAI to update - * @throws ScdException when inconsistency are found in th SCL's - * DataTypeTemplate. Which should normally not happens. - */ - public static void updateDAI(SCL scd, String iedName, String ldInst, DataAttributeRef dataAttributeRef) throws ScdException { - long startTime = System.nanoTime(); - log.info(Utils.entering()); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - DataTypeTemplateAdapter dttAdapter = sclRootAdapter.getDataTypeTemplateAdapter(); - LNodeTypeAdapter lNodeTypeAdapter = dttAdapter.getLNodeTypeAdapterById(dataAttributeRef.getLnType()) - .orElseThrow(() -> new ScdException("Unknown LNodeType : " + dataAttributeRef.getLnType())); - lNodeTypeAdapter.check(dataAttributeRef.getDoName(), dataAttributeRef.getDaName()); - - if (TPredefinedBasicTypeEnum.OBJ_REF == dataAttributeRef.getBType()) { - Long sGroup = dataAttributeRef.getDaName().getDaiValues().keySet().stream().findFirst().orElse(-1L); - String val = sGroup < 0 ? null : dataAttributeRef.getDaName().getDaiValues().get(sGroup); - sclRootAdapter.checkObjRef(val); - } - - IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); - LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst) - .orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName))); - - AbstractLNAdapter lnAdapter = AbstractLNAdapter.builder() - .withLDeviceAdapter(lDeviceAdapter) - .withLnClass(dataAttributeRef.getLnClass()) - .withLnInst(dataAttributeRef.getLnInst()) - .withLnPrefix(dataAttributeRef.getPrefix()) - .build(); - - if (TPredefinedCDCEnum.ING == dataAttributeRef.getCdc() || TPredefinedCDCEnum.ASG == dataAttributeRef.getCdc()) { - DAITracker daiTracker = new DAITracker(lnAdapter, dataAttributeRef.getDoName(), dataAttributeRef.getDaName()); - daiTracker.validateBoundedDAI(); - } - lnAdapter.updateDAI(dataAttributeRef); - log.info(Utils.leaving(startTime)); - } - - /** - * Gets EnumTypes values of ID idEnum from DataTypeTemplate of SCL file - * - * @param scd SCL file in which EnumType should be found - * @param idEnum ID of EnumType for which values are retrieved - * @return list of couple EnumType value and it's order - * @throws ScdException throws when unknown EnumType - */ - public static Set getEnumTypeValues(SCL scd, String idEnum) throws ScdException { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - DataTypeTemplateAdapter dataTypeTemplateAdapter = sclRootAdapter.getDataTypeTemplateAdapter(); - EnumTypeAdapter enumTypeAdapter = dataTypeTemplateAdapter.getEnumTypeAdapterById(idEnum) - .orElseThrow(() -> new ScdException("Unknown EnumType Id: " + idEnum)); - return enumTypeAdapter.getCurrentElem().getEnumVal().stream() - .map(tEnumVal -> new EnumValDTO(tEnumVal.getOrd(), tEnumVal.getValue())) - .collect(Collectors.toSet()); - } - - /** - * Imports IEDs, DataTypeTemplates and Communication nodes of STD files into SCL (SCD) file - * STD : System Template Definition - * To import STD into SCD, this step are realized - *
      - *
    • Check SCD and STD compatibilities by checking if there is at least one ICD_SYSTEM_VERSION_UUID in - * LNode/Private CompasICDHeader of SCL/Substation/.. not present in IED/Private CompasICDHeader of STD
    • - *
    • List all LNode/Private COMPAS-ICDHeader of SCL/Substation/.. and remove duplicated one with same iedName in order to - * ovoid repetition in actions
    • - *
    • For each Private.ICDSystemVersionUUID and Private.iedName in Substation/ of SCL find corresponding STD File
    • - *
    • import /IED /DataTypeTemplate from that STD file and update IEDName of /IED in SCD file
    • - *
    • import connectedAP and rename ConnectedAP/@iedName in Communication node in SCD file
    • - *
    - * - * @param scd SCL object in which content of STD files are imported - * @param stds list of STD files contenting datas to import into SCD - * @param subNetworkTypes couple of Subnetwork name and possible corresponding ConnectedAP names - * @throws ScdException throws when inconsistency between Substation of SCL content and gien STD files as : - *
      - *
    • ICD_SYSTEM_VERSION_UUID in IED/Private of STD is not present in COMPAS-ICDHeader in Substation/../LNode of SCL
    • - *
    • There are several STD files corresponding to ICD_SYSTEM_VERSION_UUID of COMPAS-ICDHeader in Substation/../LNode of SCL
    • - *
    • There is no STD file found corresponding to COMPAS-ICDHeader in Substation/../LNode of SCL
    • - *
    • COMPAS-ICDHeader is not the same in Substation/../LNode of SCL and in IED/Private of STD
    • - *
    • COMPAS_ICDHEADER in Substation/../LNode of SCL not found in IED/Private of STD
    • - *
    - */ - public static void importSTDElementsInSCD(SCL scd, List stds, List subNetworkTypes) throws ScdException { - - //Check SCD and STD compatibilities - Map mapICDSystemVersionUuidAndSTDFile = PrivateService.createMapICDSystemVersionUuidAndSTDFile(stds); - PrivateService.checkSTDCorrespondanceWithLNodeCompasICDHeader(mapICDSystemVersionUuidAndSTDFile); - // List all Private and remove duplicated one with same iedName - // For each Private.ICDSystemVersionUUID and Private.iedName find STD File - List iedNamesUsed = new ArrayList<>(); - SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); - PrivateService.streamIcdHeaders(scd) - .forEach(icdHeader -> { - if (!iedNamesUsed.contains(icdHeader.getIedName())) { - String iedName = icdHeader.getIedName(); - iedNamesUsed.add(iedName); - String icdSysVerUuid = icdHeader.getIcdSystemVersionUUID(); - if (!mapICDSystemVersionUuidAndSTDFile.containsKey(icdSysVerUuid)) - throw new ScdException("There is no STD file found corresponding to " + icdHeader); - // import /ied /dtt in Scd - SCL std = mapICDSystemVersionUuidAndSTDFile.get(icdSysVerUuid).stdList().get(0); - SclRootAdapter stdRootAdapter = new SclRootAdapter(std); - IEDAdapter stdIedAdapter = new IEDAdapter(stdRootAdapter, std.getIED().get(0)); - Optional optionalTPrivate = stdIedAdapter.getPrivateHeader(COMPAS_ICDHEADER.getPrivateType()); - if (optionalTPrivate.isPresent() && optionalTPrivate.flatMap(PrivateService::extractCompasICDHeader).map(IcdHeader::new).get().equals(icdHeader)) { - PrivateService.copyCompasICDHeaderFromLNodePrivateIntoSTDPrivate(optionalTPrivate.get(), icdHeader.toTCompasICDHeader()); - } else throw new ScdException("COMPAS-ICDHeader is not the same in Substation and in IED"); - scdRootAdapter.addIED(std, iedName); - - //import connectedAP and rename ConnectedAP/@iedName - TCommunication communication = stdRootAdapter.getCurrentElem().getCommunication(); - List subNetworkDTOSet = SubNetworkDTO.createDefaultSubnetwork(iedName, communication, subNetworkTypes); - addSubnetworks(scdRootAdapter.getCurrentElem(), subNetworkDTOSet, std); - } - }); - } - - - /** - * Removes all ControlBlocks and DataSets for all LNs in SCL - * - * @param scl SCL file for which ControlBlocks and DataSets should be deleted - */ - public static 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); - } - - /** - * Activate used LDevice and Deactivate unused LDevice in {@link TLNode TLNode } - * - * @param scd SCL file for which LDevice should be activated or deactivated - * @return list of encountered errors - */ - public static List updateLDeviceStatus(SCL scd) { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - SubstationAdapter substationAdapter = sclRootAdapter.getSubstationAdapter(); - final List> iedNameLdInstList = substationAdapter.getIedAndLDeviceNamesForLN0FromLNode(); - return sclRootAdapter.streamIEDAdapters() - .flatMap(IEDAdapter::streamLDeviceAdapters) - .map(LDeviceAdapter::getLN0Adapter) - .map(ln0Adapter -> ln0Adapter.updateLDeviceStatus(iedNameLdInstList)) - .flatMap(Optional::stream) - .toList(); - } - - /** - * 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 - */ - public static 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(); - } - - /** - * Update DAIs of DO InRef in all LN0 of the SCD using matching ExtRef information. - * - * @param scd SCL file for which DOs InRef should be updated with matching ExtRef information - * @return list of encountered errors - */ - public static List updateDoInRef(SCL scd) { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - return sclRootAdapter.streamIEDAdapters() - .flatMap(IEDAdapter::streamLDeviceAdapters) - .map(LDeviceAdapter::getLN0Adapter) - .map(LN0Adapter::updateDoInRef) - .flatMap(List::stream) - .toList(); - } - - /** - * Update and/or create Monitoring LNs (LSVS and LGOS) for bound GOOSE and SMV Control Blocks - * - * @param scd SCL file for which LNs (LSVS and LGOS) should be updated and/or created in each LDevice LDSUIED with matching ExtRef information - * @return list of encountered errors - */ - public static List manageMonitoringLns(SCL scd) { - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - return sclRootAdapter.streamIEDAdapters() - .filter(iedAdapter -> !iedAdapter.getName().contains(IED_TEST_NAME)) - .map(IEDAdapter::manageMonitoringLns) - .flatMap(List::stream) - .toList(); - } -} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapter.java index bc54fe6bf..07b6167cd 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapter.java @@ -17,7 +17,7 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.lfenergy.compas.sct.commons.scl.ExtRefService.filterDuplicatedExtRefs; +import static org.lfenergy.compas.sct.commons.ExtRefService.filterDuplicatedExtRefs; /** * A representation of the model object 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 997adcc84..9d2d5e104 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 @@ -12,7 +12,7 @@ import org.lfenergy.compas.sct.commons.dto.SclReportItem; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.ObjectReference; -import org.lfenergy.compas.sct.commons.scl.PrivateService; +import org.lfenergy.compas.sct.commons.util.PrivateUtils; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.util.MonitoringLnClassEnum; @@ -322,7 +322,7 @@ public Optional getPrivateHeader(String privateType) { * @return value of private compas:Bay if present, empty Optional otherwise */ public Optional getPrivateCompasBay() { - return PrivateService.extractCompasPrivate(currentElem, TCompasBay.class); + return PrivateUtils.extractCompasPrivate(currentElem, TCompasBay.class); } /** @@ -374,7 +374,7 @@ private Stream streamAccessPointAdapters() { * @return COMPAS-ICDHeader private value if present, else empty Optional */ public Optional getCompasICDHeader() { - return PrivateService.extractCompasPrivate(currentElem, TCompasICDHeader.class); + return PrivateUtils.extractCompasPrivate(currentElem, TCompasICDHeader.class); } /** @@ -383,7 +383,7 @@ public Optional getCompasICDHeader() { * @return COMPAS-SystemVersion private value if present, else empty Optional */ public Optional getCompasSystemVersion() { - return PrivateService.extractCompasPrivate(currentElem, TCompasSystemVersion.class); + return PrivateUtils.extractCompasPrivate(currentElem, TCompasSystemVersion.class); } /** diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapter.java index e932bd816..645241c3d 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/InputsAdapter.java @@ -11,10 +11,10 @@ import org.lfenergy.compas.sct.commons.dto.DataAttributeRef; import org.lfenergy.compas.sct.commons.dto.SclReportItem; import org.lfenergy.compas.sct.commons.exception.ScdException; -import org.lfenergy.compas.sct.commons.scl.ExtRefService; -import org.lfenergy.compas.sct.commons.scl.PrivateService; +import org.lfenergy.compas.sct.commons.util.PrivateUtils; import org.lfenergy.compas.sct.commons.scl.SclElementAdapter; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; +import org.lfenergy.compas.sct.commons.ExtRefService; import org.lfenergy.compas.sct.commons.util.ControlBlockEnum; import org.lfenergy.compas.sct.commons.util.FcdaCandidates; import org.lfenergy.compas.sct.commons.util.LdeviceStatus; @@ -136,7 +136,7 @@ private Optional updateExtRefIedName(TExtRef extRef, IEDAdapter s clearBinding(extRef); return sourceValidationError; } - String sourceIedName = PrivateService.extractCompasPrivate(sourceIed.getCurrentElem(), TCompasICDHeader.class) + String sourceIedName = PrivateUtils.extractCompasPrivate(sourceIed.getCurrentElem(), TCompasICDHeader.class) .map(TCompasICDHeader::getIEDName).orElse(""); extRef.setIedName(sourceIedName); compasFlow.setExtRefiedName(sourceIedName); @@ -226,7 +226,7 @@ private String extRefXPath(String extRefDesc) { * @return list of matching CompasFlows */ private List getMatchingCompasFlows(TExtRef extRef) { - return PrivateService.extractCompasPrivates(currentElem, TCompasFlow.class) + return PrivateUtils.extractCompasPrivates(currentElem, TCompasFlow.class) .filter(compasFlow -> isMatchingExtRef(compasFlow, extRef)) .toList(); } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LN0Adapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LN0Adapter.java index 8c2bb9b4e..98d8e8b0c 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LN0Adapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/LN0Adapter.java @@ -10,7 +10,7 @@ import org.lfenergy.compas.sct.commons.dto.*; import org.lfenergy.compas.sct.commons.scl.LDeviceActivation; import org.lfenergy.compas.sct.commons.scl.ObjectReference; -import org.lfenergy.compas.sct.commons.scl.PrivateService; +import org.lfenergy.compas.sct.commons.util.PrivateUtils; import java.util.List; import java.util.Optional; @@ -187,7 +187,7 @@ public Optional updateLDeviceStatus(List> ie return Optional.of(buildFatalReportItem("The LDevice doesn't have a DO @name='Beh' OR its associated DA@fc='ST' AND DA@name='stVal'")); } Set enumValues = getEnumValues(daiBehList.get(0).getDaName().getType()); - Optional optionalTCompasLDevice = PrivateService.extractCompasPrivate(getParentAdapter().getCurrentElem(), TCompasLDevice.class); + Optional optionalTCompasLDevice = PrivateUtils.extractCompasPrivate(getParentAdapter().getCurrentElem(), TCompasLDevice.class); if (optionalTCompasLDevice.isEmpty()) { return Optional.of(buildFatalReportItem("The LDevice doesn't have a Private compas:LDevice.")); } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/FcdaCsvHelper.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/FcdaCsvHelper.java index aec1aea4a..1c47ecd81 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/FcdaCsvHelper.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/FcdaCsvHelper.java @@ -13,11 +13,11 @@ import java.util.List; /** - * This class is a helper method to load FCDA from a CSV file for use with {@link org.lfenergy.compas.sct.commons.scl.HmiService#createAllHmiReportControlBlocks} + * This class is a helper method to load FCDA from a CSV file for use with {@link IHmiService#createAllHmiReportControlBlocks} * Use the getter to access the list of parsed FCDA. * * @see CsvUtils - * @see org.lfenergy.compas.sct.commons.scl.HmiService#createAllHmiReportControlBlocks + * @see IHmiService#createAllHmiReportControlBlocks */ public class FcdaCsvHelper { diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/PrivateService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/PrivateUtils.java similarity index 89% rename from sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/PrivateService.java rename to sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/PrivateUtils.java index 54b3a2880..8c9ddd26d 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/PrivateService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/PrivateUtils.java @@ -2,13 +2,14 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.lfenergy.compas.sct.commons.scl; +package org.lfenergy.compas.sct.commons.util; import lombok.NonNull; +import lombok.experimental.UtilityClass; import org.lfenergy.compas.scl2007b4.model.*; +import org.lfenergy.compas.sct.commons.dto.PrivateLinkedToStds; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.icd.IcdHeader; -import org.lfenergy.compas.sct.commons.util.PrivateEnum; import javax.xml.bind.JAXBElement; import java.util.*; @@ -19,25 +20,18 @@ import static org.lfenergy.compas.sct.commons.util.PrivateEnum.COMPAS_ICDHEADER; /** - * A representation of the {@link PrivateService PrivateService}. + * A representation of the {@link PrivateUtils PrivateService}. *

    * The following features are supported: *

    *
      - *
    1. {@link PrivateService#extractCompasPrivates(TBaseElement, Class) + *
    2. {@link PrivateUtils#extractCompasPrivates(TBaseElement, Class) * Returns the value of the TPrivate containment reference list from given TBaseElement By class type}
    3. - * - *
    4. {@link PrivateService#extractCompasPrivates(TBaseElement, Class)} - * Returns the value of the TPrivate containment reference list from given TPrivate elements By class type} - *
    5. *
    * @see org.lfenergy.compas.scl2007b4.model.TPrivate */ -public final class PrivateService { - - private PrivateService() { - throw new UnsupportedOperationException("This is a utility class and cannot be instantiated"); - } +@UtilityClass +public final class PrivateUtils { private static final ObjectFactory objectFactory = new ObjectFactory(); @@ -195,28 +189,23 @@ private static TPrivate createPrivate(JAXBElement jaxbElement) { * @return map of ICD_SYSTEM_VERSION_UUID attribute in IED/Private:COMPAS-ICDHeader and related Private coupled with * all corresponding STD */ - public static Map createMapICDSystemVersionUuidAndSTDFile(List stds) { - Map icdSysVerToPrivateStdsMap = new HashMap<>(); + public static Map createMapICDSystemVersionUuidAndSTDFile(List stds) { + Map icdSysVerToPrivateStdsMap = new HashMap<>(); stds.forEach(std -> std.getIED() .forEach(ied -> ied.getPrivate() .forEach(tp -> - PrivateService.extractCompasICDHeader(tp) + PrivateUtils.extractCompasICDHeader(tp) .map(TCompasICDHeader::getICDSystemVersionUUID) .ifPresent(icdSysVer -> { - PrivateLinkedToSTDs privateLinkedToSTDs = icdSysVerToPrivateStdsMap.get(icdSysVer); - List list = privateLinkedToSTDs != null ? privateLinkedToSTDs.stdList() : new ArrayList<>(); + PrivateLinkedToStds privateLinkedToStds = icdSysVerToPrivateStdsMap.get(icdSysVer); + List list = privateLinkedToStds != null ? privateLinkedToStds.stdList() : new ArrayList<>(); list.add(std); - icdSysVerToPrivateStdsMap.put(icdSysVer, new PrivateLinkedToSTDs(tp, list)); + icdSysVerToPrivateStdsMap.put(icdSysVer, new PrivateLinkedToStds(tp, list)); }) ))); return icdSysVerToPrivateStdsMap; } - - public record PrivateLinkedToSTDs (TPrivate tPrivate, List stdList) { - } - - /** * Checks SCD and STD compatibilities by checking if there is at least one ICD_SYSTEM_VERSION_UUID in * Substation/../LNode/Private COMPAS-ICDHeader of SCL not present in IED/Private COMPAS-ICDHeader of STD @@ -225,9 +214,9 @@ public record PrivateLinkedToSTDs (TPrivate tPrivate, List stdList) { * @throws ScdException throws when there are several STD files corresponding to ICD_SYSTEM_VERSION_UUID * from Substation/../LNode/Private COMPAS-ICDHeader of SCL */ - public static void checkSTDCorrespondanceWithLNodeCompasICDHeader(Map mapICDSystemVersionUuidAndSTDFile) throws ScdException { + public static void checkSTDCorrespondanceWithLNodeCompasICDHeader(Map mapICDSystemVersionUuidAndSTDFile) throws ScdException { mapICDSystemVersionUuidAndSTDFile.values().stream() - .filter(privateLinkedToSTDs -> privateLinkedToSTDs.stdList().size() != 1) + .filter(privateLinkedToStds -> privateLinkedToStds.stdList().size() != 1) .findFirst() .ifPresent(pToStd -> { throw new ScdException("There are several STD files corresponding to " + stdCheckFormatExceptionMessage(pToStd.tPrivate())); @@ -242,7 +231,7 @@ public static void checkSTDCorrespondanceWithLNodeCompasICDHeader(Map optionalCompasICDHeader = PrivateService.extractCompasICDHeader(key); + Optional optionalCompasICDHeader = PrivateUtils.extractCompasICDHeader(key); return HEADER_ID + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getHeaderId).orElse(null) + " " + HEADER_VERSION + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getHeaderVersion).orElse(null) + " " + HEADER_REVISION + " = " + optionalCompasICDHeader.map(TCompasICDHeader::getHeaderRevision).orElse(null) + @@ -265,7 +254,7 @@ public static Stream streamIcdHeaders(SCL scd) { .map(TBay::getFunction).flatMap(Collection::stream) .map(TFunction::getLNode).flatMap(Collection::stream) .map(TLNode::getPrivate).flatMap(Collection::stream) - .map(PrivateService::extractCompasICDHeader) + .map(PrivateUtils::extractCompasICDHeader) .filter(Optional::isPresent) .map(Optional::get) .map(IcdHeader::new); @@ -280,9 +269,9 @@ public static Stream streamIcdHeaders(SCL scd) { * @throws ScdException throws when Private is not COMPAS_ICDHEADER one */ public static boolean comparePrivateCompasICDHeaders(TPrivate iedPrivate, TPrivate scdPrivate) throws ScdException { - TCompasICDHeader iedCompasICDHeader = PrivateService.extractCompasICDHeader(iedPrivate) + TCompasICDHeader iedCompasICDHeader = PrivateUtils.extractCompasICDHeader(iedPrivate) .orElseThrow(() -> new ScdException(COMPAS_ICDHEADER + "not found in IED Private ")); - TCompasICDHeader scdCompasICDHeader = PrivateService.extractCompasICDHeader(scdPrivate) + TCompasICDHeader scdCompasICDHeader = PrivateUtils.extractCompasICDHeader(scdPrivate) .orElseThrow(() -> new ScdException(COMPAS_ICDHEADER + "not found in LNode Private ")); return Objects.equals(iedCompasICDHeader.getIEDType(), scdCompasICDHeader.getIEDType()) && Objects.equals(iedCompasICDHeader.getICDSystemVersionUUID(), scdCompasICDHeader.getICDSystemVersionUUID()) diff --git a/sct-commons/src/test/java/org/lfenergy/compas/scl2007b4/model/NamespaceConfigurationTest.java b/sct-commons/src/test/java/org/lfenergy/compas/scl2007b4/model/NamespaceConfigurationTest.java index a4b413b91..1b7606cd3 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/scl2007b4/model/NamespaceConfigurationTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/scl2007b4/model/NamespaceConfigurationTest.java @@ -5,7 +5,7 @@ package org.lfenergy.compas.scl2007b4.model; import org.junit.jupiter.api.Test; -import org.lfenergy.compas.sct.commons.scl.PrivateService; +import org.lfenergy.compas.sct.commons.util.PrivateUtils; import org.lfenergy.compas.sct.commons.testhelpers.MarshallerWrapper; import static org.assertj.core.api.Assertions.assertThat; @@ -16,7 +16,7 @@ class NamespaceConfigurationTest { void marshalling_SCL_and_Compas_Privates_should_set_correct_prefix() { // Given SCL scl = createValidScl(); - TPrivate aCompasPrivate = PrivateService.createPrivate(TCompasSclFileType.SCD); + TPrivate aCompasPrivate = PrivateUtils.createPrivate(TCompasSclFileType.SCD); scl.getPrivate().add(aCompasPrivate); // When String result = MarshallerWrapper.marshall(scl); diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ExtRefServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefServiceTest.java similarity index 82% rename from sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ExtRefServiceTest.java rename to sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefServiceTest.java index a30628ff8..d7093b917 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ExtRefServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefServiceTest.java @@ -2,16 +2,20 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.lfenergy.compas.sct.commons.scl; +package org.lfenergy.compas.sct.commons; +import org.assertj.core.api.Assertions; import org.assertj.core.groups.Tuple; 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.AbstractLNAdapter; import org.lfenergy.compas.sct.commons.scl.ied.DataSetAdapter; import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter; @@ -20,7 +24,10 @@ 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; @@ -33,16 +40,20 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; +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.scl.ExtRefService.filterDuplicatedExtRefs; 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 { + @InjectMocks + ExtRefService extRefService; + 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-"; @@ -56,7 +67,7 @@ void updateAllExtRefIedNames_should_update_iedName_and_ExtRefIedName() { // Given : An ExtRef with a matching compas:Flow SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_success.xml"); // When - ExtRefService.updateAllExtRefIedNames(scd); + extRefService.updateAllExtRefIedNames(scd); // Then TExtRef extRef = findExtRef(scd, "IED_NAME1", "LD_INST11", "STAT_LDSUIED_LPDO 1 Sortie_13_BOOLEAN_18_stVal_1"); assertThat(extRef.getIedName()).isEqualTo("IED_NAME2"); @@ -65,7 +76,7 @@ void updateAllExtRefIedNames_should_update_iedName_and_ExtRefIedName() { .getLN0Adapter() .getCurrentElem() .getInputs(); - assertThat(PrivateService.extractCompasPrivate(inputs, TCompasFlow.class)) + Assertions.assertThat(PrivateUtils.extractCompasPrivate(inputs, TCompasFlow.class)) .map(TCompasFlow::getExtRefiedName) .hasValue("IED_NAME2"); } @@ -75,7 +86,7 @@ void updateAllExtRefIedNames_should_return_success_status() { // Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_success.xml"); // When - List sclReportItems = ExtRefService.updateAllExtRefIedNames(scd); + List sclReportItems = extRefService.updateAllExtRefIedNames(scd); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)) .overridingErrorMessage(String.valueOf(sclReportItems)) @@ -87,7 +98,7 @@ void updateAllExtRefIedNames_should_return_success_status() { void updateAllExtRefIedNames_should_report_errors(String testCase, SCL scl, SclReportItem... errors) { // Given : scl parameter // When - List sclReportItems = ExtRefService.updateAllExtRefIedNames(scl); + List sclReportItems = extRefService.updateAllExtRefIedNames(scl); // Then : the sclReport should report all errors described in the comments in the SCD file assertThat(sclReportItems).isNotNull(); assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse(); @@ -161,7 +172,7 @@ void updateAllExtRefIedNames_when_not_bindable_should_clear_binding() { // Given : see comments in SCD file SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_with_extref_errors.xml"); // When - ExtRefService.updateAllExtRefIedNames(scd); + extRefService.updateAllExtRefIedNames(scd); // Then assertExtRefIsNotBound(findExtRef(scd, "IED_NAME1", "LD_INST12", "ExtRef target LDevice status is off")); assertExtRefIsNotBound(findExtRef(scd, "IED_NAME1", "LD_INST11", "Match compas:Flow but FlowStatus is INACTIVE")); @@ -176,7 +187,7 @@ void updateAllExtRefIedNames_when_lDevice_off_should_remove_binding() { // Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_with_extref_errors.xml"); // When - List sclReportItems = ExtRefService.updateAllExtRefIedNames(scd); + List sclReportItems = extRefService.updateAllExtRefIedNames(scd); // Then assertThat(sclReportItems).isNotNull(); LDeviceAdapter lDeviceAdapter = findLDeviceByLdName(scd, "IED_NAME1LD_INST12"); @@ -190,7 +201,7 @@ void updateAllExtRefIedNames_when_FlowStatus_INACTIVE_should_remove_binding() { // Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_with_extref_errors.xml"); // When - List sclReportItems = ExtRefService.updateAllExtRefIedNames(scd); + List sclReportItems = extRefService.updateAllExtRefIedNames(scd); // Then assertThat(sclReportItems).isNotNull(); LDeviceAdapter lDeviceAdapter = findLDeviceByLdName(scd, "IED_NAME1LD_INST11"); @@ -208,7 +219,7 @@ 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); + List sclReportItems = extRefService.createDataSetAndControlBlocks(scd); // Then assertThat(sclReportItems).isEmpty(); assertThat(streamAllDataSets(scd)).hasSize(6); @@ -239,7 +250,7 @@ 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); + List sclReportItems = extRefService.createDataSetAndControlBlocks(scd); // Then assertThat(sclReportItems).isEmpty(); @@ -272,7 +283,7 @@ 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); + List sclReportItems = extRefService.createDataSetAndControlBlocks(scd); // Then assertThat(sclReportItems).isEmpty(); @@ -301,7 +312,7 @@ 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"); + List sclReportItems = extRefService.createDataSetAndControlBlocks(scd, "IED_NAME1"); // Then assertThat(sclReportItems).isEmpty(); assertThat(streamAllDataSets(scd)).hasSize(6); @@ -317,7 +328,7 @@ void createDataSetAndControlBlocks_when_targetIedName_is_provided_and_no_ext_ref // 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"); + List sclReportItems = extRefService.createDataSetAndControlBlocks(scd, "IED_NAME2"); // Then assertThat(sclReportItems).isEmpty(); assertThat(streamAllDataSets(scd)).isEmpty(); @@ -328,7 +339,7 @@ void createDataSetAndControlBlocks_when_targetIedName_is_not_found_should_throw_ // 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")) + assertThatThrownBy(() -> extRefService.createDataSetAndControlBlocks(scd, "non_existing_IED_name")) .isInstanceOf(ScdException.class) .hasMessage("IED.name 'non_existing_IED_name' not found in SCD"); } @@ -338,7 +349,7 @@ void createDataSetAndControlBlocks_when_targetIedName_and_targetLDeviceInst_is_p // 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"); + List sclReportItems = extRefService.createDataSetAndControlBlocks(scd, "IED_NAME1", "LD_INST11"); // Then assertThat(sclReportItems).isEmpty(); } @@ -348,7 +359,7 @@ void createDataSetAndControlBlocks_when_targetIedName_is_not_found_and_targetLDe // 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")) + assertThatThrownBy(() -> extRefService.createDataSetAndControlBlocks(scd, "non_existing_IED_name", "LD_INST11")) .isInstanceOf(ScdException.class) .hasMessage("IED.name 'non_existing_IED_name' not found in SCD"); } @@ -358,7 +369,7 @@ void createDataSetAndControlBlocks_when_targetIedName_and_targetLDeviceInst_is_n // 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")) + assertThatThrownBy(() -> extRefService.createDataSetAndControlBlocks(scd, "IED_NAME1", "non_existing_LDevice_inst")) .isInstanceOf(ScdException.class) .hasMessage("LDevice.inst 'non_existing_LDevice_inst' not found in IED 'IED_NAME1'"); } @@ -368,7 +379,7 @@ void createDataSetAndControlBlocks_when_targetLDeviceInst_is_provided_without_ta // 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")) + assertThatThrownBy(() -> extRefService.createDataSetAndControlBlocks(scd, null, "LD_INST11")) .isInstanceOf(ScdException.class) .hasMessage("IED.name parameter is missing"); } @@ -394,7 +405,7 @@ void updateAllSourceDataSetsAndControlBlocks_should_sort_FCDA_inside_DataSet_and // 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); + List sclReportItems = extRefService.createDataSetAndControlBlocks(scd); // Then assertThat(sclReportItems).isEmpty(); DataSetAdapter dataSetAdapter = findDataSet(scd, "IED_NAME2", "LD_INST21", "DS_LD_INST21_GSI"); @@ -418,7 +429,7 @@ void configureNetworkForAllControlBlocks_should_create_GSE_and_SMV_elements() { ControlBlockNetworkSettings controlBlockNetworkSettings = controlBlockAdapter -> new SettingsOrError(new Settings(0x1D6, (byte) 4, minTime, maxTime), null); // When - List sclReportItems = ExtRefService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, RANGES_PER_CB_TYPE); + 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(); @@ -460,7 +471,7 @@ void configureNetworkForAllControlBlocks_should_create_GSE_with_incremental_appi 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); + List sclReportItems = extRefService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, RANGES_PER_CB_TYPE); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); assertThat(streamAllConnectedApGseP(scd, "APPID")) @@ -477,7 +488,7 @@ void configureNetworkForAllControlBlocks_should_fail_when_no_settings_for_this_c // 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); + List sclReportItems = extRefService.configureNetworkForAllControlBlocks(scd, controlBlockNetworkSettings, rangesPerCbType); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse(); assertThat(sclReportItems) @@ -521,7 +532,7 @@ void filterDuplicatedExtRefs_should_remove_duplicated_extrefs() { List tExtRefList = List.of(tExtRef, tExtRefLnClass, createExtRefExample("CB", TServiceType.GOOSE), createExtRefExample("CB", TServiceType.GOOSE)); // When - List result = ExtRefService.filterDuplicatedExtRefs(tExtRefList); + List result = extRefService.filterDuplicatedExtRefs(tExtRefList); // Then assertThat(result).hasSizeLessThan(tExtRefList.size()) .hasSize(2); @@ -541,7 +552,7 @@ void filterDuplicatedExtRefs_should_not_remove_not_duplicated_extrefs() { List tExtRefList = List.of(tExtRefIedName, tExtRefLdInst, tExtRefLnInst, tExtRefPrefix, createExtRefExample("CB_1", TServiceType.GOOSE), createExtRefExample("CB_1", TServiceType.SMV)); // When - List result = filterDuplicatedExtRefs(tExtRefList); + List result = extRefService.filterDuplicatedExtRefs(tExtRefList); // Then assertThat(result).hasSameSizeAs(tExtRefList) .hasSize(6); @@ -570,7 +581,7 @@ void manageBindingForLDEPF_should_return_noReportAndExtRefUpdateSuccessfully_whe .build(); // When - List sclReportItems = ExtRefService.manageBindingForLDEPF(scd, settingLDEPFCsvHelper); + List sclReportItems = extRefService.manageBindingForLDEPF(scd, settingLDEPFCsvHelper); // Then assertThat(sclReportItems).isEmpty(); TExtRef extRef1 = findExtRef(scd, "IED_NAME1", "LDEPF", "DYN_LDEPF_DIGITAL CHANNEL 1_1_BOOLEEN_1_general_1"); @@ -614,7 +625,6 @@ void manageBindingForLDEPF_should_return_noReportAndExtRefUpdateSuccessfully_whe } - @Test void manageBindingForLDEPF_should_return_no_report_when_extRef_withDifferentIedType_update_successfully() { String fileName = "LDEPF_Setting_file.csv"; @@ -623,7 +633,7 @@ void manageBindingForLDEPF_should_return_no_report_when_extRef_withDifferentIedT SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_extref_with_BCU_BPU.xml"); SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); // When - List sclReportItems = ExtRefService.manageBindingForLDEPF(scd, settingLDEPFCsvHelper); + List sclReportItems = extRefService.manageBindingForLDEPF(scd, settingLDEPFCsvHelper); // Then assertThat(sclReportItems).isEmpty(); SclTestMarshaller.assertIsMarshallable(new SclRootAdapter(scd).getCurrentElem()); @@ -701,7 +711,7 @@ void manageBindingForLDEPF_should_return_report_when_manyIedSourceFound() { SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_manyIedSources_in_same_bay.xml"); ILDEPFSettings settings = new SettingLDEPFCsvHelper(reader); // When - List sclReportItems = ExtRefService.manageBindingForLDEPF(scd, settings); + List sclReportItems = extRefService.manageBindingForLDEPF(scd, settings); // Then assertThat(sclReportItems).hasSize(2) .extracting(SclReportItem::message) @@ -743,7 +753,7 @@ void manageBindingForLDEPF_should_return_no_report_when_extRefInFlowKindInternal SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ldepf/scd_ldepf_dataTypeTemplateValid.xml"); SettingLDEPFCsvHelper settingLDEPFCsvHelper = new SettingLDEPFCsvHelper(reader); // When - List sclReportItems = ExtRefService.manageBindingForLDEPF(scd, settingLDEPFCsvHelper); + List sclReportItems = extRefService.manageBindingForLDEPF(scd, settingLDEPFCsvHelper); // Then assertThat(sclReportItems).isEmpty(); SclTestMarshaller.assertIsMarshallable(scd); @@ -804,4 +814,156 @@ private LDEPFSettingData getLDEPFSettingByAnalogNum(List setti .findFirst().get(); } + @Test + void updateExtRefSource_shouldThrowScdException_whenSignalInfoNullOrInvalid() { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); + ExtRefInfo extRefInfo = new ExtRefInfo(); + extRefInfo.setHolderIEDName("IED_NAME2"); + extRefInfo.setHolderLDInst("LD_INST21"); + extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); + + //When Then + assertThat(extRefInfo.getSignalInfo()).isNull(); + assertThatThrownBy(() -> extRefService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // signal = null + extRefInfo.setSignalInfo(new ExtRefSignalInfo()); + assertThat(extRefInfo.getSignalInfo()).isNotNull(); + assertThatThrownBy(() -> extRefService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class);// signal invalid + } + + @Test + void updateExtRefSource_shouldThrowScdException_whenBindingInfoNullOrInvalid() { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); + ExtRefInfo extRefInfo = new ExtRefInfo(); + extRefInfo.setHolderIEDName("IED_NAME2"); + extRefInfo.setHolderLDInst("LD_INST21"); + extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); + + ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo(); + extRefSignalInfo.setIntAddr("INT_ADDR21"); + extRefSignalInfo.setPDA("da21.bda211.bda212.bda213"); + extRefSignalInfo.setPDO("Do21.sdo21"); + extRefInfo.setSignalInfo(extRefSignalInfo); + //When Then + assertThat(extRefInfo.getBindingInfo()).isNull(); + assertThatThrownBy(() -> extRefService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // binding = null + extRefInfo.setBindingInfo(new ExtRefBindingInfo()); + assertThat(extRefInfo.getBindingInfo()).isNotNull(); + assertThatThrownBy(() -> extRefService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class);// binding invalid + } + + @Test + void updateExtRefSource_shouldThrowScdException_whenBindingInternalByIedName() { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); + ExtRefInfo extRefInfo = new ExtRefInfo(); + extRefInfo.setHolderIEDName("IED_NAME2"); + extRefInfo.setHolderLDInst("LD_INST21"); + extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); + + ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo(); + extRefSignalInfo.setIntAddr("INT_ADDR21"); + extRefSignalInfo.setPDA("da21.bda211.bda212.bda213"); + extRefSignalInfo.setPDO("Do21.sdo21"); + extRefInfo.setSignalInfo(extRefSignalInfo); + + ExtRefBindingInfo extRefBindingInfo = new ExtRefBindingInfo(); + extRefBindingInfo.setIedName("IED_NAME2"); // internal binding + extRefBindingInfo.setLdInst("LD_INST12"); + extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value()); + extRefInfo.setBindingInfo(new ExtRefBindingInfo()); + //When Then + assertThatThrownBy(() -> extRefService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // CB not allowed + } + + @Test + void updateExtRefSource_shouldThrowScdException_whenBindingInternaByServiceType() { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); + ExtRefInfo extRefInfo = new ExtRefInfo(); + extRefInfo.setHolderIEDName("IED_NAME2"); + extRefInfo.setHolderLDInst("LD_INST21"); + extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); + + ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo(); + extRefSignalInfo.setIntAddr("INT_ADDR21"); + extRefSignalInfo.setPDA("da21.bda211.bda212.bda213"); + extRefSignalInfo.setPDO("Do21.sdo21"); + extRefInfo.setSignalInfo(extRefSignalInfo); + + ExtRefBindingInfo extRefBindingInfo = new ExtRefBindingInfo(); + extRefBindingInfo.setIedName("IED_NAME2"); // internal binding + extRefBindingInfo.setLdInst("LD_INST12"); + extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value()); + extRefBindingInfo.setServiceType(TServiceType.POLL); + extRefInfo.setBindingInfo(new ExtRefBindingInfo()); + //When Then + assertThatThrownBy(() -> extRefService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // CB not allowed + } + + @Test + void updateExtRefSource_shouldThrowScdException_whenSourceInfoNullOrInvalid() { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); + ExtRefInfo extRefInfo = new ExtRefInfo(); + extRefInfo.setHolderIEDName("IED_NAME2"); + extRefInfo.setHolderLDInst("LD_INST21"); + extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); + + ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo(); + extRefSignalInfo.setIntAddr("INT_ADDR21"); + extRefSignalInfo.setPDA("da21.bda211.bda212.bda213"); + extRefSignalInfo.setPDO("Do21.sdo21"); + extRefInfo.setSignalInfo(extRefSignalInfo); + + ExtRefBindingInfo extRefBindingInfo = new ExtRefBindingInfo(); + extRefBindingInfo.setIedName("IED_NAME1"); // internal binding + extRefBindingInfo.setLdInst("LD_INST12"); + extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value()); + extRefInfo.setBindingInfo(new ExtRefBindingInfo()); + + //When Then + assertThat(extRefInfo.getSourceInfo()).isNull(); + assertThatThrownBy(() -> extRefService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // signal = null + extRefInfo.setSourceInfo(new ExtRefSourceInfo()); + assertThat(extRefInfo.getSourceInfo()).isNotNull(); + assertThatThrownBy(() -> extRefService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class);// signal invalid + } + + @Test + void updateExtRefSource_shouldThrowScdException_whenBindingExternalBinding() { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); + ExtRefInfo extRefInfo = new ExtRefInfo(); + extRefInfo.setHolderIEDName("IED_NAME2"); + extRefInfo.setHolderLDInst("LD_INST21"); + extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); + + ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo(); + extRefSignalInfo.setIntAddr("INT_ADDR21"); + extRefSignalInfo.setPDA("da21.bda211.bda212.bda213"); + extRefSignalInfo.setPDO("Do21.sdo21"); + extRefInfo.setSignalInfo(extRefSignalInfo); + + ExtRefBindingInfo extRefBindingInfo = new ExtRefBindingInfo(); + extRefBindingInfo.setIedName("IED_NAME1"); + extRefBindingInfo.setLdInst("LD_INST12"); + extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value()); + extRefInfo.setBindingInfo(extRefBindingInfo); + + ExtRefSourceInfo sourceInfo = new ExtRefSourceInfo(); + sourceInfo.setSrcLDInst(extRefInfo.getBindingInfo().getLdInst()); + sourceInfo.setSrcLNClass(extRefInfo.getBindingInfo().getLnClass()); + sourceInfo.setSrcCBName("goose1"); + extRefInfo.setSourceInfo(sourceInfo); + + //When + TExtRef extRef = assertDoesNotThrow(() -> extRefService.updateExtRefSource(scd, extRefInfo)); + //Then + assertThat(extRef.getSrcCBName()).isEqualTo(extRefInfo.getSourceInfo().getSrcCBName()); + assertThat(extRef.getSrcLDInst()).isEqualTo(extRefInfo.getBindingInfo().getLdInst()); + assertThat(extRef.getSrcLNClass()).contains(extRefInfo.getBindingInfo().getLnClass()); + } + } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/HmiServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/HmiServiceTest.java similarity index 93% rename from sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/HmiServiceTest.java rename to sct-commons/src/test/java/org/lfenergy/compas/sct/commons/HmiServiceTest.java index 5cf61c0b4..a13a86efb 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/HmiServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/HmiServiceTest.java @@ -2,9 +2,10 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.lfenergy.compas.sct.commons.scl; +package org.lfenergy.compas.sct.commons; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.lfenergy.compas.scl2007b4.model.*; import org.lfenergy.compas.sct.commons.scl.ied.DataSetAdapter; import org.lfenergy.compas.sct.commons.scl.ied.LN0Adapter; @@ -12,6 +13,8 @@ import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; import org.lfenergy.compas.sct.commons.util.CommonConstants; import org.lfenergy.compas.sct.commons.util.LdeviceStatus; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; import java.util.List; @@ -19,15 +22,19 @@ import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.*; import static org.lfenergy.compas.sct.commons.util.SclConstructorHelper.newFcda; +@ExtendWith(MockitoExtension.class) class HmiServiceTest { + @InjectMocks + HmiService hmiService; + @Test void createAllIhmReportControlBlocks_with_fc_ST_should_create_dataset_and_controlblock() { // Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-hmi-create-report-cb/scd_create_dataset_and_controlblocks_for_hmi.xml"); TFCDA fcda = newFcda("LdInst11", "ANCR", "1", null, "DoName1", null, TFCEnum.ST); // When - HmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); + hmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); // Then // Check DataSet is created DataSetAdapter dataSet = findDataSet(scd, "IedName1", "LdInst11", "DS_LDINST11_DQPO"); @@ -53,7 +60,7 @@ void createAllIhmReportControlBlocks_with_fc_MX_should_create_dataset_and_contro SCL scd = SclTestMarshaller.getSCLFromFile("/scd-hmi-create-report-cb/scd_create_dataset_and_controlblocks_for_hmi.xml"); TFCDA fcda = newFcda("LdInst11", "PVOC", "1", null, "DoName2", null, TFCEnum.MX); // When - HmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); + hmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); // Then // Check DataSet is created DataSetAdapter dataSet = findDataSet(scd, "IedName1", "LdInst11", "DS_LDINST11_CYPO"); @@ -80,7 +87,7 @@ void createAllIhmReportControlBlocks_with_FCDA_on_ln0_should_create_dataset_and_ SCL scd = SclTestMarshaller.getSCLFromFile("/scd-hmi-create-report-cb/scd_create_dataset_and_controlblocks_for_hmi.xml"); TFCDA fcda = newFcda("LdInst11", "LLN0", null, null, "DoName0", null, TFCEnum.ST); // When - HmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); + hmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); // Then // Check DataSet is created DataSetAdapter dataSet = findDataSet(scd, "IedName1", "LdInst11", "DS_LDINST11_DQPO"); @@ -108,7 +115,7 @@ void createAllIhmReportControlBlocks_when_lDevice_ON_but_LN_Mod_StVal_missing_sh ln.getCurrentElem().unsetDOI(); TFCDA fcda = newFcda("LdInst11", "ANCR", "1", null, "DoName1", null, TFCEnum.ST); // When - HmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); + hmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); // Then // Check DataSet is created DataSetAdapter dataSet = findDataSet(scd, "IedName1", "LdInst11", "DS_LDINST11_DQPO"); @@ -132,7 +139,7 @@ void createAllIhmReportControlBlocks_when_lDevice_ON_but_LN_Mod_StVal_OFF_should assertThat(ln.getDaiModStValValue()).hasValue("off"); TFCDA fcda = newFcda("LdInst11", "ANCR", "1", null, "DoName1", null, TFCEnum.ST); // When - HmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); + hmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); // Then assertThat(streamAllDataSets(scd)).isEmpty(); assertThat(streamAllControlBlocks(scd, TReportControl.class)).isEmpty(); @@ -147,7 +154,7 @@ void createAllIhmReportControlBlocks_when_lDevice_OFF_should_not_create_dataset( assertThat(findLDevice(scd, "IedName1", "LdInst11").getLDeviceStatus()).hasValue(LdeviceStatus.OFF.getValue()); TFCDA fcda = newFcda("LdInst11", "ANCR", "1", null, "DoName1", null, TFCEnum.ST); // When - HmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); + hmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); // Then assertThat(streamAllDataSets(scd)).isEmpty(); assertThat(streamAllControlBlocks(scd, TReportControl.class)).isEmpty(); @@ -162,7 +169,7 @@ void createAllIhmReportControlBlocks_when_LDevice_has_no_status_should_not_creat assertThat(findLDevice(scd, "IedName1", "LdInst11").getLDeviceStatus()).isEmpty(); TFCDA fcda = newFcda("LdInst11", "ANCR", "1", null, "DoName1", null, TFCEnum.ST); // When - HmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); + hmiService.createAllHmiReportControlBlocks(scd, List.of(fcda)); // Then assertThat(streamAllDataSets(scd)).isEmpty(); assertThat(streamAllControlBlocks(scd, TReportControl.class)).isEmpty(); diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclEditorServiceTest.java similarity index 50% rename from sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java rename to sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclEditorServiceTest.java index 54d598e9a..0b660677e 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclEditorServiceTest.java @@ -2,11 +2,11 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.lfenergy.compas.sct.commons.scl; +package org.lfenergy.compas.sct.commons; -import org.apache.commons.lang3.StringUtils; import org.assertj.core.groups.Tuple; 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.CsvSource; @@ -14,25 +14,29 @@ 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.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.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; -import static org.assertj.core.api.Assertions.assertThatThrownBy; import static org.junit.jupiter.api.Assertions.*; -import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDa; -import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDo; import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.LD_SUIED; import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.getDAIAdapters; import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable; import static org.lfenergy.compas.sct.commons.util.PrivateEnum.COMPAS_SCL_FILE_TYPE; -class SclServiceTest { +@ExtendWith(MockitoExtension.class) +class SclEditorServiceTest { + + @InjectMocks + SclEditorService sclEditorService; private static Stream sclProviderMissingRequiredObjects() { SCL scl1 = SclTestMarshaller.getSCLFromFile("/scd-refresh-lnode/issue68_Test_KO_MissingBeh.scd"); @@ -92,7 +96,7 @@ void testAddHistoryItem() throws ScdException { SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); SCL scd = sclRootAdapter.getCurrentElem(); - SclService.addHistoryItem(scd, "who", "what", "why"); + sclEditorService.addHistoryItem(scd, "who", "what", "why"); assertNotNull(scd.getHeader()); THeader.History history = scd.getHeader().getHistory(); @@ -115,7 +119,7 @@ void testAddIED() { assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd)); + assertDoesNotThrow(() -> sclEditorService.addIED(scd, "IED_NAME1", icd)); assertEquals("IED_NAME1", scd.getIED().get(0).getName()); assertNotNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); @@ -129,7 +133,7 @@ void testAddSubnetworks() { assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd)); + assertDoesNotThrow(() -> sclEditorService.addIED(scd, "IED_NAME1", icd)); SubNetworkDTO subNetworkDTO = new SubNetworkDTO(); subNetworkDTO.setName("sName1"); @@ -137,7 +141,7 @@ void testAddSubnetworks() { ConnectedApDTO connectedApDTO = new ConnectedApDTO("IED_NAME1", "AP_NAME"); subNetworkDTO.addConnectedAP(connectedApDTO); - assertDoesNotThrow(() -> SclService.addSubnetworks(scd, List.of(subNetworkDTO), icd)); + assertDoesNotThrow(() -> sclEditorService.addSubnetworks(scd, List.of(subNetworkDTO), icd)); assertIsMarshallable(scd); } @@ -148,588 +152,17 @@ void testAddSubnetworksWithoutCommunicationTagInIcd() { assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd)); + assertDoesNotThrow(() -> sclEditorService.addIED(scd, "IED_NAME1", icd)); - assertDoesNotThrow(() -> SclService.addSubnetworks(scd, List.of(), icd)); + assertDoesNotThrow(() -> sclEditorService.addSubnetworks(scd, List.of(), icd)); String marshalledScd = assertIsMarshallable(scd); assertThat(marshalledScd).doesNotContain(" SclService.addIED(scd, "IED_NAME1", icd)); - - List subNetworkDTOSet = SclService.getSubnetwork(icd); - assertDoesNotThrow(() -> SclService.addSubnetworks(scd, subNetworkDTOSet, icd)); - - String marshalledScd = assertIsMarshallable(scd); - assertThat(marshalledScd).contains("
    ", "PhysConn"); - } - - @Test - void testAddSubnetworksWithoutImportingIcdAddressAndPhysConn() { - SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); - SCL scd = sclRootAdapter.getCurrentElem(); - assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); - SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_with_filled_communication.xml"); - - assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd)); - - List subNetworkDTOSet = SclService.getSubnetwork(icd); - assertDoesNotThrow(() -> SclService.addSubnetworks(scd, subNetworkDTOSet, null)); - - String marshalledScd = assertIsMarshallable(scd); - assertThat(marshalledScd).doesNotContain("
    ", "PhysConn"); - } - - @Test - void testGetSubnetwork() { - SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); - SCL scd = sclRootAdapter.getCurrentElem(); - assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); - SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - - assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd)); - - SubNetworkDTO subNetworkDTO = new SubNetworkDTO(); - subNetworkDTO.setName("sName1"); - subNetworkDTO.setType("IP"); - ConnectedApDTO connectedApDTO = new ConnectedApDTO("IED_NAME1", "AP_NAME"); - subNetworkDTO.addConnectedAP(connectedApDTO); - - assertDoesNotThrow(() -> SclService.addSubnetworks(scd, List.of(subNetworkDTO), icd)); - - List subNetworkDTOS = assertDoesNotThrow(() -> SclService.getSubnetwork(scd)); - assertEquals(1, subNetworkDTOS.size()); - } - - @Test - void testGetExtRefInfo() { - SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); - SCL scd = sclRootAdapter.getCurrentElem(); - assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); - SCL icd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - - assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd)); - var extRefInfos = assertDoesNotThrow(() -> SclService.getExtRefInfo(scd, "IED_NAME1", "LD_INST11")); - assertEquals(1, extRefInfos.size()); - - assertEquals("IED_NAME1", extRefInfos.get(0).getHolderIEDName()); - - assertThrows(ScdException.class, () -> SclService.getExtRefInfo(scd, "IED_NAME1", "UNKNOWN_LD")); - } - - @Test - void getExtRefBinders_shouldThowScdException_whenExtRefNotExist() { - //Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_binders_test.xml"); - - ExtRefSignalInfo signalInfo = createSignalInfo("Do11.sdo11", "da11.bda111.bda112.bda113", "INT_ADDR11"); - signalInfo.setPLN("ANCR"); - //When Then - assertThatThrownBy( - () -> SclService.getExtRefBinders(scd, "IED_NAME1", "UNKNOWN_LD", "LLN0", "", "", signalInfo)) - .isInstanceOf(ScdException.class); - } - - @Test - void getExtRefBinders_shouldReturnSortedListBindingInfo_whenExtRefAndDOExist() { - // Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_binders_test.xml"); - - ExtRefSignalInfo signalInfo = createSignalInfo( - "Do11.sdo11", "da11.bda111.bda112.bda113", "INT_ADDR11" - ); - signalInfo.setPLN("ANCR"); - - // When - List potentialBinders = SclService.getExtRefBinders(scd, "IED_NAME1", "LD_INST11", "LLN0", "", "", signalInfo); - - // Then - assertThat(potentialBinders).hasSize(4); - assertThat(potentialBinders) - .extracting(ExtRefBindingInfo::getIedName) - .containsExactly("IED_NAME1", "IED_NAME1", "IED_NAME2", "IED_NAME3"); - assertThat(potentialBinders) - .extracting(ExtRefBindingInfo::getLdInst) - .containsExactly("LD_INST11", "LD_INST12", "LD_INST22", "LD_INST31"); - assertThat(potentialBinders) - .extracting(ExtRefBindingInfo::getLnClass) - .containsExactly("ANCR", "ANCR", "ANCR", "ANCR"); - assertThat(potentialBinders) - .extracting(ExtRefBindingInfo::getLnInst) - .containsExactly("1", "1", "2", "3"); - } - - @Test - void testUpdateExtRefBinders() { - SclRootAdapter sclRootAdapter = new SclRootAdapter("hId", SclRootAdapter.VERSION, SclRootAdapter.REVISION); - SCL scd = sclRootAdapter.getCurrentElem(); - assertNull(sclRootAdapter.getCurrentElem().getDataTypeTemplates()); - SCL icd1 = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - SCL icd2 = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_2_test.xml"); - - assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME1", icd1)); - assertDoesNotThrow(() -> SclService.addIED(scd, "IED_NAME2", icd2)); - - ExtRefSignalInfo signalInfo = createSignalInfo( - "Do11.sdo11", "da11.bda111.bda112.bda113", "INT_ADDR11" - ); - signalInfo.setPServT(null); - signalInfo.setPLN(null); - signalInfo.setDesc(null); - // Signal for external binding (in IED 2 LD_INST22 - PIOC) - ExtRefBindingInfo bindingInfo = new ExtRefBindingInfo(); - bindingInfo.setIedName("IED_NAME2"); - bindingInfo.setLdInst("LD_INST22"); - bindingInfo.setLnClass("PIOC"); - bindingInfo.setLnInst("1"); - bindingInfo.setLnType("LN2"); - bindingInfo.setDoName(new DoTypeName(signalInfo.getPDO())); - bindingInfo.setDaName(new DaTypeName(signalInfo.getPDA())); - bindingInfo.setServiceType(signalInfo.getPServT()); - LNodeDTO lNodeDTO = new LNodeDTO(); - lNodeDTO.setNodeClass(TLLN0Enum.LLN_0.value()); - ExtRefInfo extRefInfo = new ExtRefInfo(); - extRefInfo.setHolderIEDName("IED_NAME1"); - extRefInfo.setHolderLDInst("LD_INST11"); - extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); - extRefInfo.setSignalInfo(signalInfo); - extRefInfo.setBindingInfo(bindingInfo); - lNodeDTO.getExtRefs().add(extRefInfo); - - assertDoesNotThrow( - () -> SclService.updateExtRefBinders(scd, extRefInfo) - ); - - extRefInfo.setHolderLDInst("UNKNOWN_LD"); - assertThrows( - ScdException.class, - () -> SclService.updateExtRefBinders(scd, extRefInfo) - ); - assertIsMarshallable(scd); - } - - @Test - void getExtRefSourceInfo_shouldReturnEmptyList_whenExtRefMatchNoFCDA() { - //Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); - String iedName = "IED_NAME2"; - String ldInst = "LD_INST21"; - String lnClass = TLLN0Enum.LLN_0.value(); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); - LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iedAdapter.findLDeviceAdapterByLdInst(ldInst).get()); - LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter(); - List extRefs = ln0Adapter.getExtRefs(null); - assertFalse(extRefs.isEmpty()); - - ExtRefInfo extRefInfo = new ExtRefInfo(extRefs.get(0)); - - extRefInfo.setHolderIEDName(iedName); - extRefInfo.setHolderLDInst(ldInst); - extRefInfo.setHolderLnClass(lnClass); - - //When - List controlBlocks = SclService.getExtRefSourceInfo(scd, extRefInfo); - - //Then - assertThat(controlBlocks).isEmpty(); - } - - @Test - void getExtRefSourceInfo_shouldReturnListOfControlBlocks_whenExtRefMatchFCDA() { - //Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/issue_175_scd_get_cbs_test.xml"); - String iedName = "IED_NAME2"; - String ldInst = "LD_INST21"; - String lnClass = TLLN0Enum.LLN_0.value(); - SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); - LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iedAdapter.findLDeviceAdapterByLdInst(ldInst).get()); - LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter(); - List extRefs = ln0Adapter.getExtRefs(null); - assertFalse(extRefs.isEmpty()); - - ExtRefInfo extRefInfo = new ExtRefInfo(extRefs.get(0)); - - extRefInfo.setHolderIEDName(iedName); - extRefInfo.setHolderLDInst(ldInst); - extRefInfo.setHolderLnClass(lnClass); - - //When - List controlBlocks = SclService.getExtRefSourceInfo(scd, extRefInfo); - - //Then - assertThat(controlBlocks).hasSize(1); - assertThat(controlBlocks.get(0).getName()).isEqualTo("goose2"); - } - - @Test - void updateExtRefSource_shouldThrowScdException_whenSignalInfoNullOrInvalid() { - //Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); - ExtRefInfo extRefInfo = new ExtRefInfo(); - extRefInfo.setHolderIEDName("IED_NAME2"); - extRefInfo.setHolderLDInst("LD_INST21"); - extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); - - //When Then - assertThat(extRefInfo.getSignalInfo()).isNull(); - assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // signal = null - extRefInfo.setSignalInfo(new ExtRefSignalInfo()); - assertThat(extRefInfo.getSignalInfo()).isNotNull(); - assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class);// signal invalid - } - - @Test - void updateExtRefSource_shouldThrowScdException_whenBindingInfoNullOrInvalid() { - //Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); - ExtRefInfo extRefInfo = new ExtRefInfo(); - extRefInfo.setHolderIEDName("IED_NAME2"); - extRefInfo.setHolderLDInst("LD_INST21"); - extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); - - ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo(); - extRefSignalInfo.setIntAddr("INT_ADDR21"); - extRefSignalInfo.setPDA("da21.bda211.bda212.bda213"); - extRefSignalInfo.setPDO("Do21.sdo21"); - extRefInfo.setSignalInfo(extRefSignalInfo); - //When Then - assertThat(extRefInfo.getBindingInfo()).isNull(); - assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // binding = null - extRefInfo.setBindingInfo(new ExtRefBindingInfo()); - assertThat(extRefInfo.getBindingInfo()).isNotNull(); - assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class);// binding invalid - } - - @Test - void updateExtRefSource_shouldThrowScdException_whenBindingInternalByIedName() { - //Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); - ExtRefInfo extRefInfo = new ExtRefInfo(); - extRefInfo.setHolderIEDName("IED_NAME2"); - extRefInfo.setHolderLDInst("LD_INST21"); - extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); - - ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo(); - extRefSignalInfo.setIntAddr("INT_ADDR21"); - extRefSignalInfo.setPDA("da21.bda211.bda212.bda213"); - extRefSignalInfo.setPDO("Do21.sdo21"); - extRefInfo.setSignalInfo(extRefSignalInfo); - - ExtRefBindingInfo extRefBindingInfo = new ExtRefBindingInfo(); - extRefBindingInfo.setIedName("IED_NAME2"); // internal binding - extRefBindingInfo.setLdInst("LD_INST12"); - extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value()); - extRefInfo.setBindingInfo(new ExtRefBindingInfo()); - //When Then - assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // CB not allowed - } - - @Test - void updateExtRefSource_shouldThrowScdException_whenBindingInternaByServiceType() { - //Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); - ExtRefInfo extRefInfo = new ExtRefInfo(); - extRefInfo.setHolderIEDName("IED_NAME2"); - extRefInfo.setHolderLDInst("LD_INST21"); - extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); - - ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo(); - extRefSignalInfo.setIntAddr("INT_ADDR21"); - extRefSignalInfo.setPDA("da21.bda211.bda212.bda213"); - extRefSignalInfo.setPDO("Do21.sdo21"); - extRefInfo.setSignalInfo(extRefSignalInfo); - - ExtRefBindingInfo extRefBindingInfo = new ExtRefBindingInfo(); - extRefBindingInfo.setIedName("IED_NAME2"); // internal binding - extRefBindingInfo.setLdInst("LD_INST12"); - extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value()); - extRefBindingInfo.setServiceType(TServiceType.POLL); - extRefInfo.setBindingInfo(new ExtRefBindingInfo()); - //When Then - assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // CB not allowed - } - - @Test - void updateExtRefSource_shouldThrowScdException_whenSourceInfoNullOrInvalid() { - //Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); - ExtRefInfo extRefInfo = new ExtRefInfo(); - extRefInfo.setHolderIEDName("IED_NAME2"); - extRefInfo.setHolderLDInst("LD_INST21"); - extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); - - ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo(); - extRefSignalInfo.setIntAddr("INT_ADDR21"); - extRefSignalInfo.setPDA("da21.bda211.bda212.bda213"); - extRefSignalInfo.setPDO("Do21.sdo21"); - extRefInfo.setSignalInfo(extRefSignalInfo); - - ExtRefBindingInfo extRefBindingInfo = new ExtRefBindingInfo(); - extRefBindingInfo.setIedName("IED_NAME1"); // internal binding - extRefBindingInfo.setLdInst("LD_INST12"); - extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value()); - extRefInfo.setBindingInfo(new ExtRefBindingInfo()); - - //When Then - assertThat(extRefInfo.getSourceInfo()).isNull(); - assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // signal = null - extRefInfo.setSourceInfo(new ExtRefSourceInfo()); - assertThat(extRefInfo.getSourceInfo()).isNotNull(); - assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class);// signal invalid - } - - @Test - void updateExtRefSource_shouldThrowScdException_whenBindingExternalBinding() { - //Given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); - ExtRefInfo extRefInfo = new ExtRefInfo(); - extRefInfo.setHolderIEDName("IED_NAME2"); - extRefInfo.setHolderLDInst("LD_INST21"); - extRefInfo.setHolderLnClass(TLLN0Enum.LLN_0.value()); - - ExtRefSignalInfo extRefSignalInfo = new ExtRefSignalInfo(); - extRefSignalInfo.setIntAddr("INT_ADDR21"); - extRefSignalInfo.setPDA("da21.bda211.bda212.bda213"); - extRefSignalInfo.setPDO("Do21.sdo21"); - extRefInfo.setSignalInfo(extRefSignalInfo); - - ExtRefBindingInfo extRefBindingInfo = new ExtRefBindingInfo(); - extRefBindingInfo.setIedName("IED_NAME1"); - extRefBindingInfo.setLdInst("LD_INST12"); - extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value()); - extRefInfo.setBindingInfo(extRefBindingInfo); - - ExtRefSourceInfo sourceInfo = new ExtRefSourceInfo(); - sourceInfo.setSrcLDInst(extRefInfo.getBindingInfo().getLdInst()); - sourceInfo.setSrcLNClass(extRefInfo.getBindingInfo().getLnClass()); - sourceInfo.setSrcCBName("goose1"); - extRefInfo.setSourceInfo(sourceInfo); - - //When - TExtRef extRef = assertDoesNotThrow(() -> SclService.updateExtRefSource(scd, extRefInfo)); - //Then - assertThat(extRef.getSrcCBName()).isEqualTo(extRefInfo.getSourceInfo().getSrcCBName()); - assertThat(extRef.getSrcLDInst()).isEqualTo(extRefInfo.getBindingInfo().getLdInst()); - assertThat(extRef.getSrcLNClass()).contains(extRefInfo.getBindingInfo().getLnClass()); - } - - private ExtRefSignalInfo createSignalInfo(String pDO, String pDA, String intAddr) { - - final String DESC = "DESC"; - final String P_LN = TLLN0Enum.LLN_0.value(); - final String P_SERV_T = "Report"; - - ExtRefSignalInfo signalInfo = new ExtRefSignalInfo(); - signalInfo.setDesc(DESC); - signalInfo.setPDA(pDA); - signalInfo.setPDO(pDO); - signalInfo.setPLN(P_LN); - signalInfo.setPServT(TServiceType.fromValue(P_SERV_T)); - signalInfo.setIntAddr(intAddr); - - return signalInfo; - } - - @Test - void getDAI_should_return_all_dai() { - // given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - - // when - Set allResults = SclService.getDAI(scd, "IED_NAME1", "LD_INST12", new DataAttributeRef(), true); - - // then - assertThat(allResults).hasSize(733); - - List resultsWithDa = allResults.stream().filter(rdt -> StringUtils.isNotBlank(rdt.getDaRef())).collect(Collectors.toList()); - assertThat(resultsWithDa).hasSize(733); - - List resultsWithNoBda = allResults.stream().filter(rdt -> rdt.getBdaNames().isEmpty()).collect(Collectors.toList()); - assertThat(resultsWithNoBda).hasSize(3); - List resultsWithBdaDepth1 = allResults.stream().filter(rdt -> rdt.getBdaNames().size() == 1).collect(Collectors.toList()); - assertThat(resultsWithBdaDepth1).isEmpty(); - List resultsWithBdaDepth2 = allResults.stream().filter(rdt -> rdt.getBdaNames().size() == 2).collect(Collectors.toList()); - assertThat(resultsWithBdaDepth2).hasSize(1); - List resultsWithBdaDepth3 = allResults.stream().filter(rdt -> rdt.getBdaNames().size() == 3).collect(Collectors.toList()); - assertThat(resultsWithBdaDepth3).hasSize(729); - - - List resultsWithDo = allResults.stream().filter(rdt -> StringUtils.isNotBlank(rdt.getDoRef())).collect(Collectors.toList()); - assertThat(resultsWithDo).hasSize(733); - - List resultsWithNoSdo = allResults.stream().filter(rdt -> rdt.getSdoNames().isEmpty()).collect(Collectors.toList()); - assertThat(resultsWithNoSdo).hasSize(3); - List resultsWithSdoDepth1 = allResults.stream().filter(rdt -> rdt.getSdoNames().size() == 1).collect(Collectors.toList()); - assertThat(resultsWithSdoDepth1).isEmpty(); - List resultsWithSdoDepth2 = allResults.stream().filter(rdt -> rdt.getSdoNames().size() == 2).collect(Collectors.toList()); - assertThat(resultsWithSdoDepth2).hasSize(730); - List resultsWithSdoDepth3 = allResults.stream().filter(rdt -> rdt.getSdoNames().size() == 3).collect(Collectors.toList()); - assertThat(resultsWithSdoDepth3).isEmpty(); - } - - @Test - void getDAI_should_aggregate_attribute_from_DAI() { - // given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_aggregate_DAI.xml"); - - // when - Set dais = SclService.getDAI(scd, "VirtualBCU", "LDMODEXPF", new DataAttributeRef(), false); - - // then - DataAttributeRef lln0 = DataAttributeRef.builder().prefix("").lnType("lntype1").lnClass("LLN0").lnInst("").build(); - DataAttributeRef lln0DoA = lln0.toBuilder().doName(createDo("DoA", TPredefinedCDCEnum.DPL)).build(); - DataAttributeRef lln0DoB = lln0.toBuilder().doName(createDo("DoB", TPredefinedCDCEnum.ACD)).build(); - - assertThat(dais).containsExactlyInAnyOrder( - lln0DoA.toBuilder().daName(createDa("daNotInDai", TFCEnum.CF, false, Map.of(0L, "0"))).build(), - lln0DoA.toBuilder().daName(createDa("daNotInDai2", TFCEnum.CF, true, Map.of())).build(), - lln0DoA.toBuilder().daName(createDa("daiOverrideVal", TFCEnum.CF, false, Map.of(0L, "1"))).build(), - lln0DoA.toBuilder().daName(createDa("daiOverrideValImport", TFCEnum.CF, true, Map.of())).build(), - lln0DoA.toBuilder().daName(createDa("daiOverrideValImport2", TFCEnum.CF, false, Map.of())).build(), - - lln0DoB.toBuilder().daName(createDa("structDa.daNotInDai", TFCEnum.ST, false, Map.of(0L, "0"))).build(), - lln0DoB.toBuilder().daName(createDa("structDa.daNotInDai2", TFCEnum.ST, true, Map.of())).build(), - lln0DoB.toBuilder().daName(createDa("structDa.daiOverrideVal", TFCEnum.ST, false, Map.of(0L, "1"))).build(), - lln0DoB.toBuilder().daName(createDa("structDa.daiOverrideValImport", TFCEnum.ST, true, Map.of())).build(), - lln0DoB.toBuilder().daName(createDa("structDa.daiOverrideValImport2", TFCEnum.ST, false, Map.of())).build(), - - DataAttributeRef.builder().prefix("").lnType("lntype2").lnClass("LPHD").lnInst("0") - .doName(createDo("PhyNam", TPredefinedCDCEnum.DPS)) - .daName(createDa("aDa", TFCEnum.BL, false, Map.of())).build() - ); - } - - @Test - void getDAI_when_LDevice_not_found_should_throw_exception() { - // given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - - // when & then - DataAttributeRef dataAttributeRef = new DataAttributeRef(); - assertThrows(ScdException.class, - () -> SclService.getDAI(scd, "IED_NAME1", "UNKNOWNLD", dataAttributeRef, true)); - } - - @Test - void getDAI_should_filter_updatable_DA() { - // given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); - - // when - Set dais = SclService.getDAI(scd, "VirtualBCU", "LDMODEXPF", new DataAttributeRef(), true); - - // then - assertThat(dais).isNotNull(); - List resultSimpleDa = dais.stream() - .filter(dataAttributeRef -> dataAttributeRef.getBdaNames().isEmpty()) // test only simple DA - .map(DataAttributeRef::getLNRef).collect(Collectors.toList()); - assertThat(resultSimpleDa).containsExactlyInAnyOrder( - // ...AndTrueInDai : If ValImport is True in DAI, DA is updatable - "LLN0.DoA.valImportNotSetAndTrueInDai", - "LLN0.DoA.valImportTrueAndTrueInDai", - "LLN0.DoA.valImportFalseAndTrueInDai", - // valImportTrue : If ValImport is True in DA and DAI does not exist, DA is updatable - "LLN0.DoA.valImportTrue", - // valImportTrueAndNotSetInDai : If ValImport is True in DA and DAI exists but DAI ValImport is not set, DA is updatable - "LLN0.DoA.valImportTrueAndNotSetInDai", - // Only these FC are updatable - "LLN0.DoA.fcCF", - "LLN0.DoA.fcDC", - "LLN0.DoA.fcSG", - "LLN0.DoA.fcSP", - "LLN0.DoA.fcST", - "LLN0.DoA.fcSE" - ); - } - - @Test - void getDAI_should_filter_updatable_BDA() { - // given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); - - // when - Set dais = SclService.getDAI(scd, "VirtualBCU", "LDMODEXPF", new DataAttributeRef(), true); - - // then - assertThat(dais).isNotNull(); - List resultStructDa = dais.stream() - .filter(dataAttributeRef -> !dataAttributeRef.getBdaNames().isEmpty()) // test only struct DA - .map(DataAttributeRef::getLNRef).collect(Collectors.toList()); - assertThat(resultStructDa).containsExactlyInAnyOrder( - // ...AndTrueInDai : If ValImport is True in DAI, BDA is updatable - "LLN0.DoB.structValImportNotSet.bValImportFalseAndTrueInDai", - "LLN0.DoB.structValImportNotSet.bValImportNotSetAndTrueInDai", - "LLN0.DoB.structValImportNotSet.bValImportTrueAndTrueInDai", - "LLN0.DoB.structValImportTrue.bValImportFalseAndTrueInDai", - "LLN0.DoB.structValImportTrue.bValImportNotSetAndTrueInDai", - "LLN0.DoB.structValImportTrue.bValImportTrueAndTrueInDai", - "LLN0.DoB.structValImportFalse.bValImportFalseAndTrueInDai", - "LLN0.DoB.structValImportFalse.bValImportNotSetAndTrueInDai", - "LLN0.DoB.structValImportFalse.bValImportTrueAndTrueInDai", - // bValImportTrue : If ValImport is True in BDA and DAI does not exist, BDA is updatable - "LLN0.DoB.structValImportFalse.bValImportTrue", - "LLN0.DoB.structValImportTrue.bValImportTrue", - "LLN0.DoB.structValImportNotSet.bValImportTrue", - // bValImportTrueAndNotSetInDai : If ValImport is True in BDA and DAI exists but DAI ValImport is not set, BDA is updatable - "LLN0.DoB.structValImportTrue.bValImportTrueAndNotSetInDai", - "LLN0.DoB.structValImportNotSet.bValImportTrueAndNotSetInDai", - "LLN0.DoB.structValImportFalse.bValImportTrueAndNotSetInDai", - // Only these FC are updatable - "LLN0.DoB.structWithFcCF.bda1", - "LLN0.DoB.structWithFcDC.bda1", - "LLN0.DoB.structWithFcSG.bda1", - "LLN0.DoB.structWithFcSP.bda1", - "LLN0.DoB.structWithFcST.bda1", - "LLN0.DoB.structWithFcSE.bda1" - ); - } - - @Test - void getDAI_should_filter_updatable_DA_with_sGroup_Val() { - // given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); - - // when - Set dais = SclService.getDAI(scd, "VirtualBCU", "LDCAP", new DataAttributeRef(), true); - - // then - assertThat(dais).isNotNull(); - List resultSimpleDa = dais.stream() - .filter(dataAttributeRef -> dataAttributeRef.getBdaNames().isEmpty()) // test only simple DA - .map(DataAttributeRef::getLNRef).collect(Collectors.toList()); - assertThat(resultSimpleDa).containsExactlyInAnyOrder( - "LLN0.DoD.sGroupValImportNotSet", - "LLN0.DoD.sGroupValImportTrue" - ); - } - - @Test - void getDAI_should_filter_updatable_DA_with_sGroup_Val_without_ConfSg() { - // given - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); - - // when - Set dais = SclService.getDAI(scd, "VirtualBCU", "LDMOD", new DataAttributeRef(), true); - - // then - assertThat(dais) - .isNotNull() - .isEmpty(); - } - @Test void testInitScl_With_headerId_shouldNotThrowError() { UUID headerId = UUID.randomUUID(); - SCL scd = assertDoesNotThrow(() -> SclService.initScl(headerId, "hVersion", "hRevision")); + SCL scd = assertDoesNotThrow(() -> sclEditorService.initScl(headerId, "hVersion", "hRevision")); assertIsMarshallable(scd); } @@ -738,7 +171,7 @@ void initScl_should_create_Private_SCL_FILETYPE() { // Given UUID headerId = UUID.randomUUID(); // When Then - SCL scd = assertDoesNotThrow(() -> SclService.initScl(headerId, "hVersion", "hRevision")); + SCL scd = assertDoesNotThrow(() -> sclEditorService.initScl(headerId, "hVersion", "hRevision")); assertThat(scd.getPrivate()).isNotEmpty(); assertThat(scd.getPrivate().get(0).getType()).isEqualTo(COMPAS_SCL_FILE_TYPE.getPrivateType()); assertIsMarshallable(scd); @@ -747,11 +180,11 @@ void initScl_should_create_Private_SCL_FILETYPE() { @Test void updateHeader_should_update_header_tag() { //Given - SCL scd = assertDoesNotThrow(() -> SclService.initScl(UUID.randomUUID(), "hVersion", "hRevision")); + SCL scd = assertDoesNotThrow(() -> sclEditorService.initScl(UUID.randomUUID(), "hVersion", "hRevision")); UUID hId = UUID.fromString(scd.getHeader().getId()); HeaderDTO headerDTO = DTO.createHeaderDTO(hId); //When - SclService.updateHeader(scd, headerDTO); + sclEditorService.updateHeader(scd, headerDTO); //Then assertIsMarshallable(scd); } @@ -762,7 +195,7 @@ void testUpdateDAI() { dataAttributeRef.setLnType("unknownID"); SCL scd = SclTestMarshaller.getSCLFromFile("/ied-test-schema-conf/ied_unit_test.xml"); - assertThrows(ScdException.class, () -> SclService.updateDAI( + assertThrows(ScdException.class, () -> sclEditorService.updateDAI( scd, "IED", "LD", dataAttributeRef )); dataAttributeRef.setLnType("LNO1"); @@ -773,24 +206,16 @@ void testUpdateDAI() { TVal tVal = new TVal(); tVal.setValue("newValue"); dataAttributeRef.setDaiValues(List.of(tVal)); - assertDoesNotThrow(() -> SclService.updateDAI(scd, "IED_NAME", "LD_INS1", dataAttributeRef)); + assertDoesNotThrow(() -> sclEditorService.updateDAI(scd, "IED_NAME", "LD_INS1", dataAttributeRef)); assertIsMarshallable(scd); } - @Test - void testGetEnumTypeValues() { - SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - assertThrows(ScdException.class, () -> SclService.getEnumTypeValues(scd, "unknwnID")); - var enumList = assertDoesNotThrow(() -> SclService.getEnumTypeValues(scd, "RecCycModKind")); - assertFalse(enumList.isEmpty()); - } - @Test void testImportSTDElementsInSCD() { SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml"); SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); - assertDoesNotThrow(() -> SclService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)); + assertDoesNotThrow(() -> sclEditorService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)); assertThat(scd.getIED()).hasSize(1); assertThat(scd.getDataTypeTemplates()).hasNoNullFieldsOrProperties(); assertThat(scd.getCommunication().getSubNetwork()).hasSize(2); @@ -803,9 +228,8 @@ void testImportSTDElementsInSCD_with_Multiple_STD() { SCL std0 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); 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"); - SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); - assertDoesNotThrow(() -> SclService.importSTDElementsInSCD(scd, List.of(std0, std1, std2), DTO.SUB_NETWORK_TYPES)); + assertDoesNotThrow(() -> sclEditorService.importSTDElementsInSCD(scd, List.of(std0, std1, std2), DTO.SUB_NETWORK_TYPES)); assertThat(scd.getIED()).hasSize(3); assertThat(scd.getDataTypeTemplates()).hasNoNullFieldsOrProperties(); assertThat(scd.getCommunication().getSubNetwork()).hasSize(2); @@ -822,7 +246,7 @@ void testImportSTDElementsInSCD_Several_STD_Match_Compas_ICDHeader() { SCL std1 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); //When Then List stds = List.of(std, std1); - assertThrows(ScdException.class, () -> SclService.importSTDElementsInSCD(scd, stds, DTO.SUB_NETWORK_TYPES)); + assertThrows(ScdException.class, () -> sclEditorService.importSTDElementsInSCD(scd, stds, DTO.SUB_NETWORK_TYPES)); assertIsMarshallable(scd); } @@ -832,7 +256,7 @@ void test_importSTDElementsInSCD_should_not_throw_exception_when_SCD_file_contai 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 - assertDoesNotThrow(() -> SclService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)); + assertDoesNotThrow(() -> sclEditorService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)); assertIsMarshallable(scd); } @@ -841,9 +265,9 @@ void testImportSTDElementsInSCD_Compas_ICDHeader_Not_Match() { //Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml"); SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_with_same_ICDSystemVersionUUID.xml"); - SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); + List stdList = List.of(std); //When Then - assertThrows(ScdException.class, () -> SclService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)); + assertThrows(ScdException.class, () -> sclEditorService.importSTDElementsInSCD(scd, stdList, DTO.SUB_NETWORK_TYPES)); assertIsMarshallable(scd); } @@ -851,10 +275,9 @@ void testImportSTDElementsInSCD_Compas_ICDHeader_Not_Match() { void testImportSTDElementsInSCD_No_STD_Match() { //Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml"); - SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); + List stdList = List.of(); //When Then - Set stds = new HashSet<>(); - assertThrows(ScdException.class, () -> SclService.importSTDElementsInSCD(scd, List.of(), DTO.SUB_NETWORK_TYPES)); + assertThrows(ScdException.class, () -> sclEditorService.importSTDElementsInSCD(scd, stdList, DTO.SUB_NETWORK_TYPES)); assertIsMarshallable(scd); } @@ -863,7 +286,7 @@ void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_D // Given SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); // When - SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); + sclEditorService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); // Then SclRootAdapter scdRootAdapter = new SclRootAdapter(scl); List lDevices = scdRootAdapter.streamIEDAdapters().flatMap(IEDAdapter::streamLDeviceAdapters).toList(); @@ -883,7 +306,7 @@ void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_controlBlocks_and_D // Given SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); // When - SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); + sclEditorService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); // Then SclRootAdapter scdRootAdapter = new SclRootAdapter(scl); List lns = scdRootAdapter.streamIEDAdapters() @@ -903,7 +326,7 @@ void removeControlBlocksAndDatasetAndExtRefSrc_should_remove_srcXXX_attributes_o // Given SCL scl = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml"); // When - SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); + sclEditorService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scl); // Then SclRootAdapter scdRootAdapter = new SclRootAdapter(scl); List extRefs = scdRootAdapter @@ -930,7 +353,7 @@ void updateLDeviceStatus_shouldReturnReportWithError_MissingRequiredObject(Strin assertEquals("off", getLDeviceStatusValue(scl, "IedName1", "LDSUIED").get().getValue()); String before = MarshallerWrapper.marshall(scl); // When - List sclReportItems = SclService.updateLDeviceStatus(scl); + List sclReportItems = sclEditorService.updateLDeviceStatus(scl); // Then String after = MarshallerWrapper.marshall(scl); assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse(); @@ -951,7 +374,7 @@ void updateLDeviceStatus_shouldReturnReportWithError_WhenLDeviceStatusActiveOrUn assertThat(getLDeviceStatusValue(scl, "IedName3", "LDSUIED")).isEmpty(); String before = MarshallerWrapper.marshall(scl); // When - List sclReportItems = SclService.updateLDeviceStatus(scl); + List sclReportItems = sclEditorService.updateLDeviceStatus(scl); // Then String after = MarshallerWrapper.marshall(scl); assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse(); @@ -973,7 +396,7 @@ void updateLDeviceStatus_shouldReturnReportWithError_WhenAllLDeviceInactive_Test assertThat(getLDeviceStatusValue(scl, "IedName2", "LDSUIED").get().getValue()).isEqualTo("on"); assertThat(getLDeviceStatusValue(scl, "IedName3", "LDSUIED")).isEmpty(); // When - List sclReportItems = SclService.updateLDeviceStatus(scl); + List sclReportItems = sclEditorService.updateLDeviceStatus(scl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse(); assertThat(sclReportItems) @@ -1001,7 +424,7 @@ void updateLDeviceStatus_shouldReturnUpdatedFile() { assertThat(getLDeviceStatusValue(givenScl, "IedName3", "LDSUIED")).isEmpty(); // When - List sclReportItems = SclService.updateLDeviceStatus(givenScl); + List sclReportItems = sclEditorService.updateLDeviceStatus(givenScl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); assertThat(getLDeviceStatusValue(givenScl, "IedName1", "LDSUIED")).isPresent(); @@ -1032,7 +455,7 @@ void updateLDeviceStatus_shouldReturnUpdatedFile_when_DAI_Mod_DO_stVal_whatever_ .map(TVal::getValue) .hasValue("on"); // When - List sclReportItems = SclService.updateLDeviceStatus(givenScl); + List sclReportItems = sclEditorService.updateLDeviceStatus(givenScl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); @@ -1075,7 +498,7 @@ void updateDoInRef_shouldReturnUpdatedFile(String testName, String ldInst, Strin SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_issue_231_test_ok.xml"); // When - List sclReportItems = SclService.updateDoInRef(givenScl); + List sclReportItems = sclEditorService.updateDoInRef(givenScl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); @@ -1099,7 +522,7 @@ void updateDoInRef_should_not_update_DAI(String testName, String ldInst, String SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_issue_231_test_ok.xml"); // When - List sclReportItems = SclService.updateDoInRef(givenScl); + List sclReportItems = sclEditorService.updateDoInRef(givenScl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); @@ -1112,7 +535,7 @@ void updateDoInRef_shouldReturnReportWithError_when_ExtRef_not_coherent() { SCL givenScl = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_issue_231_test_ko.xml"); // When - List sclReportItems = SclService.updateDoInRef(givenScl); + List sclReportItems = sclEditorService.updateDoInRef(givenScl); // Then assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue(); @@ -1146,7 +569,7 @@ void analyzeDataGroups_should_success() { iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxSMV(2L); iedAdapter1.getCurrentElem().getAccessPoint().get(0).getServices().getClientServices().setMaxReports(1L); // When - List sclReportItems = SclService.analyzeDataGroups(scd); + List sclReportItems = sclEditorService.analyzeDataGroups(scd); //Then assertThat(sclReportItems).isEmpty(); @@ -1165,7 +588,7 @@ void analyzeDataGroups_should_return_errors_messages() { iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getGOOSE().setMax(2L); iedAdapter.getCurrentElem().getAccessPoint().get(0).getServices().getConfReportControl().setMax(0L); // When - List sclReportItems = SclService.analyzeDataGroups(scd); + List sclReportItems = sclEditorService.analyzeDataGroups(scd); //Then assertThat(sclReportItems).hasSize(11) .extracting(SclReportItem::message) @@ -1188,7 +611,7 @@ void manageMonitoringLns_should_update_and_create_lsvs_and_goose() { // Given SCL scd = SclTestMarshaller.getSCLFromFile("/monitoring_lns/scd_monitoring_lsvs_lgos.xml"); // When - List sclReportItems = SclService.manageMonitoringLns(scd); + List sclReportItems = sclEditorService.manageMonitoringLns(scd); //Then assertThat(sclReportItems).isEmpty(); LDeviceAdapter lDeviceAdapter = new SclRootAdapter(scd).getIEDAdapterByName("IED_NAME1").getLDeviceAdapterByLdInst(LD_SUIED); @@ -1210,7 +633,7 @@ void manageMonitoringLns_should_not_update_and_not_create_lsvs_and_goose_when_no LDeviceAdapter lDeviceAdapter21 = sclRootAdapter.getIEDAdapterByName("IED_NAME1").getLDeviceAdapterByLdInst("LD_INST21"); lDeviceAdapter21.getLN0Adapter().getCurrentElem().setInputs(null); // When - List sclReportItems = SclService.manageMonitoringLns(scd); + List sclReportItems = sclEditorService.manageMonitoringLns(scd); //Then assertThat(sclReportItems).isEmpty(); LDeviceAdapter lDeviceAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1").getLDeviceAdapterByLdInst(LD_SUIED); @@ -1232,7 +655,7 @@ void manageMonitoringLns_should_not_update_and_not_create_lsvs_and_goose_when_da getDAIAdapters(lDeviceAdapter, "LSVS", "SvCBRef", "setSrcRef") .forEach(daiAdapter -> daiAdapter.getCurrentElem().setValImport(false)); // When - List sclReportItems = SclService.manageMonitoringLns(scd); + List sclReportItems = sclEditorService.manageMonitoringLns(scd); //Then assertThat(sclReportItems) .isNotEmpty() diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclElementsProviderServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclElementsProviderServiceTest.java new file mode 100644 index 000000000..487d242f9 --- /dev/null +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SclElementsProviderServiceTest.java @@ -0,0 +1,343 @@ +// SPDX-FileCopyrightText: 2021 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons; + +import org.apache.commons.lang3.StringUtils; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +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.SclRootAdapter; +import org.lfenergy.compas.sct.commons.scl.ied.*; +import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; + +import java.util.*; +import java.util.stream.Collectors; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.assertThatThrownBy; +import static org.junit.jupiter.api.Assertions.*; +import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDa; +import static org.lfenergy.compas.sct.commons.testhelpers.DataTypeUtils.createDo; + +@ExtendWith(MockitoExtension.class) +class SclElementsProviderServiceTest { + + @InjectMocks + SclElementsProviderService sclElementsProviderService; + + @Test + void getExtRefBinders_shouldThrowScdException_whenExtRefNotExist() { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_binders_test.xml"); + + ExtRefSignalInfo signalInfo = createSignalInfo("Do11.sdo11", "da11.bda111.bda112.bda113", "INT_ADDR11"); + signalInfo.setPLN("ANCR"); + //When Then + assertThatThrownBy( + () -> sclElementsProviderService.getExtRefBinders(scd, "IED_NAME1", "UNKNOWN_LD", "LLN0", "", "", signalInfo)) + .isInstanceOf(ScdException.class); + } + + @Test + void getExtRefBinders_shouldReturnSortedListBindingInfo_whenExtRefAndDOExist() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_binders_test.xml"); + + ExtRefSignalInfo signalInfo = createSignalInfo( + "Do11.sdo11", "da11.bda111.bda112.bda113", "INT_ADDR11" + ); + signalInfo.setPLN("ANCR"); + + // When + List potentialBinders = sclElementsProviderService.getExtRefBinders(scd, "IED_NAME1", "LD_INST11", "LLN0", "", "", signalInfo); + + // Then + assertThat(potentialBinders).hasSize(4); + assertThat(potentialBinders) + .extracting(ExtRefBindingInfo::getIedName) + .containsExactly("IED_NAME1", "IED_NAME1", "IED_NAME2", "IED_NAME3"); + assertThat(potentialBinders) + .extracting(ExtRefBindingInfo::getLdInst) + .containsExactly("LD_INST11", "LD_INST12", "LD_INST22", "LD_INST31"); + assertThat(potentialBinders) + .extracting(ExtRefBindingInfo::getLnClass) + .containsExactly("ANCR", "ANCR", "ANCR", "ANCR"); + assertThat(potentialBinders) + .extracting(ExtRefBindingInfo::getLnInst) + .containsExactly("1", "1", "2", "3"); + } + + @Test + void getExtRefSourceInfo_shouldReturnEmptyList_whenExtRefMatchNoFCDA() { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); + String iedName = "IED_NAME2"; + String ldInst = "LD_INST21"; + String lnClass = TLLN0Enum.LLN_0.value(); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); + LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iedAdapter.findLDeviceAdapterByLdInst(ldInst).get()); + LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter(); + List extRefs = ln0Adapter.getExtRefs(null); + assertFalse(extRefs.isEmpty()); + + ExtRefInfo extRefInfo = new ExtRefInfo(extRefs.get(0)); + + extRefInfo.setHolderIEDName(iedName); + extRefInfo.setHolderLDInst(ldInst); + extRefInfo.setHolderLnClass(lnClass); + + //When + List controlBlocks = sclElementsProviderService.getExtRefSourceInfo(scd, extRefInfo); + + //Then + assertThat(controlBlocks).isEmpty(); + } + + @Test + void getExtRefSourceInfo_shouldReturnListOfControlBlocks_whenExtRefMatchFCDA() { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/issue_175_scd_get_cbs_test.xml"); + String iedName = "IED_NAME2"; + String ldInst = "LD_INST21"; + String lnClass = TLLN0Enum.LLN_0.value(); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); + LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iedAdapter.findLDeviceAdapterByLdInst(ldInst).get()); + LN0Adapter ln0Adapter = lDeviceAdapter.getLN0Adapter(); + List extRefs = ln0Adapter.getExtRefs(null); + assertFalse(extRefs.isEmpty()); + + ExtRefInfo extRefInfo = new ExtRefInfo(extRefs.get(0)); + + extRefInfo.setHolderIEDName(iedName); + extRefInfo.setHolderLDInst(ldInst); + extRefInfo.setHolderLnClass(lnClass); + + //When + List controlBlocks = sclElementsProviderService.getExtRefSourceInfo(scd, extRefInfo); + + //Then + assertThat(controlBlocks).hasSize(1); + assertThat(controlBlocks.get(0).getName()).isEqualTo("goose2"); + } + + private ExtRefSignalInfo createSignalInfo(String pDO, String pDA, String intAddr) { + + final String DESC = "DESC"; + final String P_LN = TLLN0Enum.LLN_0.value(); + final String P_SERV_T = "Report"; + + ExtRefSignalInfo signalInfo = new ExtRefSignalInfo(); + signalInfo.setDesc(DESC); + signalInfo.setPDA(pDA); + signalInfo.setPDO(pDO); + signalInfo.setPLN(P_LN); + signalInfo.setPServT(TServiceType.fromValue(P_SERV_T)); + signalInfo.setIntAddr(intAddr); + + return signalInfo; + } + + @Test + void getDAI_should_return_all_dai() { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); + + // when + Set allResults = sclElementsProviderService.getDAI(scd, "IED_NAME1", "LD_INST12", new DataAttributeRef(), true); + + // then + assertThat(allResults).hasSize(733); + + List resultsWithDa = allResults.stream().filter(rdt -> StringUtils.isNotBlank(rdt.getDaRef())).collect(Collectors.toList()); + assertThat(resultsWithDa).hasSize(733); + + List resultsWithNoBda = allResults.stream().filter(rdt -> rdt.getBdaNames().isEmpty()).collect(Collectors.toList()); + assertThat(resultsWithNoBda).hasSize(3); + List resultsWithBdaDepth1 = allResults.stream().filter(rdt -> rdt.getBdaNames().size() == 1).collect(Collectors.toList()); + assertThat(resultsWithBdaDepth1).isEmpty(); + List resultsWithBdaDepth2 = allResults.stream().filter(rdt -> rdt.getBdaNames().size() == 2).collect(Collectors.toList()); + assertThat(resultsWithBdaDepth2).hasSize(1); + List resultsWithBdaDepth3 = allResults.stream().filter(rdt -> rdt.getBdaNames().size() == 3).collect(Collectors.toList()); + assertThat(resultsWithBdaDepth3).hasSize(729); + + + List resultsWithDo = allResults.stream().filter(rdt -> StringUtils.isNotBlank(rdt.getDoRef())).collect(Collectors.toList()); + assertThat(resultsWithDo).hasSize(733); + + List resultsWithNoSdo = allResults.stream().filter(rdt -> rdt.getSdoNames().isEmpty()).collect(Collectors.toList()); + assertThat(resultsWithNoSdo).hasSize(3); + List resultsWithSdoDepth1 = allResults.stream().filter(rdt -> rdt.getSdoNames().size() == 1).collect(Collectors.toList()); + assertThat(resultsWithSdoDepth1).isEmpty(); + List resultsWithSdoDepth2 = allResults.stream().filter(rdt -> rdt.getSdoNames().size() == 2).collect(Collectors.toList()); + assertThat(resultsWithSdoDepth2).hasSize(730); + List resultsWithSdoDepth3 = allResults.stream().filter(rdt -> rdt.getSdoNames().size() == 3).collect(Collectors.toList()); + assertThat(resultsWithSdoDepth3).isEmpty(); + } + + @Test + void getDAI_should_aggregate_attribute_from_DAI() { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_aggregate_DAI.xml"); + + // when + Set dais = sclElementsProviderService.getDAI(scd, "VirtualBCU", "LDMODEXPF", new DataAttributeRef(), false); + + // then + DataAttributeRef lln0 = DataAttributeRef.builder().prefix("").lnType("lntype1").lnClass("LLN0").lnInst("").build(); + DataAttributeRef lln0DoA = lln0.toBuilder().doName(createDo("DoA", TPredefinedCDCEnum.DPL)).build(); + DataAttributeRef lln0DoB = lln0.toBuilder().doName(createDo("DoB", TPredefinedCDCEnum.ACD)).build(); + + assertThat(dais).containsExactlyInAnyOrder( + lln0DoA.toBuilder().daName(createDa("daNotInDai", TFCEnum.CF, false, Map.of(0L, "0"))).build(), + lln0DoA.toBuilder().daName(createDa("daNotInDai2", TFCEnum.CF, true, Map.of())).build(), + lln0DoA.toBuilder().daName(createDa("daiOverrideVal", TFCEnum.CF, false, Map.of(0L, "1"))).build(), + lln0DoA.toBuilder().daName(createDa("daiOverrideValImport", TFCEnum.CF, true, Map.of())).build(), + lln0DoA.toBuilder().daName(createDa("daiOverrideValImport2", TFCEnum.CF, false, Map.of())).build(), + + lln0DoB.toBuilder().daName(createDa("structDa.daNotInDai", TFCEnum.ST, false, Map.of(0L, "0"))).build(), + lln0DoB.toBuilder().daName(createDa("structDa.daNotInDai2", TFCEnum.ST, true, Map.of())).build(), + lln0DoB.toBuilder().daName(createDa("structDa.daiOverrideVal", TFCEnum.ST, false, Map.of(0L, "1"))).build(), + lln0DoB.toBuilder().daName(createDa("structDa.daiOverrideValImport", TFCEnum.ST, true, Map.of())).build(), + lln0DoB.toBuilder().daName(createDa("structDa.daiOverrideValImport2", TFCEnum.ST, false, Map.of())).build(), + + DataAttributeRef.builder().prefix("").lnType("lntype2").lnClass("LPHD").lnInst("0") + .doName(createDo("PhyNam", TPredefinedCDCEnum.DPS)) + .daName(createDa("aDa", TFCEnum.BL, false, Map.of())).build() + ); + } + + @Test + void getDAI_when_LDevice_not_found_should_throw_exception() { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); + + // when & then + DataAttributeRef dataAttributeRef = new DataAttributeRef(); + assertThrows(ScdException.class, + () -> sclElementsProviderService.getDAI(scd, "IED_NAME1", "UNKNOWNLD", dataAttributeRef, true)); + } + + @Test + void getDAI_should_filter_updatable_DA() { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); + + // when + Set dais = sclElementsProviderService.getDAI(scd, "VirtualBCU", "LDMODEXPF", new DataAttributeRef(), true); + + // then + assertThat(dais).isNotNull(); + List resultSimpleDa = dais.stream() + .filter(dataAttributeRef -> dataAttributeRef.getBdaNames().isEmpty()) // test only simple DA + .map(DataAttributeRef::getLNRef).collect(Collectors.toList()); + assertThat(resultSimpleDa).containsExactlyInAnyOrder( + // ...AndTrueInDai : If ValImport is True in DAI, DA is updatable + "LLN0.DoA.valImportNotSetAndTrueInDai", + "LLN0.DoA.valImportTrueAndTrueInDai", + "LLN0.DoA.valImportFalseAndTrueInDai", + // valImportTrue : If ValImport is True in DA and DAI does not exist, DA is updatable + "LLN0.DoA.valImportTrue", + // valImportTrueAndNotSetInDai : If ValImport is True in DA and DAI exists but DAI ValImport is not set, DA is updatable + "LLN0.DoA.valImportTrueAndNotSetInDai", + // Only these FC are updatable + "LLN0.DoA.fcCF", + "LLN0.DoA.fcDC", + "LLN0.DoA.fcSG", + "LLN0.DoA.fcSP", + "LLN0.DoA.fcST", + "LLN0.DoA.fcSE" + ); + } + + @Test + void getDAI_should_filter_updatable_BDA() { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); + + // when + Set dais = sclElementsProviderService.getDAI(scd, "VirtualBCU", "LDMODEXPF", new DataAttributeRef(), true); + + // then + assertThat(dais).isNotNull(); + List resultStructDa = dais.stream() + .filter(dataAttributeRef -> !dataAttributeRef.getBdaNames().isEmpty()) // test only struct DA + .map(DataAttributeRef::getLNRef).collect(Collectors.toList()); + assertThat(resultStructDa).containsExactlyInAnyOrder( + // ...AndTrueInDai : If ValImport is True in DAI, BDA is updatable + "LLN0.DoB.structValImportNotSet.bValImportFalseAndTrueInDai", + "LLN0.DoB.structValImportNotSet.bValImportNotSetAndTrueInDai", + "LLN0.DoB.structValImportNotSet.bValImportTrueAndTrueInDai", + "LLN0.DoB.structValImportTrue.bValImportFalseAndTrueInDai", + "LLN0.DoB.structValImportTrue.bValImportNotSetAndTrueInDai", + "LLN0.DoB.structValImportTrue.bValImportTrueAndTrueInDai", + "LLN0.DoB.structValImportFalse.bValImportFalseAndTrueInDai", + "LLN0.DoB.structValImportFalse.bValImportNotSetAndTrueInDai", + "LLN0.DoB.structValImportFalse.bValImportTrueAndTrueInDai", + // bValImportTrue : If ValImport is True in BDA and DAI does not exist, BDA is updatable + "LLN0.DoB.structValImportFalse.bValImportTrue", + "LLN0.DoB.structValImportTrue.bValImportTrue", + "LLN0.DoB.structValImportNotSet.bValImportTrue", + // bValImportTrueAndNotSetInDai : If ValImport is True in BDA and DAI exists but DAI ValImport is not set, BDA is updatable + "LLN0.DoB.structValImportTrue.bValImportTrueAndNotSetInDai", + "LLN0.DoB.structValImportNotSet.bValImportTrueAndNotSetInDai", + "LLN0.DoB.structValImportFalse.bValImportTrueAndNotSetInDai", + // Only these FC are updatable + "LLN0.DoB.structWithFcCF.bda1", + "LLN0.DoB.structWithFcDC.bda1", + "LLN0.DoB.structWithFcSG.bda1", + "LLN0.DoB.structWithFcSP.bda1", + "LLN0.DoB.structWithFcST.bda1", + "LLN0.DoB.structWithFcSE.bda1" + ); + } + + @Test + void getDAI_should_filter_updatable_DA_with_sGroup_Val() { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); + + // when + Set dais = sclElementsProviderService.getDAI(scd, "VirtualBCU", "LDCAP", new DataAttributeRef(), true); + + // then + assertThat(dais).isNotNull(); + List resultSimpleDa = dais.stream() + .filter(dataAttributeRef -> dataAttributeRef.getBdaNames().isEmpty()) // test only simple DA + .map(DataAttributeRef::getLNRef).collect(Collectors.toList()); + assertThat(resultSimpleDa).containsExactlyInAnyOrder( + "LLN0.DoD.sGroupValImportNotSet", + "LLN0.DoD.sGroupValImportTrue" + ); + } + + @Test + void getDAI_should_filter_updatable_DA_with_sGroup_Val_without_ConfSg() { + // given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_test_updatable_DAI.xml"); + + // when + Set dais = sclElementsProviderService.getDAI(scd, "VirtualBCU", "LDMOD", new DataAttributeRef(), true); + + // then + assertThat(dais) + .isNotNull() + .isEmpty(); + } + + @Test + void testGetEnumTypeValues() { + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); + assertThrows(ScdException.class, () -> sclElementsProviderService.getEnumTypeValues(scd, "unknwnID")); + var enumList = assertDoesNotThrow(() -> sclElementsProviderService.getEnumTypeValues(scd, "RecCycModKind")); + assertFalse(enumList.isEmpty()); + } + +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SubstationServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SubstationServiceTest.java similarity index 79% rename from sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SubstationServiceTest.java rename to sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SubstationServiceTest.java index 1c6d9bbee..9a3bfa060 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SubstationServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/SubstationServiceTest.java @@ -2,29 +2,36 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.lfenergy.compas.sct.commons.scl; +package org.lfenergy.compas.sct.commons; import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TSubstation; import org.lfenergy.compas.scl2007b4.model.TVoltageLevel; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; +import org.mockito.InjectMocks; +import org.mockito.junit.jupiter.MockitoExtension; import static org.assertj.core.api.AssertionsForClassTypes.assertThat; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Assertions.assertThrows; import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable; +@ExtendWith(MockitoExtension.class) class SubstationServiceTest { + @InjectMocks + SubstationService substationService; + @Test void addSubstation_when_SCD_has_no_substation_should_succeed() { // Given SCL scd = SclTestMarshaller.getSCLFromFile("/scl-root-test-schema-conf/add_ied_test.xml"); SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); - assertThat(scd.getSubstation().size()).isZero(); + assertThat(scd.getSubstation()).asList().isEmpty(); // When - SubstationService.addSubstation(scd, ssd); + substationService.addSubstation(scd, ssd); // Then assertIsMarshallable(scd); assertThat(scd.getSubstation().size()).isNotZero(); @@ -40,11 +47,11 @@ void addSubstation_when_SCD_has_a_substation_should_succeed() { TSubstation ssdSubstation = ssd.getSubstation().get(0); assertThat(scdSubstation.getVoltageLevel().stream().map(TVoltageLevel::getBay).count()).isEqualTo(1); // When - SubstationService.addSubstation(scd, ssd); + substationService.addSubstation(scd, ssd); // Then assertIsMarshallable(scd); assertThat(scdSubstation.getName()).isEqualTo(ssdSubstation.getName()); - assertThat(scd.getSubstation().size()).isEqualTo(ssd.getSubstation().size()); + assertThat(scd.getSubstation()).asList().hasSameSizeAs(ssd.getSubstation()); assertThat(scdSubstation.getVoltageLevel().stream().map(TVoltageLevel::getBay).count()).isEqualTo(2); } @@ -55,7 +62,7 @@ void addSubstation_when_SSD_with_multiple_Substations_should_throw_exception() { SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd_with_2_substations.xml"); // When & Then - assertThrows(ScdException.class, () -> SubstationService.addSubstation(scd, ssd)); + assertThrows(ScdException.class, () -> substationService.addSubstation(scd, ssd)); } @Test @@ -65,7 +72,7 @@ void addSubstation_when_SSD_with_no_substation_should_throw_exception() { SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd_without_substations.xml"); // When & Then - assertThrows(ScdException.class, () -> SubstationService.addSubstation(scd, ssd)); + assertThrows(ScdException.class, () -> substationService.addSubstation(scd, ssd)); } @Test @@ -74,7 +81,7 @@ void addSubstation_when_substations_names_differ_should_throw_exception() { SCL scd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/scd_with_substation_name_different.xml"); SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml"); // When & Then - assertThrows(ScdException.class, () -> SubstationService.addSubstation(scd, ssd)); + assertThrows(ScdException.class, () -> substationService.addSubstation(scd, ssd)); } } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettingsTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettingsTest.java index abd09200f..89450f8d6 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettingsTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ControlBlockNetworkSettingsTest.java @@ -14,7 +14,7 @@ import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.scl2007b4.model.TDurationInMilliSec; import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.SettingsOrError; -import org.lfenergy.compas.sct.commons.scl.PrivateService; +import org.lfenergy.compas.sct.commons.util.PrivateUtils; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.scl.ied.ControlBlockAdapter; import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter; @@ -193,7 +193,7 @@ void getNetworkSettings_should_return_null_when_missing_ied_private(PrivateEnum //Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml"); SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); - PrivateService.removePrivates(findIed(sclRootAdapter.getCurrentElem(), "IED_NAME2").getCurrentElem(), missingPrivate); + PrivateUtils.removePrivates(findIed(sclRootAdapter.getCurrentElem(), "IED_NAME2").getCurrentElem(), missingPrivate); ControlBlockAdapter controlBlockAdapter = findControlBlock(sclRootAdapter.getCurrentElem(), "IED_NAME2", "LD_INST21", "CB_LD_INST21_GSI", ControlBlockEnum.GSE); //When diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java index 29de7b98b..4d24f57ef 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/IEDAdapterTest.java @@ -14,7 +14,7 @@ import org.lfenergy.compas.sct.commons.dto.SclReportItem; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.ObjectReference; -import org.lfenergy.compas.sct.commons.scl.PrivateService; +import org.lfenergy.compas.sct.commons.util.PrivateUtils; import org.lfenergy.compas.sct.commons.scl.SclRootAdapter; import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; import org.lfenergy.compas.sct.commons.util.MonitoringLnClassEnum; @@ -291,7 +291,7 @@ void getCompasICDHeader_should_return_compas_icd_header(){ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME"); TCompasICDHeader tCompasICDHeader = new TCompasICDHeader(); tCompasICDHeader.setHeaderId("HEADER_ID"); - iedAdapter.getCurrentElem().getPrivate().add(PrivateService.createPrivate(tCompasICDHeader)); + iedAdapter.getCurrentElem().getPrivate().add(PrivateUtils.createPrivate(tCompasICDHeader)); // When Optional compasICDHeader = iedAdapter.getCompasICDHeader(); @@ -307,7 +307,7 @@ void getCompasSystemVersion_should_return_compas_icd_header(){ IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME"); TCompasSystemVersion tCompasSystemVersion = new TCompasSystemVersion(); tCompasSystemVersion.setMainSystemVersion("01.00"); - iedAdapter.getCurrentElem().getPrivate().add(PrivateService.createPrivate(tCompasSystemVersion)); + iedAdapter.getCurrentElem().getPrivate().add(PrivateUtils.createPrivate(tCompasSystemVersion)); // When Optional compasSystemVersion = iedAdapter.getCompasSystemVersion(); diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java index 366c2d64e..000d694d2 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LN0AdapterTest.java @@ -274,8 +274,7 @@ void testGetControlBlocks() { void testGetControlSetByBindingInfo() { LN0 ln0 = new LN0(); - LN0Adapter ln0Adapter = mock(LN0Adapter.class); - ln0Adapter = Mockito.spy(ln0Adapter); + LN0Adapter ln0Adapter = Mockito.spy(new LN0Adapter(null, ln0)); when(ln0Adapter.getCurrentElem()).thenReturn(ln0); diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/sstation/LNodeAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/sstation/LNodeAdapterTest.java index 7429cfdca..76f833157 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/sstation/LNodeAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/sstation/LNodeAdapterTest.java @@ -8,7 +8,7 @@ import org.junit.platform.commons.support.HierarchyTraversalMode; import org.junit.platform.commons.support.ReflectionSupport; import org.lfenergy.compas.scl2007b4.model.*; -import org.lfenergy.compas.sct.commons.scl.PrivateService; +import org.lfenergy.compas.sct.commons.util.PrivateUtils; import javax.xml.bind.JAXBElement; import javax.xml.namespace.QName; @@ -60,7 +60,7 @@ void addPrivate_should_succeed() { // Given TLNode tlNode = new TLNode(); LNodeAdapter lNodeAdapter = new LNodeAdapter(null, tlNode); - TPrivate tPrivate = PrivateService.createPrivate(TCompasSclFileType.SCD); + TPrivate tPrivate = PrivateUtils.createPrivate(TCompasSclFileType.SCD); // When lNodeAdapter.addPrivate(tPrivate); // Then @@ -87,7 +87,7 @@ void deepCopy_should_succeed() { tText.getContent().add("Text1"); tText.getOtherAttributes().put(QName.valueOf("Text1_attribute1"), "Text1_value1"); tlNode.setText(tText); - tlNode.getPrivate().add(PrivateService.createPrivate(TCompasSclFileType.SCD)); + tlNode.getPrivate().add(PrivateUtils.createPrivate(TCompasSclFileType.SCD)); tlNode.getOtherAttributes().put(QName.valueOf("tlNode_attribute1"), "tlNode_value1"); LNodeAdapter lNodeAdapter = new LNodeAdapter(null, tlNode); // When diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/PrivateServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/PrivateUtilsTest.java similarity index 75% rename from sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/PrivateServiceTest.java rename to sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/PrivateUtilsTest.java index cbee0d90c..6e6148e7c 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/PrivateServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/PrivateUtilsTest.java @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: Apache-2.0 -package org.lfenergy.compas.sct.commons.scl; +package org.lfenergy.compas.sct.commons.util; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -10,10 +10,10 @@ import org.junit.jupiter.params.provider.MethodSource; import org.junit.platform.commons.support.ReflectionSupport; import org.lfenergy.compas.scl2007b4.model.*; +import org.lfenergy.compas.sct.commons.dto.PrivateLinkedToStds; import org.lfenergy.compas.sct.commons.exception.ScdException; import org.lfenergy.compas.sct.commons.scl.icd.IcdHeader; import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; -import org.lfenergy.compas.sct.commons.util.PrivateEnum; import javax.xml.bind.JAXBElement; import java.lang.reflect.Constructor; @@ -26,7 +26,7 @@ import static org.assertj.core.api.Assertions.*; import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; -class PrivateServiceTest { +class PrivateUtilsTest { private TPrivate privateSCD; private TPrivate privateICD; @@ -46,14 +46,14 @@ void setUp() { @Test void class_should_not_be_instantiable() { // Given - Constructor[] constructors = PrivateService.class.getDeclaredConstructors(); + Constructor[] constructors = PrivateUtils.class.getDeclaredConstructors(); assertThat(constructors).hasSize(1); Constructor constructor = constructors[0]; constructor.setAccessible(true); // When & Then assertThatThrownBy(constructor::newInstance) - .isInstanceOf(InvocationTargetException.class) - .getCause().isInstanceOf(UnsupportedOperationException.class); + .isInstanceOf(InvocationTargetException.class) + .getCause().isInstanceOf(UnsupportedOperationException.class); } @Test @@ -64,11 +64,11 @@ void extractCompasPrivates_should_return_privates_value() { baseElement.getPrivate().add(privateICD); // Given : setUp // When - List result = PrivateService.extractCompasPrivates(baseElement, TCompasSclFileType.class).toList(); + List result = PrivateUtils.extractCompasPrivates(baseElement, TCompasSclFileType.class).toList(); //Then assertThat(result) - .hasSize(2) - .containsExactly(TCompasSclFileType.SCD, TCompasSclFileType.ICD); + .hasSize(2) + .containsExactly(TCompasSclFileType.SCD, TCompasSclFileType.ICD); } @Test @@ -77,7 +77,7 @@ void extractCompasPrivates_when_no_privates_match_class_should_return_empty_list TBaseElement baseElement = new SCL(); baseElement.getPrivate().add(privateSCD); // When - List result = PrivateService.extractCompasPrivates(baseElement, TCompasICDHeader.class).toList(); + List result = PrivateUtils.extractCompasPrivates(baseElement, TCompasICDHeader.class).toList(); //Then assertThat(result).isEmpty(); } @@ -88,7 +88,7 @@ void extractCompasPrivates_when_class_is_not_compas_class_should_throw_exception TBaseElement baseElement = new SCL(); baseElement.getPrivate().add(privateSCD); // When - Stream compasPrivates = PrivateService.extractCompasPrivates(baseElement, Object.class); + Stream compasPrivates = PrivateUtils.extractCompasPrivates(baseElement, Object.class); // Then assertThatCode(compasPrivates::toList) .isInstanceOf(NoSuchElementException.class) @@ -103,7 +103,7 @@ void extractCompasPrivates_when_content_not_match_private_type_should_throw_exce baseElement.getPrivate().add(privateSCD); Class compasClass = PrivateEnum.COMPAS_BAY.getCompasClass(); - Stream stream = PrivateService.extractCompasPrivates(baseElement, compasClass); + Stream stream = PrivateUtils.extractCompasPrivates(baseElement, compasClass); // When & Then assertThatCode(stream::toList) .isInstanceOf(ClassCastException.class) @@ -117,11 +117,11 @@ void extractCompasPrivates_on_base_element_should_return_privates_value() { baseElement.getPrivate().add(privateSCD); baseElement.getPrivate().add(privateICD); // When - List result = PrivateService.extractCompasPrivates(baseElement, TCompasSclFileType.class).toList(); + List result = PrivateUtils.extractCompasPrivates(baseElement, TCompasSclFileType.class).toList(); // Then assertThat(result) - .hasSize(2) - .containsExactly(TCompasSclFileType.SCD, TCompasSclFileType.ICD); + .hasSize(2) + .containsExactly(TCompasSclFileType.SCD, TCompasSclFileType.ICD); } @Test @@ -129,7 +129,7 @@ void extractCompasPrivates_on_base_element_should_not_set_private() { // Given TBaseElement baseElement = new SCL(); // When - PrivateService.extractCompasPrivates(baseElement, TCompasSclFileType.class); + PrivateUtils.extractCompasPrivates(baseElement, TCompasSclFileType.class); // Then assertThat(baseElement.isSetPrivate()).isFalse(); } @@ -140,10 +140,10 @@ void extractCompasPrivate_on_base_element_should_return_private_value() { TBaseElement baseElement = new SCL(); baseElement.getPrivate().add(privateSCD); // When - Optional result = PrivateService.extractCompasPrivate(baseElement, TCompasSclFileType.class); + Optional result = PrivateUtils.extractCompasPrivate(baseElement, TCompasSclFileType.class); //Then assertThat(result).isPresent() - .hasValue(TCompasSclFileType.SCD); + .hasValue(TCompasSclFileType.SCD); } @Test @@ -151,7 +151,7 @@ void extractCompasPrivate_on_base_element_should_return_empty() { // Given TBaseElement baseElement = new SCL(); // When - Optional result = PrivateService.extractCompasPrivate(baseElement, TCompasBay.class); + Optional result = PrivateUtils.extractCompasPrivate(baseElement, TCompasBay.class); //Then assertThat(result).isNotPresent(); } @@ -163,7 +163,7 @@ void extractCompasPrivate_on_base_element_should_throw_exception() { baseElement.getPrivate().add(privateSCD); baseElement.getPrivate().add(privateICD); // When & Then - assertThatCode(() -> PrivateService.extractCompasPrivate(baseElement, TCompasSclFileType.class)) + assertThatCode(() -> PrivateUtils.extractCompasPrivate(baseElement, TCompasSclFileType.class)) .isInstanceOf(ScdException.class) .hasMessage("Expecting maximum 1 element of type class org.lfenergy.compas.scl2007b4.model.TCompasSclFileType in private COMPAS-SclFileType, but got more"); } @@ -176,7 +176,7 @@ void extractCompasICDHeader_should_return_private_value() { TCompasICDHeader tCompasICDHeader = objectFactory.createTCompasICDHeader(); privateSCD.getContent().add(objectFactory.createICDHeader(tCompasICDHeader)); // When - Optional optionalResult = PrivateService.extractCompasICDHeader(privateSCD); + Optional optionalResult = PrivateUtils.extractCompasICDHeader(privateSCD); //Then assertThat(optionalResult).isPresent().get().matches(result -> result == tCompasICDHeader); } @@ -187,7 +187,7 @@ void createPrivate_should_return_private_new_private(Object compasElement) throw // Given PrivateEnum privateEnum = PrivateEnum.fromClass(compasElement.getClass()); assertThat(privateEnum).isNotNull(); - Optional optionalCreatePrivateMethod = ReflectionSupport.findMethod(PrivateService.class, "createPrivate", compasElement.getClass()); + Optional optionalCreatePrivateMethod = ReflectionSupport.findMethod(PrivateUtils.class, "createPrivate", compasElement.getClass()); assertThat(optionalCreatePrivateMethod).isPresent(); Method createPrivateMethod = optionalCreatePrivateMethod.get(); // When @@ -196,19 +196,19 @@ void createPrivate_should_return_private_new_private(Object compasElement) throw assertThat(result).isInstanceOf(TPrivate.class); TPrivate resultPrivate = (TPrivate) result; assertThat(resultPrivate).isNotNull() - .hasFieldOrPropertyWithValue("type", privateEnum.getPrivateType()); + .hasFieldOrPropertyWithValue("type", privateEnum.getPrivateType()); assertThat(resultPrivate.getContent()).hasSize(1).first().satisfies(content -> assertThat(content).isInstanceOf(JAXBElement.class)); JAXBElement content = (JAXBElement) resultPrivate.getContent().get(0); assertThat(content.isNil()).isFalse(); assertThat(content.getValue()).isNotNull().isInstanceOf(compasElement.getClass()) - .isEqualTo(compasElement); + .isEqualTo(compasElement); } public static Stream createPrivateTestSources() { return Stream.of(new TCompasBay(), - new TCompasICDHeader(), - TCompasSclFileType.SCD, - new TCompasSystemVersion()); + new TCompasICDHeader(), + TCompasSclFileType.SCD, + new TCompasSystemVersion()); } @Test @@ -217,7 +217,7 @@ void removePrivates_should_remove_privates() { TBaseElement baseElement = new SCL(); baseElement.getPrivate().add(privateSCD); // When - PrivateService.removePrivates(baseElement, PrivateEnum.COMPAS_SCL_FILE_TYPE); + PrivateUtils.removePrivates(baseElement, PrivateEnum.COMPAS_SCL_FILE_TYPE); // Then assertThat(baseElement.isSetPrivate()).isFalse(); } @@ -228,7 +228,7 @@ void removePrivates_should_do_nothing_when_no_private_match_type() { TBaseElement baseElement = new SCL(); baseElement.getPrivate().add(privateSCD); // When - PrivateService.removePrivates(baseElement, PrivateEnum.COMPAS_ICDHEADER); + PrivateUtils.removePrivates(baseElement, PrivateEnum.COMPAS_ICDHEADER); // Then assertThat(baseElement.getPrivate()).hasSize(1); } @@ -239,9 +239,9 @@ void removePrivates_should_remove_privates_of_given_type() { TBaseElement baseElement = new SCL(); baseElement.getPrivate().add(privateSCD); TCompasICDHeader tCompasICDHeader = objectFactory.createTCompasICDHeader(); - baseElement.getPrivate().add(PrivateService.createPrivate(tCompasICDHeader)); + baseElement.getPrivate().add(PrivateUtils.createPrivate(tCompasICDHeader)); // When - PrivateService.removePrivates(baseElement, PrivateEnum.COMPAS_ICDHEADER); + PrivateUtils.removePrivates(baseElement, PrivateEnum.COMPAS_ICDHEADER); // Then assertThat(baseElement.getPrivate()).hasSize(1); TPrivate tPrivate = baseElement.getPrivate().get(0); @@ -258,7 +258,7 @@ void removePrivates_should_not_set_private() { TBaseElement baseElement = new SCL(); baseElement.unsetPrivate(); // When - PrivateService.removePrivates(baseElement, PrivateEnum.COMPAS_ICDHEADER); + PrivateUtils.removePrivates(baseElement, PrivateEnum.COMPAS_ICDHEADER); // Then assertThat(baseElement.isSetPrivate()).isFalse(); } @@ -269,12 +269,12 @@ void createMapICDSystemVersionUuidAndSTDFile_Should_return_empty_map_when_no_ICD SCL scl1 = new SCL(); TIED tied1 = new TIED(); TCompasICDHeader compasICDHeader1 = new TCompasICDHeader(); - TPrivate tPrivate1 = PrivateService.createPrivate(compasICDHeader1); + TPrivate tPrivate1 = PrivateUtils.createPrivate(compasICDHeader1); tied1.getPrivate().add(tPrivate1); scl1.getIED().add(tied1); //When - Map stringSCLMap = PrivateService.createMapICDSystemVersionUuidAndSTDFile(List.of(scl1)); + Map stringSCLMap = PrivateUtils.createMapICDSystemVersionUuidAndSTDFile(List.of(scl1)); //Then assertThat(stringSCLMap.keySet()).isEmpty(); @@ -296,9 +296,9 @@ void createMapICDSystemVersionUuidAndSTDFile_Should_return_map_with_two_lines() compasICDHeader2.setICDSystemVersionUUID("UUID-2"); TCompasICDHeader compasICDHeader3 = new TCompasICDHeader(); compasICDHeader3.setICDSystemVersionUUID("UUID-2"); - TPrivate tPrivate1 = PrivateService.createPrivate(compasICDHeader1); - TPrivate tPrivate2 = PrivateService.createPrivate(compasICDHeader2); - TPrivate tPrivate3 = PrivateService.createPrivate(compasICDHeader3); + TPrivate tPrivate1 = PrivateUtils.createPrivate(compasICDHeader1); + TPrivate tPrivate2 = PrivateUtils.createPrivate(compasICDHeader2); + TPrivate tPrivate3 = PrivateUtils.createPrivate(compasICDHeader3); tied1.getPrivate().add(tPrivate1); tied2.getPrivate().add(tPrivate2); tied3.getPrivate().add(tPrivate3); @@ -307,7 +307,7 @@ void createMapICDSystemVersionUuidAndSTDFile_Should_return_map_with_two_lines() scl3.getIED().add(tied3); //When - Map stringSCLMap = PrivateService.createMapICDSystemVersionUuidAndSTDFile(List.of(scl1,scl2,scl3)); + Map stringSCLMap = PrivateUtils.createMapICDSystemVersionUuidAndSTDFile(List.of(scl1,scl2,scl3)); //Then assertThat(stringSCLMap.keySet()).hasSize(2).containsExactly("UUID-1", "UUID-2"); @@ -324,18 +324,18 @@ void checkSTDCorrespondanceWithLNodeCompasICDHeadershoul_throw_scdEception(){ compasICDHeader2.setHeaderId("ID-2"); compasICDHeader2.setHeaderVersion("VER-2"); compasICDHeader2.setHeaderRevision("REV-2"); - TPrivate tPrivate1 = PrivateService.createPrivate(compasICDHeader1); - TPrivate tPrivate2 = PrivateService.createPrivate(compasICDHeader2); + TPrivate tPrivate1 = PrivateUtils.createPrivate(compasICDHeader1); + TPrivate tPrivate2 = PrivateUtils.createPrivate(compasICDHeader2); - PrivateService.PrivateLinkedToSTDs privateLinkedToSTDs1 = new PrivateService.PrivateLinkedToSTDs(tPrivate1,Collections.singletonList(new SCL())); - PrivateService.PrivateLinkedToSTDs privateLinkedToSTDs2 = new PrivateService.PrivateLinkedToSTDs(tPrivate2, Arrays.asList(new SCL(), new SCL())); + PrivateLinkedToStds privateLinkedToSTDs1 = new PrivateLinkedToStds(tPrivate1,Collections.singletonList(new SCL())); + PrivateLinkedToStds privateLinkedToSTDs2 = new PrivateLinkedToStds(tPrivate2, Arrays.asList(new SCL(), new SCL())); - Map stringSCLMap = new HashMap<>(); + Map stringSCLMap = new HashMap<>(); stringSCLMap.put("UUID-1", privateLinkedToSTDs1); stringSCLMap.put("UUID-2", privateLinkedToSTDs2); //When Then - assertThatThrownBy(() -> PrivateService.checkSTDCorrespondanceWithLNodeCompasICDHeader(stringSCLMap)) + assertThatThrownBy(() -> PrivateUtils.checkSTDCorrespondanceWithLNodeCompasICDHeader(stringSCLMap)) .isInstanceOf(ScdException.class) .hasMessage("There are several STD files corresponding to headerId = ID-2 headerVersion = VER-2 headerRevision = REV-2 and ICDSystemVersionUUID = UUID-2"); @@ -348,18 +348,18 @@ void checkSTDCorrespondanceWithLNodeCompasICDHeader_should_pass(){ compasICDHeader1.setICDSystemVersionUUID("UUID-1"); TCompasICDHeader compasICDHeader2 = new TCompasICDHeader(); compasICDHeader2.setICDSystemVersionUUID("UUID-2"); - TPrivate tPrivate1 = PrivateService.createPrivate(compasICDHeader1); - TPrivate tPrivate2 = PrivateService.createPrivate(compasICDHeader2); + TPrivate tPrivate1 = PrivateUtils.createPrivate(compasICDHeader1); + TPrivate tPrivate2 = PrivateUtils.createPrivate(compasICDHeader2); - PrivateService.PrivateLinkedToSTDs privateLinkedToSTDs1 = new PrivateService.PrivateLinkedToSTDs(tPrivate1,Collections.singletonList(new SCL())); - PrivateService.PrivateLinkedToSTDs privateLinkedToSTDs2 = new PrivateService.PrivateLinkedToSTDs(tPrivate2, Collections.singletonList(new SCL())); + PrivateLinkedToStds privateLinkedToSTDs1 = new PrivateLinkedToStds(tPrivate1,Collections.singletonList(new SCL())); + PrivateLinkedToStds privateLinkedToSTDs2 = new PrivateLinkedToStds(tPrivate2, Collections.singletonList(new SCL())); - Map stringSCLMap = new HashMap<>(); + Map stringSCLMap = new HashMap<>(); stringSCLMap.put("UUID-1", privateLinkedToSTDs1); stringSCLMap.put("UUID-2", privateLinkedToSTDs2); //When Then - assertDoesNotThrow(() -> PrivateService.checkSTDCorrespondanceWithLNodeCompasICDHeader(stringSCLMap)); + assertDoesNotThrow(() -> PrivateUtils.checkSTDCorrespondanceWithLNodeCompasICDHeader(stringSCLMap)); } @@ -370,10 +370,10 @@ void stdCheckFormatExceptionMessage_should_return_formatted_message_with_Private compasICDHeader.setHeaderId("ID-1"); compasICDHeader.setHeaderVersion("VER-1"); compasICDHeader.setICDSystemVersionUUID("UUID-1"); - TPrivate tPrivate = PrivateService.createPrivate(compasICDHeader); + TPrivate tPrivate = PrivateUtils.createPrivate(compasICDHeader); //When - String message = PrivateService.stdCheckFormatExceptionMessage(tPrivate); + String message = PrivateUtils.stdCheckFormatExceptionMessage(tPrivate); //Then assertThat(message).isEqualTo("headerId = ID-1 headerVersion = VER-1 headerRevision = null and ICDSystemVersionUUID = UUID-1"); @@ -393,9 +393,9 @@ void createMapIEDNameAndPrivate_should_return_map_of_three_items() { compasICDHeader2.setIEDName("IED-2"); TCompasICDHeader compasICDHeader3 = new TCompasICDHeader(); compasICDHeader3.setIEDName("IED-3"); - TPrivate tPrivate1 = PrivateService.createPrivate(compasICDHeader1); - TPrivate tPrivate2 = PrivateService.createPrivate(compasICDHeader2); - TPrivate tPrivate3 = PrivateService.createPrivate(compasICDHeader3); + TPrivate tPrivate1 = PrivateUtils.createPrivate(compasICDHeader1); + TPrivate tPrivate2 = PrivateUtils.createPrivate(compasICDHeader2); + TPrivate tPrivate3 = PrivateUtils.createPrivate(compasICDHeader3); tlNode1.getPrivate().add(tPrivate1); tlNode2.getPrivate().add(tPrivate2); tlNode3.getPrivate().add(tPrivate3); @@ -410,7 +410,7 @@ void createMapIEDNameAndPrivate_should_return_map_of_three_items() { scl.getSubstation().add(tSubstation); //When - Stream tPrivateStream = PrivateService.streamIcdHeaders(scl); + Stream tPrivateStream = PrivateUtils.streamIcdHeaders(scl); //Then assertThat(tPrivateStream.toList()) @@ -426,7 +426,7 @@ void createMapIEDNameAndPrivate_should_return_empty_map_when_no_compasicdheader_ TLNode tlNode1 = new TLNode(); TCompasBay compasBay = new TCompasBay(); compasBay.setUUID("UUID"); - TPrivate tPrivate1 = PrivateService.createPrivate(compasBay); + TPrivate tPrivate1 = PrivateUtils.createPrivate(compasBay); tlNode1.getPrivate().add(tPrivate1); TFunction tFunction = new TFunction(); tFunction.getLNode().add(tlNode1); @@ -439,7 +439,7 @@ void createMapIEDNameAndPrivate_should_return_empty_map_when_no_compasicdheader_ scl.getSubstation().add(tSubstation); //When - Stream tPrivateStream = PrivateService.streamIcdHeaders(scl); + Stream tPrivateStream = PrivateUtils.streamIcdHeaders(scl); //Then assertThat(tPrivateStream.toList()).isEmpty(); @@ -453,11 +453,11 @@ void comparePrivateCompasICDHeaders_should_return_true_equality_not_check_for_IE compasICDHeader1.setBayLabel("BAY-1"); compasICDHeader1.setIEDSubstationinstance(BigInteger.ONE); TCompasICDHeader compasICDHeader2 = new TCompasICDHeader(); - TPrivate tPrivate1 = PrivateService.createPrivate(compasICDHeader1); - TPrivate tPrivate2 = PrivateService.createPrivate(compasICDHeader2); + TPrivate tPrivate1 = PrivateUtils.createPrivate(compasICDHeader1); + TPrivate tPrivate2 = PrivateUtils.createPrivate(compasICDHeader2); // When - boolean result = PrivateService.comparePrivateCompasICDHeaders(tPrivate1,tPrivate2); + boolean result = PrivateUtils.comparePrivateCompasICDHeaders(tPrivate1,tPrivate2); // Then assertThat(result).isTrue(); } @@ -472,11 +472,11 @@ void comparePrivateCompasICDHeaders_should_return_false_equality_not_check_for_I compasICDHeader1.setICDSystemVersionUUID("UUID-1"); TCompasICDHeader compasICDHeader2 = new TCompasICDHeader(); compasICDHeader2.setICDSystemVersionUUID("UUID-2"); - TPrivate tPrivate1 = PrivateService.createPrivate(compasICDHeader1); - TPrivate tPrivate2 = PrivateService.createPrivate(compasICDHeader2); + TPrivate tPrivate1 = PrivateUtils.createPrivate(compasICDHeader1); + TPrivate tPrivate2 = PrivateUtils.createPrivate(compasICDHeader2); // When - boolean result = PrivateService.comparePrivateCompasICDHeaders(tPrivate1,tPrivate2); + boolean result = PrivateUtils.comparePrivateCompasICDHeaders(tPrivate1,tPrivate2); // Then assertThat(result).isFalse(); } @@ -491,11 +491,11 @@ void comparePrivateCompasICDHeaders_should_return_true() { compasICDHeader1.setICDSystemVersionUUID("UUID-1"); TCompasICDHeader compasICDHeader2 = new TCompasICDHeader(); compasICDHeader2.setICDSystemVersionUUID("UUID-1"); - TPrivate tPrivate1 = PrivateService.createPrivate(compasICDHeader1); - TPrivate tPrivate2 = PrivateService.createPrivate(compasICDHeader2); + TPrivate tPrivate1 = PrivateUtils.createPrivate(compasICDHeader1); + TPrivate tPrivate2 = PrivateUtils.createPrivate(compasICDHeader2); // When - boolean result = PrivateService.comparePrivateCompasICDHeaders(tPrivate1,tPrivate2); + boolean result = PrivateUtils.comparePrivateCompasICDHeaders(tPrivate1,tPrivate2); // Then assertThat(result).isTrue(); } @@ -510,13 +510,13 @@ void copyCompasICDHeaderFromLNodePrivateIntoSTDPrivate() { lNodeCompasICDHeader.setIEDName("IED-1"); lNodeCompasICDHeader.setBayLabel("BAY-1"); lNodeCompasICDHeader.setIEDSubstationinstance(BigInteger.ONE); - TPrivate stdTPrivate = PrivateService.createPrivate(stdCompasICDHeader); + TPrivate stdTPrivate = PrivateUtils.createPrivate(stdCompasICDHeader); // When - PrivateService.copyCompasICDHeaderFromLNodePrivateIntoSTDPrivate(stdTPrivate, lNodeCompasICDHeader); + PrivateUtils.copyCompasICDHeaderFromLNodePrivateIntoSTDPrivate(stdTPrivate, lNodeCompasICDHeader); // Then - TCompasICDHeader result = PrivateService.extractCompasICDHeader(stdTPrivate).get(); + TCompasICDHeader result = PrivateUtils.extractCompasICDHeader(stdTPrivate).get(); assertThat(result).extracting(TCompasICDHeader::getICDSystemVersionUUID, TCompasICDHeader::getIEDName, TCompasICDHeader::getIEDSubstationinstance, TCompasICDHeader::getBayLabel) .containsExactlyInAnyOrder("UUID-2", "IED-1", BigInteger.ONE, "BAY-1"); @@ -528,7 +528,7 @@ void getCompasICDHeaders_should_return_ICDHeaders() { TIED tied = createTIED(); //When - TCompasICDHeader tCompasICDHeader = PrivateService.extractCompasPrivate(tied, TCompasICDHeader.class).orElseThrow(); + TCompasICDHeader tCompasICDHeader = PrivateUtils.extractCompasPrivate(tied, TCompasICDHeader.class).orElseThrow(); //Then assertThat(tCompasICDHeader) @@ -579,7 +579,7 @@ void createPrivate_compas_Topo_should_succeed(){ TCompasTopo tCompasTopo2 = new TCompasTopo(); List compasTopos = List.of(tCompasTopo1, tCompasTopo2); // When - TPrivate result = PrivateService.createPrivate(compasTopos); + TPrivate result = PrivateUtils.createPrivate(compasTopos); // Then assertThat(result.getContent()) .map(JAXBElement.class::cast)