diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefEditorService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefEditorService.java index d99f14fb9..65cdce821 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefEditorService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefEditorService.java @@ -1,10 +1,11 @@ -// SPDX-FileCopyrightText: 2022 RTE FRANCE +// SPDX-FileCopyrightText: 2023 RTE FRANCE // // SPDX-License-Identifier: Apache-2.0 package org.lfenergy.compas.sct.commons; import lombok.RequiredArgsConstructor; +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.*; @@ -24,13 +25,13 @@ import org.lfenergy.compas.sct.commons.util.PrivateUtils; import org.lfenergy.compas.sct.commons.util.Utils; +import java.math.BigInteger; import java.util.*; import java.util.function.Function; import java.util.stream.Collectors; import static org.apache.commons.lang3.StringUtils.*; import static org.lfenergy.compas.sct.commons.util.CommonConstants.*; -import static org.lfenergy.compas.sct.commons.util.Utils.isExtRefFeedBySameControlBlock; @RequiredArgsConstructor public class ExtRefEditorService implements ExtRefEditor { @@ -42,21 +43,9 @@ public class ExtRefEditorService implements ExtRefEditor { "6", "THT", "7", "THT" ); - private final ExtRefService extRefService; - /** - * Remove ExtRef which are fed by same Control Block - * - * @return list ExtRefs without duplication - */ - public static List filterDuplicatedExtRefs(List tExtRefs) { - List filteredList = new ArrayList<>(); - tExtRefs.forEach(tExtRef -> { - if (filteredList.stream().noneMatch(t -> isExtRefFeedBySameControlBlock(tExtRef, t))) - filteredList.add(tExtRef); - }); - return filteredList; - } + private final LdeviceService ldeviceService; + private final ExtRefService extRefService; /** * Provides valid IED sources according to EPF configuration.
@@ -427,8 +416,7 @@ public void debindCompasFlowsAndExtRefsBasedOnVoltageLevel(SCL scd) { .filter(tlDevice -> tlDevice.getLN0().isSetInputs()) .forEach(tlDevice -> { String flowSource = voltageCodification.get(tVoltageLevelName); - TInputs tInputs = tlDevice.getLN0().getInputs(); - PrivateUtils.getPrivateStream(tInputs.getPrivate(), TCompasFlow.class) + extRefService.getCompasFlows(tlDevice) .filter(TCompasFlow::isSetFlowSourceVoltageLevel) .filter(TCompasFlow::isSetExtRefiedName) .forEach(tCompasFlow -> { @@ -437,19 +425,66 @@ public void debindCompasFlowsAndExtRefsBasedOnVoltageLevel(SCL scd) { extRefService.clearCompasFlowBinding(tCompasFlow); } else if (!tCompasFlow.getFlowSourceVoltageLevel().equals(flowSource)) { //debind extRef - extRefService.getMatchingExtRef(tInputs, tCompasFlow) + extRefService.getMatchingExtRefs(tlDevice, tCompasFlow) .forEach(extRefService::clearExtRefBinding); //debind compas flow extRefService.clearCompasFlowBinding(tCompasFlow); - } }); }) ); } - private record DoNameAndDaName(String doName, String daName) { + + @Override + public void updateIedNameBasedOnLnode(SCL scl) { + Map bayByTopoKey = scl.getSubstation().stream() + .flatMap(tSubstation -> tSubstation.getVoltageLevel().stream()) + .flatMap(tVoltageLevel -> tVoltageLevel.getBay().stream()) + .map(tBay -> PrivateUtils.extractCompasPrivate(tBay, TCompasTopo.class) + .filter(tCompasTopo -> isNotBlank(tCompasTopo.getNode()) && Objects.nonNull(tCompasTopo.getNodeOrder())) + .map(tCompasTopo -> new BayTopoKey(tBay, new TopoKey(tCompasTopo.getNode(), tCompasTopo.getNodeOrder()))) + ) + .flatMap(Optional::stream) + .collect(Collectors.toMap(BayTopoKey::topoKey, BayTopoKey::bay)); + + scl.getIED().stream() + .flatMap(ldeviceService::getLdevices) + .forEach(tlDevice -> + extRefService.getCompasFlows(tlDevice) + .filter(tCompasFlow -> Objects.nonNull(tCompasFlow.getFlowSourceBayNode()) && Objects.nonNull(tCompasFlow.getFlowSourceBayNodeOrder())) + .forEach(tCompasFlow -> + Optional.ofNullable(bayByTopoKey.get(new TopoKey(tCompasFlow.getFlowSourceBayNode().toString(), tCompasFlow.getFlowSourceBayNodeOrder()))) + .flatMap(tBay -> tBay.getFunction().stream() + .flatMap(tFunction -> tFunction.getLNode().stream()) + .filter(tlNode -> Objects.equals(tlNode.getLdInst(), tCompasFlow.getExtRefldinst()) + && Objects.equals(tlNode.getLnInst(), tCompasFlow.getExtReflnInst()) + && Utils.lnClassEquals(tlNode.getLnClass(), tCompasFlow.getExtReflnClass()) + && Objects.equals(tlNode.getPrefix(), tCompasFlow.getExtRefprefix())) + .map(TLNode::getIedName) + .filter(StringUtils::isNotBlank) + .findFirst() + ) + .ifPresentOrElse(iedName -> { + extRefService.getMatchingExtRefs(tlDevice, tCompasFlow).forEach(tExtRef -> tExtRef.setIedName(iedName)); + tCompasFlow.setExtRefiedName(iedName); + }, + () -> { + extRefService.getMatchingExtRefs(tlDevice, tCompasFlow).forEach(extRefService::clearExtRefBinding); + extRefService.clearCompasFlowBinding(tCompasFlow); + } + ) + ) + ); + } + + record TopoKey(String FlowNode, BigInteger FlowNodeOrder) { } + record BayTopoKey(TBay bay, TopoKey topoKey) { + } + + private record DoNameAndDaName(String doName, String daName) { + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ExtRefEditor.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ExtRefEditor.java index 4b656468f..6c2da6d7c 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ExtRefEditor.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/api/ExtRefEditor.java @@ -70,4 +70,9 @@ public interface ExtRefEditor { */ void debindCompasFlowsAndExtRefsBasedOnVoltageLevel(SCL scd); + /** + * Update compas:Flow.ExtRefiedName and ExtRef.iedName, based on Substation LNode iedName + */ + void updateIedNameBasedOnLnode(SCL scd); + } 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/scl/ExtRefService.java index 09da0767f..8040d4917 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/scl/ExtRefService.java @@ -6,26 +6,38 @@ package org.lfenergy.compas.sct.commons.scl; -import org.lfenergy.compas.scl2007b4.model.TCompasFlow; -import org.lfenergy.compas.scl2007b4.model.TExtRef; -import org.lfenergy.compas.scl2007b4.model.TInputs; +import org.lfenergy.compas.scl2007b4.model.*; import org.lfenergy.compas.sct.commons.util.PrivateUtils; import org.lfenergy.compas.sct.commons.util.Utils; +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; +import java.util.Optional; import java.util.stream.Stream; public class ExtRefService { /** - * List all ExtRefs in this Inputs + * List all ExtRefs in this LDevice * * @return list of ExtRefs. List is modifiable. */ - public Stream getExtRefs(TInputs inputs) { - if (inputs == null || !inputs.isSetExtRef()) { - return Stream.empty(); - } - return inputs.getExtRef().stream(); + public Stream getExtRefs(TLDevice tlDevice) { + return getInputs(tlDevice) + .filter(TInputs::isSetExtRef) + .stream() + .flatMap(tInputs -> tInputs.getExtRef().stream()); + } + + /** + * List all CompasFlows in this LDevice + * + * @return list of ExtRefs. List is modifiable. + */ + public Stream getCompasFlows(TLDevice tlDevice) { + return getInputs(tlDevice).stream() + .flatMap(tInputs -> PrivateUtils.extractCompasPrivates(tlDevice.getLN0().getInputs(), TCompasFlow.class)); } /** @@ -43,12 +55,12 @@ public Stream getMatchingCompasFlows(TInputs inputs, TExtRef tExtRe /** * Retrieves ExtRefs corresponding to given CompasFlow * - * @param inputs node containing CompasFlows and ExtRefs + * @param tlDevice LDevice containing CompasFlows and ExtRefs * @param tCompasFlow corresponding to Extrefs we are searching * @return stream of matching ExtRefs */ - public Stream getMatchingExtRef(TInputs inputs, TCompasFlow tCompasFlow) { - return getExtRefs(inputs) + public Stream getMatchingExtRefs(TLDevice tlDevice, TCompasFlow tCompasFlow) { + return getExtRefs(tlDevice) .filter(tExtRef -> isMatchingExtRef(tCompasFlow, tExtRef)); } @@ -103,4 +115,45 @@ private boolean isMatchingExtRef(TCompasFlow compasFlow, TExtRef extRef) { && Utils.equalsOrBothBlank(compasFlow.getExtReflnClass(), extRefLnClass) && Utils.equalsOrBothBlank(compasFlow.getExtReflnInst(), extRef.getLnInst()); } + + /** + * Checks if two ExtRefs fed by same Control Block + * + * @param t1 extref to compare + * @param t2 extref to compare + * @return true if the two ExtRef are fed by same Control Block, otherwise false + */ + public boolean isExtRefFeedBySameControlBlock(TExtRef t1, TExtRef t2) { + String srcLNClass1 = (t1.isSetSrcLNClass()) ? t1.getSrcLNClass().get(0) : TLLN0Enum.LLN_0.value(); + String srcLNClass2 = (t2.isSetSrcLNClass()) ? t2.getSrcLNClass().get(0) : TLLN0Enum.LLN_0.value(); + return Utils.equalsOrBothBlank(t1.getIedName(), t2.getIedName()) + && Utils.equalsOrBothBlank(t1.getSrcLDInst(), t2.getSrcLDInst()) + && srcLNClass1.equals(srcLNClass2) + && Utils.equalsOrBothBlank(t1.getSrcLNInst(), t2.getSrcLNInst()) + && Utils.equalsOrBothBlank(t1.getSrcPrefix(), t2.getSrcPrefix()) + && Utils.equalsOrBothBlank(t1.getSrcCBName(), t2.getSrcCBName()) + && Objects.equals(t1.getServiceType(), t2.getServiceType()); + } + + /** + * Remove ExtRef which are fed by same Control Block + * + * @return list ExtRefs without duplication + */ + public List filterDuplicatedExtRefs(List tExtRefs) { + List filteredList = new ArrayList<>(); + tExtRefs.forEach(tExtRef -> { + if (filteredList.stream().noneMatch(t -> isExtRefFeedBySameControlBlock(tExtRef, t))) + filteredList.add(tExtRef); + }); + return filteredList; + } + + private Optional getInputs(TLDevice tlDevice){ + if (!tlDevice.isSetLN0() || !tlDevice.getLN0().isSetInputs()) { + return Optional.empty(); + } + return Optional.of(tlDevice.getLN0().getInputs()); + } + } 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 afa9958c8..b2f38cbd5 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 @@ -9,6 +9,7 @@ import org.lfenergy.compas.scl2007b4.model.*; 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.SclElementAdapter; import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter; import org.lfenergy.compas.sct.commons.scl.ln.AbstractLNAdapter; @@ -19,8 +20,6 @@ import java.util.stream.Collectors; import java.util.stream.Stream; -import static org.lfenergy.compas.sct.commons.ExtRefEditorService.filterDuplicatedExtRefs; - /** * A representation of the model object * {@link org.lfenergy.compas.scl2007b4.model.TAccessPoint AccessPoint}. @@ -245,7 +244,7 @@ public ExtRefAnalyzeRecord getAllCoherentExtRefForAnalyze() { return extRefs; }).flatMap(Collection::stream) .toList(); - return new ExtRefAnalyzeRecord(sclReportItems, filterDuplicatedExtRefs(tExtRefList)); + return new ExtRefAnalyzeRecord(sclReportItems, new ExtRefService().filterDuplicatedExtRefs(tExtRefList)); } /** 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 b25094698..10a49ae39 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 @@ -8,7 +8,6 @@ import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.lfenergy.compas.scl2007b4.model.*; -import org.lfenergy.compas.sct.commons.ExtRefEditorService; import org.lfenergy.compas.sct.commons.dto.DataAttributeRef; import org.lfenergy.compas.sct.commons.dto.FcdaForDataSetsCreation; import org.lfenergy.compas.sct.commons.dto.SclReportItem; @@ -104,13 +103,13 @@ public List updateAllExtRefIedNames(Map icdSy try { ActiveStatus lDeviceStatus = ActiveStatus.fromValue(optionalLDeviceStatus.get()); return switch (lDeviceStatus) { - case ON -> extRefService.getExtRefs(currentElem) + case ON -> currentElem.getExtRef().stream() .filter(tExtRef -> StringUtils.isNotBlank(tExtRef.getIedName()) && StringUtils.isNotBlank(tExtRef.getDesc())) .map(extRef -> updateExtRefIedName(extRef, icdSystemVersionToIed.get(extRef.getIedName()))) .flatMap(Optional::stream) .toList(); case OFF -> { - extRefService.getExtRefs(currentElem).forEach(extRefService::clearExtRefBinding); + currentElem.getExtRef().forEach(extRefService::clearExtRefBinding); yield Collections.emptyList(); } }; @@ -209,7 +208,7 @@ public List updateAllSourceDataSetsAndControlBlocks(Set filterDuplicatedExtRefs() { - return ExtRefEditorService.filterDuplicatedExtRefs(extRefService.getExtRefs(currentElem).toList()); + return new ExtRefService().filterDuplicatedExtRefs(currentElem.getExtRef()); } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java index b5d155e69..ddbfdfb98 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/Utils.java @@ -10,12 +10,7 @@ import jakarta.xml.bind.Unmarshaller; import jakarta.xml.bind.util.JAXBSource; import org.apache.commons.lang3.StringUtils; -import org.lfenergy.compas.scl2007b4.model.TExtRef; -import org.lfenergy.compas.scl2007b4.model.TLLN0Enum; import org.lfenergy.compas.sct.commons.exception.ScdException; -import org.lfenergy.compas.sct.commons.scl.ln.AbstractLNAdapter; -import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter; -import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter; import javax.xml.namespace.QName; import java.util.*; @@ -371,23 +366,4 @@ public static T copySclElement(T object, Class clazz) { } } - /** - * Checks if two ExtRefs fed by same Control Block - * - * @param t1 extref to compare - * @param t2 extref to compare - * @return true if the two ExtRef are fed by same Control Block, otherwise false - */ - public static boolean isExtRefFeedBySameControlBlock(TExtRef t1, TExtRef t2) { - String srcLNClass1 = (t1.isSetSrcLNClass()) ? t1.getSrcLNClass().get(0) : TLLN0Enum.LLN_0.value(); - String srcLNClass2 = (t2.isSetSrcLNClass()) ? t2.getSrcLNClass().get(0) : TLLN0Enum.LLN_0.value(); - return Utils.equalsOrBothBlank(t1.getIedName(), t2.getIedName()) - && Utils.equalsOrBothBlank(t1.getSrcLDInst(), t2.getSrcLDInst()) - && srcLNClass1.equals(srcLNClass2) - && Utils.equalsOrBothBlank(t1.getSrcLNInst(), t2.getSrcLNInst()) - && Utils.equalsOrBothBlank(t1.getSrcPrefix(), t2.getSrcPrefix()) - && Utils.equalsOrBothBlank(t1.getSrcCBName(), t2.getSrcCBName()) - && Objects.equals(t1.getServiceType(), t2.getServiceType()); - } - } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefEditorServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefEditorServiceTest.java index df0e36403..73b5b1747 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefEditorServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ExtRefEditorServiceTest.java @@ -30,7 +30,6 @@ 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.sct.commons.ExtRefEditorService.filterDuplicatedExtRefs; import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.*; import static org.lfenergy.compas.sct.commons.util.CommonConstants.*; @@ -40,7 +39,7 @@ class ExtRefEditorServiceTest { @BeforeEach void init() { - extRefEditorService = new ExtRefEditorService(new ExtRefService()); + extRefEditorService = new ExtRefEditorService(new LdeviceService(), new ExtRefService()); } @Test @@ -211,41 +210,6 @@ private void assertExtRefIsNotBound(TExtRef extRef) { assertThat(extRef.isSetSrcCBName()).isFalse(); } - @Test - void filterDuplicatedExtRefs_should_remove_duplicated_extrefs() { - // Given - TExtRef tExtRefLnClass = createExtRefExample("CB_Name1", TServiceType.GOOSE); - tExtRefLnClass.getSrcLNClass().add(TLLN0Enum.LLN_0.value()); - TExtRef tExtRef = createExtRefExample("CB_Name1", TServiceType.GOOSE); - List tExtRefList = List.of(tExtRef, tExtRefLnClass, createExtRefExample("CB", TServiceType.GOOSE), - createExtRefExample("CB", TServiceType.GOOSE)); - // When - List result = filterDuplicatedExtRefs(tExtRefList); - // Then - assertThat(result).hasSizeLessThan(tExtRefList.size()) - .hasSize(2); - } - - @Test - void filterDuplicatedExtRefs_should_not_remove_not_duplicated_extrefs() { - // Given - TExtRef tExtRefIedName = createExtRefExample("CB_1", TServiceType.GOOSE); - tExtRefIedName.setIedName("IED_XXX"); - TExtRef tExtRefLdInst = createExtRefExample("CB_1", TServiceType.GOOSE); - tExtRefLdInst.setSrcLDInst("LD_XXX"); - TExtRef tExtRefLnInst = createExtRefExample("CB_1", TServiceType.GOOSE); - tExtRefLnInst.setSrcLNInst("X"); - TExtRef tExtRefPrefix = createExtRefExample("CB_1", TServiceType.GOOSE); - tExtRefPrefix.setSrcPrefix("X"); - List tExtRefList = List.of(tExtRefIedName, tExtRefLdInst, tExtRefLnInst, tExtRefPrefix, - createExtRefExample("CB_1", TServiceType.GOOSE), createExtRefExample("CB_1", TServiceType.SMV)); - // When - List result = filterDuplicatedExtRefs(tExtRefList); - // Then - assertThat(result).hasSameSizeAs(tExtRefList) - .hasSize(6); - } - @Test void manageBindingForLDEPF_whenFlowKindIsInternalAndAllExtRefInSameBay_should_return_noReportAndExtRefUpdateSuccessfully() { //Given @@ -532,7 +496,6 @@ void manageBindingForLDEPF_when_extRefMatchFlowKindInternalOrExternal_should_upd assertThat(extRefBindExternally.getIedName()).isEqualTo("IED_NAME2"); assertExtRefIsBoundAccordingTOLDEPF(extRefBindExternally, analogueChannel10WithBayExternalBayScope); } - private void assertExtRefIsBoundAccordingTOLDEPF(TExtRef extRef, TChannel setting) { assertThat(extRef.getLdInst()).isEqualTo(setting.getLDInst()); assertThat(extRef.getLnClass()).contains(setting.getLNClass()); @@ -829,4 +792,32 @@ private TInputs findInputs(SCL scd) { } + @Test + void updateIedNameBasedOnLnode_should_update_CompasFlow_and_ExtRef_iedName(){ + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_based_on_lnode_success.xml"); + // When + extRefEditorService.updateIedNameBasedOnLnode(scd); + // Then + assertThat(findCompasFlow(scd, "IED_NAME1", "LD_INST11", "STAT_LDSUIED_LPDO 1 Sortie_13_BOOLEAN_18_stVal_1").getExtRefiedName()) + .isEqualTo("IED_NAME2"); + assertThat(findExtRef(scd, "IED_NAME1", "LD_INST11", "STAT_LDSUIED_LPDO 1 Sortie_13_BOOLEAN_18_stVal_1").getIedName()) + .isEqualTo("IED_NAME2"); + } + + @Test + void updateIedNameBasedOnLnode_when_no_matching_lnode_should_clear_binding(){ + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-iedname/scd_set_extref_iedname_based_on_lnode_success.xml"); + PrivateUtils.extractCompasPrivate(scd.getSubstation().get(0).getVoltageLevel().get(0).getBay().get(0), TCompasTopo.class).orElseThrow().setNode("99"); + // When + extRefEditorService.updateIedNameBasedOnLnode(scd); + // Then + TCompasFlow compasFlow = findCompasFlow(scd, "IED_NAME1", "LD_INST11", "STAT_LDSUIED_LPDO 1 Sortie_13_BOOLEAN_18_stVal_1"); + assertThat(compasFlow) + .extracting(TCompasFlow::getExtRefiedName, TCompasFlow::getExtRefldinst, TCompasFlow::getExtRefprefix, TCompasFlow::getExtReflnClass, TCompasFlow::getExtReflnInst) + .containsOnlyNulls(); + assertExtRefIsNotBound(findExtRef(scd, "IED_NAME1", "LD_INST11", "STAT_LDSUIED_LPDO 1 Sortie_13_BOOLEAN_18_stVal_1")); + + } } 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/scl/ExtRefServiceTest.java index d0812915b..04c6057c6 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/scl/ExtRefServiceTest.java @@ -7,6 +7,7 @@ package org.lfenergy.compas.sct.commons.scl; import org.assertj.core.groups.Tuple; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -18,38 +19,74 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Named.named; +import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.createExtRefExample; class ExtRefServiceTest { - private static final ObjectFactory objectFactory = new ObjectFactory(); - ExtRefService extRefService = new ExtRefService(); + ExtRefService extRefService; - @ParameterizedTest(name = "{0}") - @MethodSource("provideTAnyLns") - void getExtRefs(String testCase, TInputs tInputs, int size) { - //Given - //When - //Then - assertThat(extRefService.getExtRefs(tInputs)).hasSize(size); + @BeforeEach + void setUp() { + extRefService = new ExtRefService(); } - private static Stream provideTAnyLns() { - TInputs tInputsEmpty = new TInputs(); + @Test + void getExtRefs_should_return_extRefs() { + //Given + TLDevice tlDevice = new TLDevice(); + tlDevice.setLN0(new LN0()); TInputs tInputs = new TInputs(); + tlDevice.getLN0().setInputs(tInputs); TExtRef tExtRef1 = new TExtRef(); TExtRef tExtRef2 = new TExtRef(); tInputs.getExtRef().add(tExtRef1); tInputs.getExtRef().add(tExtRef2); + //When + Stream result = extRefService.getExtRefs(tlDevice); + //Then + assertThat(result).hasSize(2); + } + + @ParameterizedTest + @MethodSource("provideLDevices") + void getExtRefs_should_return_empty_stream(TLDevice tlDevice) { + //Given : parameters + //When + Stream result = extRefService.getExtRefs(tlDevice); + //Then + assertThat(result).isEmpty(); + } + private static Stream provideLDevices() { + TLDevice tlDeviceWithoutLn0 = new TLDevice(); + tlDeviceWithoutLn0.setLN0(new LN0()); return Stream.of( - Arguments.of("Ln without Inputs node should return empty stream", null, 0), - Arguments.of("Ln with empty Inputs should return empty stream", tInputsEmpty, 0), - Arguments.of("Ln0 with Inputs node should return stream 2 extrefs", tInputs, 2)); + Arguments.of(named("LDevice without LN0 should return empty stream", tlDeviceWithoutLn0)), + Arguments.of(named("LDevice with empty Inputs should return empty stream", new TLDevice())) + ); + } + + @Test + void getCompasFlows_should_return_compasFlow() { + // Given + TLDevice tlDevice = new TLDevice(); + tlDevice.setLN0(new LN0()); + TInputs tInputs = new TInputs(); + tlDevice.getLN0().setInputs(tInputs); + TPrivate tPrivate = new TPrivate(); + tPrivate.setType(PrivateEnum.COMPAS_FLOW.getPrivateType()); + tPrivate.getContent().add(new ObjectFactory().createFlow(new TCompasFlow())); + tInputs.getPrivate().add(tPrivate); + // When + Stream result = extRefService.getCompasFlows(tlDevice); + // Then + assertThat(result).hasSize(1); } @Test - void getMatchingCompasFlows() { + void getMatchingCompasFlows_should_succeed() { //Given TInputs tInputs = new TInputs(); TExtRef tExtRef1 = createExtRef("Desc_1", "IED_Name_1", "LD_INST_1"); @@ -66,18 +103,19 @@ void getMatchingCompasFlows() { } @Test - void getMatchingTextRef() { + void getMatchingExtRefs_should_succeed() { //Given - TLN tln = new TLN(); + TLDevice tlDevice = new TLDevice(); + tlDevice.setLN0(new LN0()); TInputs tInputs = new TInputs(); TExtRef tExtRef1 = createExtRef("Desc_1", "IED_Name_1", "LD_INST_1"); TExtRef tExtRef2 = createExtRef("Desc_2", "IED_Name_2", "LD_INST_2"); tInputs.getExtRef().add(tExtRef1); tInputs.getExtRef().add(tExtRef2); TCompasFlow tCompasFlow = createCompasFlow("Desc_1", "IED_Name_1", "LD_INST_1"); - tln.setInputs(tInputs); + tlDevice.getLN0().setInputs(tInputs); //When - Stream tExtRefStream = extRefService.getMatchingExtRef(tInputs, tCompasFlow); + Stream tExtRefStream = extRefService.getMatchingExtRefs(tlDevice, tCompasFlow); //Then assertThat(tExtRefStream).hasSize(1) .map(TExtRef::getIedName, TExtRef::getLdInst, TExtRef::getDesc) @@ -85,28 +123,7 @@ void getMatchingTextRef() { } @Test - void getMatchingTextRef_success_when_lnclass_null() { - //Given - TLN tln = new TLN(); - TInputs tInputs = new TInputs(); - TExtRef tExtRef1 = createExtRef("Desc_1", "IED_Name_1", "LD_INST_1"); - tExtRef1.getLnClass().clear(); - TExtRef tExtRef2 = createExtRef("Desc_2", "IED_Name_2", "LD_INST_2"); - tInputs.getExtRef().add(tExtRef1); - tInputs.getExtRef().add(tExtRef2); - TCompasFlow tCompasFlow = createCompasFlow("Desc_1", "IED_Name_1", "LD_INST_1"); - tCompasFlow.setExtReflnClass(null); - tln.setInputs(tInputs); - //When - Stream tExtRefStream = extRefService.getMatchingExtRef(tInputs, tCompasFlow); - //Then - assertThat(tExtRefStream).hasSize(1) - .map(TExtRef::getIedName, TExtRef::getLdInst, TExtRef::getDesc) - .containsExactly(Tuple.tuple("IED_Name_1", "LD_INST_1", "Desc_1")); - } - - @Test - void clearBinding() { + void clearExtRefBinding_should_remove_binding() { //Given TExtRef tExtRef = createExtRef("Desc_1", "IED_Name_1", "LD_INST_1"); //When @@ -119,7 +136,7 @@ void clearBinding() { } @Test - void clearCompasFlowBinding() { + void clearCompasFlowBinding_should_remove_binding() { //Given TCompasFlow compasFlow = createCompasFlow("Desc_1", "IED_Name_1", "LD_INST_1"); //When @@ -131,10 +148,106 @@ void clearCompasFlowBinding() { assertThat(compasFlow.getDataStreamKey()).isEqualTo("Desc_1"); } + @ParameterizedTest + @MethodSource("provideExtRefsFedBySameControlBlock") + void isExtRefFeedBySameControlBlock_should_return_true(TExtRef tExtRef1, TExtRef tExtRef2) { + // Given : parameter + // When + boolean result = extRefService.isExtRefFeedBySameControlBlock(tExtRef1, tExtRef2); + // Then + assertThat(result).isTrue(); + } + + private static Stream provideExtRefsFedBySameControlBlock() { + TExtRef tExtRefLnClass = createExtRefExample("CB_1", TServiceType.GOOSE); + tExtRefLnClass.getSrcLNClass().add(TLLN0Enum.LLN_0.value()); + + return Stream.of( + Arguments.of(createExtRefExample("CB_1", TServiceType.GOOSE), createExtRefExample("CB_1", TServiceType.GOOSE)), + Arguments.of(tExtRefLnClass, createExtRefExample("CB_1", TServiceType.GOOSE)), + Arguments.of(createExtRefExample("CB_1", TServiceType.GOOSE), tExtRefLnClass) + ); + } + + @ParameterizedTest + @MethodSource("provideExtRefsToCompare") + void isExtRefFeedBySameControlBlock_should_return_false(TExtRef tExtRef1, TExtRef tExtRef2) { + // Given : parameters + // When + boolean result = extRefService.isExtRefFeedBySameControlBlock(tExtRef1, tExtRef2); + // Then + assertThat(result).isFalse(); + } + + private static Stream provideExtRefsToCompare() { + TExtRef tExtRefLnClass = createExtRefExample("CB_1", TServiceType.GOOSE); + tExtRefLnClass.getSrcLNClass().add("XXX"); + TExtRef tExtRefIedName = createExtRefExample("CB_1", TServiceType.GOOSE); + tExtRefIedName.setIedName("IED_XXX"); + TExtRef tExtRefLdInst = createExtRefExample("CB_1", TServiceType.GOOSE); + tExtRefLdInst.setSrcLDInst("LD_XXX"); + TExtRef tExtRefLnInst = createExtRefExample("CB_1", TServiceType.GOOSE); + tExtRefLnInst.setSrcLNInst("X"); + TExtRef tExtRefPrefix = createExtRefExample("CB_1", TServiceType.GOOSE); + tExtRefPrefix.setSrcPrefix("X"); + + return Stream.of( + Arguments.of(named("ExtRef is not fed by same CB when different ServiceType", createExtRefExample("CB_1", TServiceType.GOOSE)), + createExtRefExample("CB_1", TServiceType.SMV)), + Arguments.of(named("ExtRef is not fed by same CB when different SrcCBName", createExtRefExample("CB_1", TServiceType.GOOSE)), + createExtRefExample("CB_2", TServiceType.GOOSE)), + Arguments.of(named("ExtRef is not fed by same CB when different SrcLnClass", createExtRefExample("CB_1", TServiceType.GOOSE)), + tExtRefLnClass), + Arguments.of(named("ExtRef is not fed by same CB when different IedName", createExtRefExample("CB_1", TServiceType.GOOSE)), + tExtRefIedName), + Arguments.of(named("ExtRef is not fed by same CB when different SrcLdInst", createExtRefExample("CB_1", TServiceType.GOOSE)), + tExtRefLdInst), + Arguments.of(named("ExtRef is not fed by same CB when different SrcLnInst", createExtRefExample("CB_1", TServiceType.GOOSE)), + tExtRefLnInst), + Arguments.of(named("ExtRef is not fed by same CB when different SrcPrefix", createExtRefExample("CB_1", TServiceType.GOOSE)), + tExtRefPrefix) + ); + } + + @Test + void filterDuplicatedExtRefs_should_remove_duplicated_extrefs() { + // Given + TExtRef tExtRefLnClass = createExtRefExample("CB_Name1", TServiceType.GOOSE); + tExtRefLnClass.getSrcLNClass().add(TLLN0Enum.LLN_0.value()); + TExtRef tExtRef = createExtRefExample("CB_Name1", TServiceType.GOOSE); + List tExtRefList = List.of(tExtRef, tExtRefLnClass, createExtRefExample("CB", TServiceType.GOOSE), + createExtRefExample("CB", TServiceType.GOOSE)); + // When + List result = extRefService.filterDuplicatedExtRefs(tExtRefList); + // Then + assertThat(result).hasSizeLessThan(tExtRefList.size()) + .hasSize(2); + } + + @Test + void filterDuplicatedExtRefs_should_not_remove_not_duplicated_extrefs() { + // Given + TExtRef tExtRefIedName = createExtRefExample("CB_1", TServiceType.GOOSE); + tExtRefIedName.setIedName("IED_XXX"); + TExtRef tExtRefLdInst = createExtRefExample("CB_1", TServiceType.GOOSE); + tExtRefLdInst.setSrcLDInst("LD_XXX"); + TExtRef tExtRefLnInst = createExtRefExample("CB_1", TServiceType.GOOSE); + tExtRefLnInst.setSrcLNInst("X"); + TExtRef tExtRefPrefix = createExtRefExample("CB_1", TServiceType.GOOSE); + tExtRefPrefix.setSrcPrefix("X"); + List tExtRefList = List.of(tExtRefIedName, tExtRefLdInst, tExtRefLnInst, tExtRefPrefix, + createExtRefExample("CB_1", TServiceType.GOOSE), createExtRefExample("CB_1", TServiceType.SMV)); + // When + List result = extRefService.filterDuplicatedExtRefs(tExtRefList); + // Then + assertThat(result).hasSameSizeAs(tExtRefList) + .hasSize(6); + } + private static TPrivate createPrivateCompasFlow(List compasFlows) { TPrivate tPrivate = new TPrivate(); tPrivate.setType(PrivateEnum.COMPAS_FLOW.getPrivateType()); - tPrivate.getContent().addAll(compasFlows.stream().map(objectFactory::createFlow).toList()); + tPrivate.getContent().addAll(compasFlows.stream().map(value -> new ObjectFactory().createFlow(value)).toList()); return tPrivate; } @@ -158,4 +271,4 @@ private TCompasFlow createCompasFlow(String dataStreamKey, String extRefIedName, return tCompasFlow; } -} \ No newline at end of file +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java index fdea655ab..89987741d 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java @@ -13,6 +13,7 @@ import org.lfenergy.compas.sct.commons.scl.ln.LN0Adapter; import org.lfenergy.compas.sct.commons.scl.ln.LNAdapter; import org.lfenergy.compas.sct.commons.util.ControlBlockEnum; +import org.lfenergy.compas.sct.commons.util.PrivateUtils; import org.lfenergy.compas.sct.commons.util.Utils; import org.opentest4j.AssertionFailedError; @@ -69,7 +70,14 @@ public static TExtRef findExtRef(SCL scl, String iedName, String ldInst, String .stream() .filter(extRef -> extRefDesc.equals(extRef.getDesc())) .findFirst() - .orElseThrow(() -> new AssertionFailedError(String.format("ExtRef.des=%s not found in IED.name=%s,LDevice.inst=%s", extRefDesc, iedName, ldInst))); + .orElseThrow(() -> new AssertionFailedError(String.format("ExtRef.desc=%s not found in IED.name=%s,LDevice.inst=%s", extRefDesc, iedName, ldInst))); + } + + public static TCompasFlow findCompasFlow(SCL scl, String iedName, String ldInst, String compasFlowDataStreamKey) { + return PrivateUtils.extractCompasPrivates(findInputs(scl, iedName, ldInst).getCurrentElem(), TCompasFlow.class) + .filter(compasFlow -> compasFlowDataStreamKey.equals(compasFlow.getDataStreamKey())) + .findFirst() + .orElseThrow(() -> new AssertionFailedError(String.format("CompasFlow.dataStreamKey=%s not found in IED.name=%s,LDevice.inst=%s", compasFlowDataStreamKey, iedName, ldInst))); } public static LN0Adapter findLn0(SCL scl, String iedName, String ldInst) { diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/UtilsTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/UtilsTest.java index 788b466d3..a1d66361f 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/UtilsTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/util/UtilsTest.java @@ -11,10 +11,8 @@ import org.junit.jupiter.params.provider.MethodSource; import org.junit.jupiter.params.provider.ValueSource; import org.junit.platform.commons.support.ReflectionSupport; -import org.lfenergy.compas.scl2007b4.model.TExtRef; import org.lfenergy.compas.scl2007b4.model.TLLN0Enum; import org.lfenergy.compas.scl2007b4.model.TLN; -import org.lfenergy.compas.scl2007b4.model.TServiceType; import org.lfenergy.compas.sct.commons.dto.FCDAInfo; import org.lfenergy.compas.sct.commons.exception.ScdException; @@ -22,7 +20,6 @@ import java.util.stream.Stream; import static org.assertj.core.api.Assertions.*; -import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.createExtRefExample; import static org.lfenergy.compas.sct.commons.util.Utils.copySclElement; @@ -514,57 +511,6 @@ void toHex_should_return_hexadecimal(long number, int length, String expected) { assertThat(result).isEqualTo(expected); } - @Test - void isExtRefFeedBySameControlBlock_should_return_true() { - // Given - TExtRef tExtRefLnClass = createExtRefExample("CB_1", TServiceType.GOOSE); - tExtRefLnClass.getSrcLNClass().add(TLLN0Enum.LLN_0.value()); - TExtRef tExtRef = createExtRefExample("CB_1", TServiceType.GOOSE); - // When - // Then - assertThat(Utils.isExtRefFeedBySameControlBlock(tExtRef, tExtRefLnClass)).isTrue(); - assertThat(Utils.isExtRefFeedBySameControlBlock(createExtRefExample("CB_1", TServiceType.GOOSE), tExtRef)).isTrue(); - } - - @ParameterizedTest(name = "{0}") - @MethodSource("provideExtRefsToCompare") - void isExtRefFeedBySameControlBlock_should_return_false(String testCase, TExtRef tExtRef1, TExtRef tExtRef2) { - // Given - // When - // Then - assertThat(Utils.isExtRefFeedBySameControlBlock(tExtRef1, tExtRef2)).isFalse(); - } - - private static Stream provideExtRefsToCompare() { - TExtRef tExtRefLnClass = createExtRefExample("CB_1", TServiceType.GOOSE); - tExtRefLnClass.getSrcLNClass().add("XXX"); - TExtRef tExtRefIedName = createExtRefExample("CB_1", TServiceType.GOOSE); - tExtRefIedName.setIedName("IED_XXX"); - TExtRef tExtRefLdInst = createExtRefExample("CB_1", TServiceType.GOOSE); - tExtRefLdInst.setSrcLDInst("LD_XXX"); - TExtRef tExtRefLnInst = createExtRefExample("CB_1", TServiceType.GOOSE); - tExtRefLnInst.setSrcLNInst("X"); - TExtRef tExtRefPrefix = createExtRefExample("CB_1", TServiceType.GOOSE); - tExtRefPrefix.setSrcPrefix("X"); - - return Stream.of( - Arguments.of("ExtRef is not fed by same CB when different ServiceType", createExtRefExample("CB_1", TServiceType.GOOSE), - createExtRefExample("CB_1", TServiceType.SMV)), - Arguments.of("ExtRef is not fed by same CB when different SrcCBName", createExtRefExample("CB_1", TServiceType.GOOSE), - createExtRefExample("CB_2", TServiceType.GOOSE)), - Arguments.of("ExtRef is not fed by same CB when different SrcLnClass", createExtRefExample("CB_1", TServiceType.GOOSE), - tExtRefLnClass), - Arguments.of("ExtRef is not fed by same CB when different IedName", createExtRefExample("CB_1", TServiceType.GOOSE), - tExtRefIedName), - Arguments.of("ExtRef is not fed by same CB when different SrcLdInst", createExtRefExample("CB_1", TServiceType.GOOSE), - tExtRefLdInst), - Arguments.of("ExtRef is not fed by same CB when different SrcLnInst", createExtRefExample("CB_1", TServiceType.GOOSE), - tExtRefLnInst), - Arguments.of("ExtRef is not fed by same CB when different SrcPrefix", createExtRefExample("CB_1", TServiceType.GOOSE), - tExtRefPrefix) - ); - } - @Test void copySclElement_should_copy_by_value() { // Given diff --git a/sct-commons/src/test/resources/scd-extref-iedname/scd_set_extref_iedname_based_on_lnode_success.xml b/sct-commons/src/test/resources/scd-extref-iedname/scd_set_extref_iedname_based_on_lnode_success.xml new file mode 100644 index 000000000..f42453fb9 --- /dev/null +++ b/sct-commons/src/test/resources/scd-extref-iedname/scd_set_extref_iedname_based_on_lnode_success.xml @@ -0,0 +1,93 @@ + + + + + +
+ + + 0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + on + + + + + + + + + + + + + + + + + + + + + + + + + on + + + + + + + + + + + + + + + + + + + + + + + on + off + test + + +