From 32116f0f847a2f60591eb0b0ec6bf32bb1f166b0 Mon Sep 17 00:00:00 2001 From: Aliou DIAITE Date: Mon, 14 Nov 2022 11:01:01 +0100 Subject: [PATCH] fix(#185): fix bug update extref cb Signed-off-by: Aliou DIAITE Signed-off-by: SABATIER Philippe Ext Signed-off-by: Aliou DIAITE --- .../compas/sct/commons/dto/DataSetInfo.java | 2 +- .../compas/sct/commons/dto/ExtRefInfo.java | 47 --- .../compas/sct/commons/scl/SclService.java | 4 +- .../commons/scl/ied/AbstractLNAdapter.java | 322 +++++++++--------- .../sct/commons/dto/DataSetInfoTest.java | 77 ++++- .../sct/commons/dto/ExtRefInfoTest.java | 51 --- .../sct/commons/scl/SclServiceTest.java | 99 +++++- .../sct/commons/scl/ied/LN0AdapterTest.java | 107 ++---- .../sct/commons/scl/ied/LNAdapterTest.java | 141 ++++++-- .../scd-extref-cb/scd_get_cbs_test.xml | 2 +- 10 files changed, 470 insertions(+), 382 deletions(-) diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataSetInfo.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataSetInfo.java index e1a62614a..8ef98c1b1 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataSetInfo.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/DataSetInfo.java @@ -65,7 +65,7 @@ public static DataSetInfo from(TDataSet tDataSet) { * @return Set of DataSetInfo */ public static Set getDataSets(AbstractLNAdapter lnAdapter){ - return lnAdapter.getDataSet(null) + return lnAdapter.getDataSetMatchingExtRefInfo(null) .stream().map(DataSetInfo::from).collect(Collectors.toSet()); } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfo.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfo.java index 595bfcc06..867c2fc17 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfo.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfo.java @@ -6,13 +6,8 @@ import lombok.*; -import org.apache.commons.lang3.StringUtils; import org.lfenergy.compas.scl2007b4.model.TExtRef; import org.lfenergy.compas.scl2007b4.model.TFCDA; -import org.lfenergy.compas.scl2007b4.model.TLLN0Enum; -import org.lfenergy.compas.sct.commons.scl.ied.AbstractLNAdapter; - -import java.util.Objects; /** * A representation of the model object ExtRef. * @@ -75,48 +70,6 @@ public static ExtRefInfo from(TExtRef tExtRef, String iedName, String ldInst, return extRefInfo; } - /** - * Check match between FCDA and ExtRef information (for binding) - * @param tfcda FCDA data object - * @return match state - */ - //TODO this method should be checked, return if parameter tested are not present in FCDA even if two object are different - public boolean matchFCDA(@NonNull TFCDA tfcda){ - boolean returnValue = true; - if(AbstractLNAdapter.isFCDANull(tfcda)) { - returnValue = false; - } - - if(tfcda.getLdInst() != null && - (bindingInfo == null || !tfcda.getLdInst().equals(bindingInfo.getLdInst()))){ - returnValue = false; - } - if (!tfcda.getLnClass().isEmpty() && - ( bindingInfo == null || !tfcda.getLnClass().contains(bindingInfo.getLnClass())) ){ - returnValue = false; - } - - boolean isLN0 = tfcda.getLnClass().contains(TLLN0Enum.LLN_0.value()); - if (!isLN0 && tfcda.getLnInst() != null && - (bindingInfo == null || !tfcda.getLnInst().equals(bindingInfo.getLnInst()))) { - returnValue = false; - } - if (!isLN0 && !StringUtils.isBlank(tfcda.getPrefix()) && - (bindingInfo == null || !tfcda.getPrefix().equals(bindingInfo.getPrefix()))) { - returnValue = false; - } - - if(!StringUtils.isBlank(tfcda.getDoName()) && - (signalInfo == null || !Objects.equals(signalInfo.getPDO(),tfcda.getDoName())) ){ - returnValue = false; - } - - if(!StringUtils.isBlank(tfcda.getDaName()) && - (signalInfo == null || !Objects.equals(signalInfo.getPDA(),tfcda.getDaName())) ){ - returnValue = false; - } - return returnValue; - } /** * Check matching between FCDA and ExtRef information (for external binding) * Check is done for parameter lDInst(mandatory), lNClass(mandatory), lNInst, prefix doName as pDO(mandatory) and daName as pDA diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java index 6488cec5c..8b52b1666 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java @@ -365,7 +365,7 @@ public static TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws if (bindingInfo == null || !bindingInfo.isValid()) { throw new ScdException(INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO); } - if (bindingInfo.getIedName().equals(iedName)) { + if (bindingInfo.getIedName().equals(iedName) || TServiceType.POLL.equals(bindingInfo.getServiceType())) { throw new ScdException("Internal binding can't have control block"); } ExtRefSourceInfo sourceInfo = extRefInfo.getSourceInfo(); @@ -377,7 +377,7 @@ public static TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws IEDAdapter iedAdapter = sclRootAdapter.getIEDAdapterByName(iedName); LDeviceAdapter lDeviceAdapter = iedAdapter.findLDeviceAdapterByLdInst(ldInst) .orElseThrow(() -> new ScdException(String.format(UNKNOWN_LDEVICE_S_IN_IED_S, ldInst, iedName))); - var anLNAdapter = AbstractLNAdapter.builder() + AbstractLNAdapter anLNAdapter = AbstractLNAdapter.builder() .withLDeviceAdapter(lDeviceAdapter) .withLnClass(lnClass) .withLnInst(lnInst) diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java index cb5d84742..5286d7b2f 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AbstractLNAdapter.java @@ -19,6 +19,7 @@ import java.util.*; import java.util.stream.Collectors; +import java.util.stream.Stream; /** @@ -45,10 +46,8 @@ *
  • {@link AbstractLNAdapter#getDAI Returns the value of the ResumedDataTemplate containment reference By filter}
  • *
  • {@link AbstractLNAdapter#getDAIValues(ResumedDataTemplate) Returns DAI (sGroup, value) containment reference list By ResumedDataTemplate filter}
  • * - *
  • {@link AbstractLNAdapter#getDataSet(ExtRefInfo) Returns the value of the TDataSet containment reference list By ExtRefInfo }
  • *
  • {@link AbstractLNAdapter#getDataSetByRef(String) Returns the value of the TDataSet object reference By the value of the name attribute }
  • * - *
  • {@link AbstractLNAdapter#getControlSetByExtRefInfo(ExtRefInfo) Returns the value of the ControlBlock containment reference list By ExtRefInfo }
  • *
  • {@link AbstractLNAdapter#getControlBlocks(List, TServiceType) Returns the value of the ControlBlock containment reference list that match datSet value of given TDataSet }
  • *
  • {@link AbstractLNAdapter#addPrivate Add TPrivate under this object}
  • *
  • {@link AbstractLNAdapter#removeAllControlBlocksAndDatasets() Remove all ControlBlock}
  • @@ -89,7 +88,7 @@ public static LNAdapterBuilder builder() { protected abstract Class getElementClassType(); - public abstract String getLNClass() ; + public abstract String getLNClass(); public abstract String getLNInst(); @@ -217,6 +216,7 @@ public List getExtRefs(ExtRefSignalInfo filter) { /** * Check whether the LN has an Inputs node + * * @return true if the LN has an Inputs node */ public boolean hasInputs() { @@ -225,6 +225,7 @@ public boolean hasInputs() { /** * Checks for ExtRef signal existence in target LN + * * @param signalInfo ExtRef signal data to check */ public void isExtRefExist(ExtRefSignalInfo signalInfo) { @@ -240,7 +241,7 @@ public void isExtRefExist(ExtRefSignalInfo signalInfo) { Objects.equals(tExtRef.getPDO(), signalInfo.getPDO()) && Objects.equals(signalInfo.getIntAddr(), tExtRef.getIntAddr()) && Objects.equals(signalInfo.getPServT(), tExtRef.getPServT())); - if(!extRefExist) { + if (!extRefExist) { throw new ScdException("ExtRef signal does not exist in target LN"); } } @@ -324,22 +325,6 @@ protected void updateExtRefBindingInfo(TExtRef extRef, ExtRefInfo extRefInfo) { } } - /** - * Gets Control Blocks of LN specified in extRefInfo - * - * @param extRefInfo ExtRef signal data for which Control Blocks should be found - * @return list of ControlBlock object as ControlBlocks of LNode - */ - public List> getControlSetByExtRefInfo(ExtRefInfo extRefInfo) { - List tDataSets = this.getDataSet(extRefInfo); - return getControlBlocks(tDataSets, extRefInfo.getBindingInfo().getServiceType()); - } - public List> getControlSet(ExtRefInfo extRefInfo) { - List tDataSets = this.getDataSetMatchingExtRefInfo(extRefInfo); - return getControlBlocks(tDataSets,extRefInfo.getBindingInfo().getServiceType()); - } - - /** * Gets Control Blocks matching FCDA compatible with specified in extRefInfo * @@ -359,91 +344,84 @@ public List> getControlBlocksForMatchingFCDA(@NonNull ExtRefInfo * @return list of ControlBlock objects */ protected List> getControlBlocks(List tDataSets, TServiceType serviceType) { - List> controlBlocks = new ArrayList<>(); - List tControls; - - LNodeMetaData metaData = LNodeMetaData.from(this); - + /*List> controlBlocks = new ArrayList<>(); for (TDataSet tDataSet : tDataSets) { - if (isLN0() && (serviceType == null || serviceType == TServiceType.GOOSE)) { - tControls = this.lookUpControlBlocksByDataSetRef(tDataSet.getName(), TGSEControl.class); - controlBlocks.addAll( - tControls.stream() - .map(tgseControl -> { - var g = new GooseControlBlock((TGSEControl) tgseControl); - g.setMetaData(metaData); - return g; - }) - .collect(Collectors.toList()) - ); - } + controlBlocks.addAll(getControlBlocksByDataSetRef(tDataSet.getName(), serviceType)); + }*/ + return tDataSets.stream().map(tDataSet -> getControlBlocksByDataSetRef(tDataSet.getName(), serviceType)).flatMap(Collection::stream).toList(); - if (isLN0() && (serviceType == null || serviceType == TServiceType.SMV)) { - - tControls = this.lookUpControlBlocksByDataSetRef(tDataSet.getName(), TSampledValueControl.class); - controlBlocks.addAll( - tControls.stream() - .map(sampledValueControl -> { - var s = new SMVControlBlock((TSampledValueControl) sampledValueControl); - s.setMetaData(metaData); - return s; - }) - .collect(Collectors.toList()) - ); - } - - if (serviceType == null || serviceType == TServiceType.REPORT) { - tControls = this.lookUpControlBlocksByDataSetRef(tDataSet.getName(), TReportControl.class); - controlBlocks.addAll( - tControls.stream() - .map(reportControl -> { - var r = new ReportControlBlock((TReportControl) reportControl); - r.setMetaData(metaData); - return r; - }) - .collect(Collectors.toList()) - ); - } - } - return controlBlocks; } /** - * Gets Control Blocks for specified Data Set reference - * - * @param dataSetRef Data Set for which Control Blocks are needed - * @param cls class type of Control Block (GOOSE, SMV and REPORT) - * @param inference type - * @return List of Control Blocks corresponding to cls + * finds all Control Blocks by dataSetRef and a Service Type (GOOSE, SampleValue, Report) or all Service Types. + * @param dataSetRef DatSet value searched + * @param serviceType service type to be filtered + * @return all Control Blocks matching dataSetRef and a Service Type or all Service Types */ - protected List lookUpControlBlocksByDataSetRef(@NonNull String dataSetRef, Class cls) { - List ls = new ArrayList<>(); + private List> getControlBlocksByDataSetRef(String dataSetRef, TServiceType serviceType) { + Stream> streamGSEControl = Stream.empty(); + Stream> streamSMVControl = Stream.empty(); + Stream> streamReportControl = Stream.empty(); + LNodeMetaData metaData = LNodeMetaData.from(this); + if (isLN0() && (serviceType == null || serviceType == TServiceType.GOOSE)) { + streamGSEControl = getTControlsByType(TGSEControl.class) + .stream() + .filter(tControl -> dataSetRef.equals(tControl.getDatSet())) + .map(tgseControl -> { + GooseControlBlock gseCbl = new GooseControlBlock((TGSEControl) tgseControl); + gseCbl.setMetaData(metaData); + return gseCbl;}); + + } + if (isLN0() && (serviceType == null || serviceType == TServiceType.SMV)) { + streamSMVControl = getTControlsByType(TSampledValueControl.class) + .stream() + .filter(tControl -> dataSetRef.equals(tControl.getDatSet())) + .map(sampledValueControl -> { + SMVControlBlock smvCbl = new SMVControlBlock((TSampledValueControl) sampledValueControl); + smvCbl.setMetaData(metaData); + return smvCbl;}); + } + if (serviceType == null || serviceType == TServiceType.REPORT) { + streamReportControl = getTControlsByType(TReportControl.class) + .stream() + .filter(tControl -> dataSetRef.equals(tControl.getDatSet())) + .map(reportControl -> { + ReportControlBlock rptCbl = new ReportControlBlock((TReportControl) reportControl); + rptCbl.setMetaData(metaData); + return rptCbl; }); + } + return Stream.concat(Stream.concat(streamGSEControl,streamSMVControl),streamReportControl).toList(); + } + + /** + * finds all Control Blocks by Service Type (GOOSE, SampleValue, Report). + * @param cls Type of Control Block + * @return all Control Blocks matching a Service Type + * @param inference parameter for Type of Control Block to find + */ + private List getTControlsByType(Class cls) { + List tControls = new ArrayList<>(); if (TGSEControl.class.equals(cls) && isLN0()) { - ls = ((LN0) currentElem).getGSEControl(); + tControls = ((LN0) currentElem).getGSEControl(); } else if (TSampledValueControl.class.equals(cls) && isLN0()) { - ls = ((LN0) currentElem).getSampledValueControl(); + tControls = ((LN0) currentElem).getSampledValueControl(); } else if (TReportControl.class.equals(cls)) { - ls = currentElem.getReportControl(); + tControls = currentElem.getReportControl(); } - - return ls.stream() - .map(TControl.class::cast) - .filter(tControl -> dataSetRef.equals(tControl.getDatSet())) - .collect(Collectors.toList()); + return tControls; } /** - * Checks if FCDA is null - * - * @param tfcda FCDA to check - * @return Boolean value of check result + * Checks if LN contains a Control block with specified name + * @param cbName name of Control Block searched + * @return true if there is at one control Block matches, otherwise false */ - //TODO check method should be checked, why nullability is checked only for this parameters - public static boolean isFCDANull(TFCDA tfcda){ - return Objects.isNull(tfcda.getLdInst()) && - tfcda.getLnClass().isEmpty() && - Objects.isNull(tfcda.getFc()); - + private boolean isCBKnown(String cbName) { + return isLN0() + && ( ((LN0) currentElem).getGSEControl().stream().anyMatch(tgse -> tgse.getName().equals(cbName)) || + ((LN0) currentElem).getSampledValueControl().stream().anyMatch(tsmv -> tsmv.getName().equals(cbName))) + || currentElem.getReportControl().stream().anyMatch(trpt -> trpt.getName().equals(cbName)); } /** @@ -469,33 +447,23 @@ public boolean hasControlBlock(ControlBlock controlBlock } } - public List getDataSet(ExtRefInfo filter) { - if (filter == null || filter.getSignalInfo() == null || filter.getBindingInfo() == null) { - return currentElem.getDataSet(); - } - - return currentElem.getDataSet() - .stream() - .filter(tDataSet -> tDataSet.getFCDA() - .stream() - .anyMatch(filter::matchFCDA) - ) - .collect(Collectors.toList()); - } - /** - * retrieves all DataSets for which at least one FCDA mathches with data given in ExtRefInfo for external binding + * retrieves all DataSets for which at least one FCDA matches with data given in ExtRefInfo for external binding + * * @param filter contains data for external binding which should match with FCDAs values - * @return list of Data for which at least one FCDA mathches with filter datas + * @return list of Data for which at least one FCDA matches with filter datas */ - public List getDataSetMatchingExtRefInfo(ExtRefInfo filter){ + public List getDataSetMatchingExtRefInfo(ExtRefInfo filter) { + if (filter == null) { + return currentElem.getDataSet(); + } return currentElem.getDataSet() .stream() .filter(tDataSet -> tDataSet.getFCDA() .stream() .anyMatch(filter::checkMatchingFCDA) ) - .collect(Collectors.toList()); + .toList(); } /** @@ -510,11 +478,14 @@ public TExtRef updateExtRefSource(ExtRefInfo extRefInfo) throws ScdException { ExtRefSourceInfo sourceInfo = extRefInfo.getSourceInfo(); ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo(); - if (signalInfo == null || bindingInfo == null || sourceInfo == null) { + if (signalInfo == null || bindingInfo == null || sourceInfo == null || StringUtils.isBlank(sourceInfo.getSrcCBName())) { throw new IllegalArgumentException("ExtRef information (signal, binding, source) are missing"); } - TExtRef extRef = checkExtRefInfoCoherence(extRefInfo); + checkExtRefInfoCoherence(extRefInfo); + + TExtRef extRef = extractExtRefFromExtRefInfo(extRefInfo); + updateExtRefBindingInfo(extRef, extRefInfo); return extRef; @@ -527,45 +498,16 @@ public TExtRef updateExtRefSource(ExtRefInfo extRefInfo) throws ScdException { * ControlBlock info),it verifies that the CB and dataset it points to, exists within and existing binder IED. * * @param extRefInfo ExtRef information (signal, binding and source info) - * @return TExtRef that matches the signal info - * @throws IllegalArgumentException when no given signal info - * @throws ScdException throws exception if - *
      - *
    • given signal info or it doesn't match any TExtRef in this LNode
    • - *
    • the given binding info doesn't match the found TExtRef's binding info.
    • - *
    • the given binding info doesn't refer to an exiting IED, LDevice and LNode in the SCL
    • - *
    • given source info references unknown control block
    • - *
    - */ - public TExtRef checkExtRefInfoCoherence(@NonNull ExtRefInfo extRefInfo) throws ScdException { - ExtRefSignalInfo signalInfo = extRefInfo.getSignalInfo(); - ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo(); - if (signalInfo == null) { - log.error("Coherence checking needs at least a signal info"); - throw new IllegalArgumentException("Coherence checking needs at least a signal info"); - } - - String holderIedName = extRefInfo.getHolderIEDName(); // parent (IED) of parent (LD) can be used here - String holderLdInst = extRefInfo.getHolderLDInst(); // parent (LD) can be use here - List extRefs = getExtRefs(signalInfo); - if (extRefs.isEmpty()) { - String msg = String.format("Unknown TExtRef with signal info [pDO(%s),intAddr(%s)] in %s%s/%s%s%s", - signalInfo.getPDO(), signalInfo.getIntAddr(), holderIedName, holderLdInst, - getPrefix(), getLNClass(), getLNInst()); - log.error(msg); - throw new ScdException(msg); - } - - TExtRef extRef = extRefs.get(0); // to be refined : what's the criteria for ExtRef's uniqueness - if (bindingInfo == null) { - return extRef; - } + * @throws ScdException throws exception if + *
      + *
    • the given binding info doesn't match the found TExtRef's binding info.
    • + *
    • the given binding info doesn't refer to an existing IED, LDevice and LNode in the SCL
    • + *
    • given source info references unknown control block
    • + *
    + */ + public void checkExtRefInfoCoherence(ExtRefInfo extRefInfo) { - if (!bindingInfo.isWrappedIn(extRef)) { - String msg = "No relation between binding info and the matched TExtRef"; - log.error(msg); - throw new ScdException(msg); - } + ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo(); String binderIedName = bindingInfo.getIedName(); String binderLdInst = bindingInfo.getLdInst(); @@ -574,44 +516,82 @@ public TExtRef checkExtRefInfoCoherence(@NonNull ExtRefInfo extRefInfo) throws S String binderLnPrefix = bindingInfo.getPrefix(); IEDAdapter binderIEDAdapter; - if(!binderIedName.equals( getCurrentIed().getName())){ // external binding + + if (!binderIedName.equals(getCurrentIed().getName())) { binderIEDAdapter = getCurrentScd().getIEDAdapterByName(binderIedName); } else { binderIEDAdapter = getCurrentIed(); } - LDeviceAdapter binderLDAdapter = binderIEDAdapter.findLDeviceAdapterByLdInst(binderLdInst) + LDeviceAdapter binderLDeviceAdapter = binderIEDAdapter.findLDeviceAdapterByLdInst(binderLdInst) .orElseThrow( () -> new ScdException( String.format("Unknown LDevice (%s) in IED (%s)", binderLdInst, binderIedName) ) ); - AbstractLNAdapter anLNAdapter = AbstractLNAdapter.builder() - .withLDeviceAdapter(binderLDAdapter) - .withLnClass(binderLnClass) - .withLnInst(binderLnInst) - .withLnPrefix(binderLnPrefix) - .build(); - - boolean isCoherent; ExtRefSourceInfo sourceInfo = extRefInfo.getSourceInfo(); - if (sourceInfo == null || sourceInfo.isNull()) { // to be refined : what to do here functionally ? - return extRef; - } - List> cbs = anLNAdapter.getControlSetByExtRefInfo(extRefInfo); - isCoherent = !cbs.isEmpty() && cbs.stream() - .anyMatch(controlBlock -> controlBlock.getName().equals(sourceInfo.getSrcCBName())); - if(!isCoherent){ - String msg = String.format("Unknown control block %s in %s%s/%s%s%s", - sourceInfo.getSrcCBName(), binderIedName,binderLdInst, - binderLnPrefix , binderLnClass, binderLnInst); + List> aLNAdapters = getPossibleSourceLNAdapters(binderLDeviceAdapter, sourceInfo); + + boolean isCBKnown = aLNAdapters.stream() + .anyMatch(abstractLNAdapter -> abstractLNAdapter.isCBKnown(extRefInfo.getSourceInfo().getSrcCBName())); + + if (!isCBKnown) { + String msg = String.format("Unknown control block %s in Ied: %s / LdInst: %s / LnPrefix: %s LnClass: %s LnInst: %s", + extRefInfo.getSourceInfo().getSrcCBName(), binderIedName, binderLdInst, binderLnPrefix, binderLnClass, binderLnInst); log.error(msg); throw new ScdException(msg); + } + } - return extRef; + /** + * Gets all possible LNs for given source info + * @param binderLDeviceAdapter LDevice in which LNs are searched + * @param sourceInfo binding LN info + * @return list of LNAdapters matching SourceInfo + */ + private List> getPossibleSourceLNAdapters(LDeviceAdapter binderLDeviceAdapter, ExtRefSourceInfo sourceInfo) { + List> aLNAdapters = new ArrayList<>(); + if(StringUtils.isBlank(sourceInfo.getSrcLNClass())){ + aLNAdapters.addAll(binderLDeviceAdapter.getLNAdaptersInclundigLN0()); + } else { + if(TLLN0Enum.LLN_0.value().equals(sourceInfo.getSrcLNClass())){ + aLNAdapters.add(binderLDeviceAdapter.getLN0Adapter()); + } else { + aLNAdapters.add(binderLDeviceAdapter.getLNAdapter(sourceInfo.getSrcLNClass(), sourceInfo.getSrcLNInst(), sourceInfo.getSrcPrefix())); + } + } + return aLNAdapters; } + /** + * Finds ExtRef from LN + * @param extRefInfo ExtRef information (signal, binding and source info) + * @return TExtRef matching given + */ + public TExtRef extractExtRefFromExtRefInfo(@NonNull ExtRefInfo extRefInfo) { + + ExtRefSignalInfo signalInfo = extRefInfo.getSignalInfo(); + List extRefs = getExtRefs(signalInfo); + + if (extRefs.isEmpty()) { + String holderIedName = extRefInfo.getHolderIEDName(); // parent (IED) of parent (LD) can be used here + String holderLdInst = extRefInfo.getHolderLDInst(); // parent (LD) can be use here + String msg = String.format("Unknown TExtRef with signal info [pDO(%s),intAddr(%s)] in %s%s/%s%s%s", + signalInfo.getPDO(), signalInfo.getIntAddr(), holderIedName, holderLdInst, + getPrefix(), getLNClass(), getLNInst()); + log.error(msg); + throw new ScdException(msg); + } + TExtRef extRef = extRefs.get(0);// to be refined : what's the criteria for ExtRef's uniqueness + ExtRefBindingInfo bindingInfo = extRefInfo.getBindingInfo(); + if (!bindingInfo.isWrappedIn(extRef)) { + String msg = "No relation between binding info and the matched TExtRef"; + log.error(msg); + throw new ScdException(msg); + } + return extRef; + } /** * Returns a list of resumed DataTypeTemplate for DataAttribute (updatable or not) @@ -693,6 +673,7 @@ private IEDAdapter getCurrentIed() { /** * Gets root Scd + * * @return SclRootAdapter object */ protected SclRootAdapter getCurrentScd() { @@ -701,6 +682,7 @@ protected SclRootAdapter getCurrentScd() { /** * Gets SCL DataTypeTemplate + * * @return DataTypeTemplateAdapter object */ public DataTypeTemplateAdapter getDataTypeTemplateAdapter() { diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DataSetInfoTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DataSetInfoTest.java index b573e743f..5b7f81cba 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DataSetInfoTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DataSetInfoTest.java @@ -6,35 +6,104 @@ import org.junit.jupiter.api.Test; import org.lfenergy.compas.scl2007b4.model.TDataSet; -import org.lfenergy.compas.scl2007b4.model.TFCDA; +import org.lfenergy.compas.scl2007b4.model.TLN; +import org.lfenergy.compas.sct.commons.scl.ied.LNAdapter; +import java.util.Set; + +import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; class DataSetInfoTest { @Test void testConstructor(){ + //Given When DataSetInfo dataSetInfo = new DataSetInfo(); assertNull(dataSetInfo.getName()); dataSetInfo = new DataSetInfo("DATA_INFO"); assertEquals("DATA_INFO",dataSetInfo.getName()); dataSetInfo.setName("DATA_INFO1"); dataSetInfo.addFCDAInfo(new FCDAInfo()); - + //Then assertEquals("DATA_INFO1",dataSetInfo.getName()); assertFalse(dataSetInfo.getFCDAInfos().isEmpty()); } @Test void testFrom(){ + //Given TDataSet dataSet = new TDataSet(); dataSet.setName("dataset"); dataSet.getFCDA().add(DTO.createFCDA()); - + //When DataSetInfo dataSetInfo = DataSetInfo.from(dataSet); - + //Then assertEquals("dataset", dataSetInfo.getName()); assertEquals(1,dataSetInfo.getFCDAInfos().size()); } + @Test + void getDataSets_shouldReturnEmptyList_whenNoDataSetInLN(){ + //Given + LNAdapter lnAdapter = new LNAdapter(null, new TLN()); + //When + Set dataSetInfos = DataSetInfo.getDataSets(lnAdapter); + //Then + assertThat(dataSetInfos).isEmpty(); + } + + @Test + void getDataSets_shouldReturnDataSet_whenLNContainsMatchingFCDA(){ + //Given + TDataSet dataSet = new TDataSet(); + dataSet.setName("datasetName"); + dataSet.getFCDA().add(DTO.createFCDA()); + TLN tln = new TLN(); + tln.getDataSet().add(dataSet); + LNAdapter lnAdapter = new LNAdapter(null, tln); + //When + Set dataSetInfos = DataSetInfo.getDataSets(lnAdapter); + //Then + assertThat(dataSetInfos).hasSize(1) + .extracting(DataSetInfo::getName).contains("datasetName"); + } + + + @Test + void isValid_shouldReturnFalse_whenNameSizeMore32() { + //Given + DataSetInfo dataSetInfo = new DataSetInfo(); + assertNull(dataSetInfo.getName()); + dataSetInfo = new DataSetInfo("DATA_INFO_TEST_CHARACTERE_NAME_MORE_THAN_32_CHARACTERES"); + //When + boolean isValid = dataSetInfo.isValid(); + //Then + assertThat(isValid).isFalse(); + } + @Test + void isValid_shouldReturnFalse_whenFCDAInfoEmpty() { + DataSetInfo dataSetInfo = new DataSetInfo(); + assertNull(dataSetInfo.getName()); + dataSetInfo = new DataSetInfo("DATA_INFO"); + //When + boolean isValid = dataSetInfo.isValid(); + //Then + assertThat(dataSetInfo.getFCDAInfos()).isEmpty(); + assertThat(isValid).isFalse(); + } + + @Test + void isValid_shouldReturnTrue_whenFCDAInfosValid() { + //Given + TDataSet dataSet = new TDataSet(); + dataSet.setName("dataset"); + dataSet.getFCDA().add(DTO.createFCDA()); + DataSetInfo dataSetInfo = DataSetInfo.from(dataSet); + //When + boolean isValid = dataSetInfo.isValid(); + //Then + assertThat(isValid).isTrue(); + } + } \ No newline at end of file diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfoTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfoTest.java index fe3da128d..38e9d9ff9 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfoTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/ExtRefInfoTest.java @@ -38,57 +38,6 @@ void testConstruction(){ assertNotNull(extRefInfo1.getSourceInfo()); } - @Test - void testMatchTFCDA(){ - ExtRefInfo extRefInfo = new ExtRefInfo(); - - TFCDA tfcda = new TFCDA(); - assertFalse(extRefInfo.matchFCDA(tfcda)); - - tfcda.setLdInst("LD"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - extRefInfo.setBindingInfo(new ExtRefBindingInfo()); - assertFalse(extRefInfo.matchFCDA(tfcda)); - extRefInfo.getBindingInfo().setLdInst("LD1"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - - extRefInfo.getBindingInfo().setLdInst("LD"); - tfcda.getLnClass().add("LNCLASS"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - extRefInfo.getBindingInfo().setLnClass("LNCLASS1"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - - extRefInfo.getBindingInfo().setLnClass("LNCLASS"); - tfcda.setLnInst("1"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - extRefInfo.getBindingInfo().setLnInst("2"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - - extRefInfo.getBindingInfo().setLnInst("1"); - tfcda.setPrefix("PR"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - extRefInfo.getBindingInfo().setPrefix("RP"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - - extRefInfo.getBindingInfo().setPrefix("PR"); - tfcda.setDoName("Do"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - extRefInfo.setSignalInfo(new ExtRefSignalInfo()); - assertFalse(extRefInfo.matchFCDA(tfcda)); - extRefInfo.getSignalInfo().setPDO("Do1"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - - extRefInfo.getSignalInfo().setPDO("Do"); - tfcda.setDaName("Da"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - extRefInfo.getSignalInfo().setPDA("Da1"); - assertFalse(extRefInfo.matchFCDA(tfcda)); - - extRefInfo.getSignalInfo().setPDA("Da"); - assertTrue(extRefInfo.matchFCDA(tfcda)); - } - - private ExtRefInfo createExtRef(){ ExtRefInfo extRefInfo = new ExtRefInfo(); extRefInfo.setSignalInfo(DTO.createExtRefSignalInfo()); diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java index e4f28d5e4..30abd6ce2 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java @@ -288,7 +288,7 @@ void getExtRefSourceInfo_shouldReturnEmptyList_whenExtRefMatchNoFCDA() throws Ex List> controlBlocks = SclService.getExtRefSourceInfo(scd, extRefInfo); //Then - assertThat(controlBlocks).hasSize(0); + assertThat(controlBlocks).isEmpty(); } @Test @@ -329,8 +329,10 @@ void updateExtRefSource_shouldThrowScdException_whenSignalInfoNullOrInvalid() th 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 } @@ -349,12 +351,14 @@ void updateExtRefSource_shouldThrowScdException_whenBindingInfoNullOrInvalid() t 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_whenBindingInternalBinding() throws Exception { + void updateExtRefSource_shouldThrowScdException_whenBindingInternalByIedName() throws Exception { //Given SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); ExtRefInfo extRefInfo = new ExtRefInfo(); @@ -376,6 +380,60 @@ void updateExtRefSource_shouldThrowScdException_whenBindingInternalBinding() thr //When Then assertThatThrownBy(() -> SclService.updateExtRefSource(scd, extRefInfo)).isInstanceOf(ScdException.class); // CB not allowed } + + @Test + void updateExtRefSource_shouldThrowScdException_whenBindingInternaByServiceType() throws Exception { + //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() throws Exception { + //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() throws Exception { //Given @@ -397,14 +455,18 @@ void updateExtRefSource_shouldThrowScdException_whenBindingExternalBinding() thr extRefBindingInfo.setLnClass(TLLN0Enum.LLN_0.value()); extRefInfo.setBindingInfo(extRefBindingInfo); - extRefInfo.setSourceInfo(new ExtRefSourceInfo()); - extRefInfo.getSourceInfo().setSrcLDInst(extRefInfo.getBindingInfo().getLdInst()); - extRefInfo.getSourceInfo().setSrcLNClass(extRefInfo.getBindingInfo().getLnClass()); - extRefInfo.getSourceInfo().setSrcCBName("goose1"); + ExtRefSourceInfo sourceInfo = new ExtRefSourceInfo(); + sourceInfo.setSrcLDInst(extRefInfo.getBindingInfo().getLdInst()); + sourceInfo.setSrcLNClass(extRefInfo.getBindingInfo().getLnClass()); + sourceInfo.setSrcCBName("goose1"); + extRefInfo.setSourceInfo(sourceInfo); - //When Then + //When TExtRef extRef = assertDoesNotThrow(() -> SclService.updateExtRefSource(scd, extRefInfo)); - assertEquals(extRefInfo.getSourceInfo().getSrcCBName(), extRef.getSrcCBName()); + //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) { @@ -499,8 +561,9 @@ void getDAI_when_LDevice_not_found_should_throw_exception() throws Exception { SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); // when & then + ResumedDataTemplate resumedDataTemplate = new ResumedDataTemplate(); assertThrows(ScdException.class, - () -> SclService.getDAI(scd, "IED_NAME1", "UNKNOWNLD", new ResumedDataTemplate(), true)); + () -> SclService.getDAI(scd, "IED_NAME1", "UNKNOWNLD", resumedDataTemplate, true)); } @Test @@ -716,31 +779,37 @@ void testImportSTDElementsInSCD_with_Multiple_STD() throws Exception { @Test void testImportSTDElementsInSCD_Several_STD_Match_Compas_ICDHeader() throws Exception { + //Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml"); SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); SCL std1 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); - - assertThrows(ScdException.class, () -> SclService.importSTDElementsInSCD(scdRootAdapter, Set.of(std, std1), DTO.comMap)); + //When Then + Set stds = Set.of(std, std1); + assertThrows(ScdException.class, () -> SclService.importSTDElementsInSCD(scdRootAdapter, stds, DTO.comMap)); assertIsMarshallable(scd); } @Test void testImportSTDElementsInSCD_Compas_ICDHeader_Not_Match() throws Exception { + //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); - - assertThrows(ScdException.class, ()-> SclService.importSTDElementsInSCD(scdRootAdapter, Set.of(std), DTO.comMap)); + //When Then + Set stds = Set.of(std); + assertThrows(ScdException.class, ()-> SclService.importSTDElementsInSCD(scdRootAdapter, stds, DTO.comMap)); assertIsMarshallable(scd); } @Test void testImportSTDElementsInSCD_No_STD_Match() throws Exception { + //Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml"); SclRootAdapter scdRootAdapter = new SclRootAdapter(scd); - - assertThrows(ScdException.class, ()-> SclService.importSTDElementsInSCD(scdRootAdapter, new HashSet<>(), DTO.comMap)); + //When Then + Set stds = new HashSet<>(); + assertThrows(ScdException.class, ()-> SclService.importSTDElementsInSCD(scdRootAdapter, stds, DTO.comMap)); assertIsMarshallable(scd); } 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 d3d0d54d9..97ae4b083 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 @@ -60,38 +60,6 @@ void testAmChildElementRef() throws ScdException { LN0 ln01 = new LN0(); assertThrows(IllegalArgumentException.class, () -> new LN0Adapter(lDeviceAdapter, ln01)); } - - @Test - void testLookUpControlBlocksByDataSetRef(){ - LDeviceAdapter lDeviceAdapter = Mockito.mock(LDeviceAdapter.class); - TLDevice tlDevice = Mockito.mock(TLDevice.class); - Mockito.when(lDeviceAdapter.getCurrentElem()).thenReturn(tlDevice); - LN0 ln0 = new LN0(); - Mockito.when(tlDevice.getLN0()).thenReturn(ln0); - LN0Adapter ln0Adapter = assertDoesNotThrow( () -> new LN0Adapter(lDeviceAdapter,ln0)); - // GSE LookUp - TGSEControl tgseControl = new TGSEControl(); - String dataSetRef = "DATASET_REF"; - tgseControl.setDatSet(dataSetRef); - ln0.getGSEControl().add(tgseControl); - - assertFalse(ln0Adapter.lookUpControlBlocksByDataSetRef(dataSetRef,TGSEControl.class).isEmpty()); - - // SMV LookUp - TSampledValueControl sampledValueControl = new TSampledValueControl(); - sampledValueControl.setDatSet(dataSetRef); - ln0.getSampledValueControl().add(sampledValueControl); - - assertFalse(ln0Adapter.lookUpControlBlocksByDataSetRef(dataSetRef,TSampledValueControl.class).isEmpty()); - - // SMV LookUp - TReportControl reportControl = new TReportControl(); - reportControl.setDatSet(dataSetRef); - ln0.getReportControl().add(reportControl); - - assertFalse(ln0Adapter.lookUpControlBlocksByDataSetRef(dataSetRef,TReportControl.class).isEmpty()); - } - // AbstractLNAdapter class test @Test void containsFCDA() { @@ -232,7 +200,7 @@ void testGetDataSetWith(){ TDataSet tDataSet = new TDataSet(); ln0.getDataSet().add(tDataSet); - List tDataSets = ln0Adapter.getDataSet(null); + List tDataSets = ln0Adapter.getDataSetMatchingExtRefInfo(null); assertFalse(tDataSets.isEmpty()); ExtRefInfo extRefInfo = DTO.createExtRefInfo(); @@ -241,11 +209,11 @@ void testGetDataSetWith(){ TFCDA tfcda = new TFCDA(); tDataSet.getFCDA().add(tfcda); - tDataSets = ln0Adapter.getDataSet(extRefInfo); + tDataSets = ln0Adapter.getDataSetMatchingExtRefInfo(extRefInfo); assertTrue(tDataSets.isEmpty()); - Mockito.doReturn(true).when(extRefInfo).matchFCDA(ArgumentMatchers.any(TFCDA.class)); - tDataSets = ln0Adapter.getDataSet(extRefInfo); + Mockito.doReturn(true).when(extRefInfo).checkMatchingFCDA(ArgumentMatchers.any(TFCDA.class)); + tDataSets = ln0Adapter.getDataSetMatchingExtRefInfo(extRefInfo); assertFalse(tDataSets.isEmpty()); } @@ -260,41 +228,38 @@ void testGetControlBlocks(){ LN0 ln0 = new LN0(); Mockito.when(tlDevice.getLN0()).thenReturn(ln0); LN0Adapter ln0Adapter = assertDoesNotThrow( () -> new LN0Adapter(lDeviceAdapter,ln0)); - - - - TDataSet tDataSet = new TDataSet(); - tDataSet.setName(DTO.CB_DATASET_REF); - - List> controlBlocks = ln0Adapter.getControlBlocks(List.of(tDataSet),null); + TGSEControl tgseControl = new TGSEControl(); + tgseControl.setDatSet("GSE_REF"); + TSampledValueControl tSampledValueControl = new TSampledValueControl(); + tSampledValueControl.setDatSet("SMV_REF"); + TReportControl tReportControl = new TReportControl(); + tReportControl.setDatSet("RPT_REF"); + ln0Adapter.getCurrentElem().getGSEControl().add(tgseControl); + ln0Adapter.getCurrentElem().getSampledValueControl().add(tSampledValueControl); + ln0Adapter.getCurrentElem().getReportControl().add(tReportControl); + + TDataSet tDataSetGSE = new TDataSet(); + tDataSetGSE.setName(DTO.CB_DATASET_REF); + + List> controlBlocks = ln0Adapter.getControlBlocks(List.of(tDataSetGSE),null); assertTrue(controlBlocks.isEmpty()); - ln0Adapter = Mockito.spy(ln0Adapter); - Mockito.doReturn(List.of(new TGSEControl())) - .when(ln0Adapter) - .lookUpControlBlocksByDataSetRef( - ArgumentMatchers.anyString(),ArgumentMatchers.eq(TGSEControl.class) - ); - - Mockito.doReturn(List.of(new TSampledValueControl())) - .when(ln0Adapter) - .lookUpControlBlocksByDataSetRef( - ArgumentMatchers.anyString(),ArgumentMatchers.eq(TSampledValueControl.class) - ); - - Mockito.doReturn(List.of(new TReportControl())) - .when(ln0Adapter) - .lookUpControlBlocksByDataSetRef( - ArgumentMatchers.anyString(),ArgumentMatchers.eq(TReportControl.class) - ); - controlBlocks = ln0Adapter.getControlBlocks(List.of(tDataSet),TServiceType.REPORT); - assertEquals(1,controlBlocks.size()); - controlBlocks = ln0Adapter.getControlBlocks(List.of(tDataSet),TServiceType.SMV); - assertEquals(1,controlBlocks.size()); - controlBlocks = ln0Adapter.getControlBlocks(List.of(tDataSet),TServiceType.GOOSE); - assertEquals(1,controlBlocks.size()); - controlBlocks = ln0Adapter.getControlBlocks(List.of(tDataSet),null); - assertEquals(3,controlBlocks.size()); + tDataSetGSE.setName("GSE_REF"); + TDataSet tDataSetSMV = new TDataSet(); + tDataSetSMV.setName("SMV_REF"); + TDataSet tDataSetRPT = new TDataSet(); + tDataSetRPT.setName("RPT_REF"); + + List tDataSets = List.of(tDataSetGSE, tDataSetSMV, tDataSetRPT); + + controlBlocks = ln0Adapter.getControlBlocks(tDataSets,TServiceType.REPORT); + assertThat(controlBlocks).hasSize(1); + controlBlocks = ln0Adapter.getControlBlocks(tDataSets,TServiceType.SMV); + assertThat(controlBlocks).hasSize(1); + controlBlocks = ln0Adapter.getControlBlocks(tDataSets,TServiceType.GOOSE); + assertThat(controlBlocks).hasSize(1); + controlBlocks = ln0Adapter.getControlBlocks(tDataSets,null); + assertThat(controlBlocks).hasSize(3); } @Test @@ -313,13 +278,13 @@ void testGetControlSetByBindingInfo(){ ExtRefInfo extRefBindingInfo = DTO.createExtRefInfo(); Mockito.doReturn(List.of(new TDataSet())) - .when(ln0Adapter).getDataSet(ArgumentMatchers.any(ExtRefInfo.class)); + .when(ln0Adapter).getDataSetMatchingExtRefInfo(ArgumentMatchers.any(ExtRefInfo.class)); Mockito.doReturn(List.of(new ReportControlBlock())) .when(ln0Adapter).getControlBlocks( ArgumentMatchers.any(List.class),ArgumentMatchers.any(TServiceType.class)); - List> controlBlocks = ln0Adapter.getControlSetByExtRefInfo(extRefBindingInfo); + List> controlBlocks = ln0Adapter.getControlBlocksForMatchingFCDA(extRefBindingInfo); assertFalse(controlBlocks.isEmpty()); assertEquals(TServiceType.REPORT,controlBlocks.get(0).getServiceType()); } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java index 20643753c..dc5f526ec 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ied/LNAdapterTest.java @@ -94,7 +94,8 @@ void updateExtRefBindingInfo_shouldUpdateBindingInfo_whenBindingInfoNull() { assertNull(extRef.getIedName()); assertNull(extRef.getSrcLDInst()); } -@Test + + @Test void updateExtRefBindingInfo_shouldUpdateBindingInfo_whenNotBindingInfoNull() { //Given ExtRefInfo extRefInfo = DTO.createExtRefInfo(); @@ -123,7 +124,7 @@ void updateExtRefBinders_shouldUpdateExtRefs() throws Exception { .withLnInst("1") .build(); ExtRefInfo info = DTO.createExtRefInfo(); - info.getSignalInfo().setPDO("StrVal.sdo2"); + info.getSignalInfo().setPDO("StrVal.sdo2"); info.getSignalInfo().setPDA("antRef.bda1.bda2.bda3"); info.getSignalInfo().setIntAddr("INT_ADDR2"); info.getSignalInfo().setDesc(null); @@ -156,8 +157,8 @@ void updateExtRefBinders_shouldThrowsException(String testCase, ExtRefInfo info, private static Stream extRefInfoAndMessage() { return Stream.of( - Arguments.of("whenBindingInfoNotValid",new ExtRefInfo(), "ExtRef mandatory binding data are missing"), - Arguments.of("whenNoExtRefFound",DTO.createExtRefInfo(), "Unknown ExtRef [pDO(FACntRs1.res),intAddr(INT_ADDR)] in IED_NAME/LD_INST_H.ANCR") + Arguments.of("whenBindingInfoNotValid", new ExtRefInfo(), "ExtRef mandatory binding data are missing"), + Arguments.of("whenNoExtRefFound", DTO.createExtRefInfo(), "Unknown ExtRef [pDO(FACntRs1.res),intAddr(INT_ADDR)] in IED_NAME/LD_INST_H.ANCR") ); } @@ -174,12 +175,13 @@ void updateExtRefBinders_shouldUpdateExtRefs_whenManyExtRefMatch() { LN0Adapter ln0Adapter = new LN0Adapter(null, ln0); ExtRefInfo info = DTO.createExtRefInfo(); //When Then - assertDoesNotThrow(() ->ln0Adapter.updateExtRefBinders(info)); + assertDoesNotThrow(() -> ln0Adapter.updateExtRefBinders(info)); } - @Test - void checkExtRefInfoCoherence() throws Exception { + void should_throw_ScdException_when_the_given_binding_info_does_not_match_the_found_TExtRef_binding_info() throws Exception { + + //Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-cb/scd_get_cbs_test.xml"); SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED_NAME1")); @@ -189,14 +191,28 @@ void checkExtRefInfoCoherence() throws Exception { .withLnClass(TLLN0Enum.LLN_0.value()) .build(); - assertThrows(IllegalArgumentException.class, () -> lnAdapter.checkExtRefInfoCoherence(new ExtRefInfo())); + ExtRefInfo extRefInfo = DTO.createExtRefInfo(); + //When + //Then + assertThrows(ScdException.class, () -> lnAdapter.extractExtRefFromExtRefInfo(extRefInfo)); + } + + @Test + void should_throw_ScdException_when_the_given_binding_info_does_not_refer_to_an_existing_IED_LDevice_and_LNode_in_the_SCL() throws Exception { + + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-cb/scd_get_cbs_test.xml"); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iAdapter = assertDoesNotThrow(() -> sclRootAdapter.getIEDAdapterByName("IED_NAME1")); + LDeviceAdapter lDeviceAdapter = assertDoesNotThrow(() -> iAdapter.getLDeviceAdapterByLdInst("LD_INST11")); + AbstractLNAdapter lnAdapter = AbstractLNAdapter.builder() + .withLDeviceAdapter(lDeviceAdapter) + .withLnClass(TLLN0Enum.LLN_0.value()) + .build(); ExtRefInfo extRefInfo = DTO.createExtRefInfo(); - extRefInfo.setBindingInfo(null); extRefInfo.setSourceInfo(null); - assertThrows(ScdException.class, () -> lnAdapter.checkExtRefInfoCoherence(extRefInfo)); - extRefInfo.getSignalInfo().setDesc(null); extRefInfo.getSignalInfo().setPLN(null); extRefInfo.getSignalInfo().setPServT(null); @@ -204,31 +220,94 @@ void checkExtRefInfoCoherence() throws Exception { extRefInfo.getSignalInfo().setPDO("Do11.sdo11"); extRefInfo.getSignalInfo().setIntAddr("INT_ADDR11"); - TExtRef extRef = assertDoesNotThrow(() -> lnAdapter.checkExtRefInfoCoherence(extRefInfo)); - assertEquals(extRefInfo.getSignalInfo().getPDO(), extRef.getPDO()); - ExtRefBindingInfo bindingInfo = DTO.createExtRefBindingInfo_Remote(); extRefInfo.setBindingInfo(bindingInfo); - assertThrows(ScdException.class, () -> lnAdapter.checkExtRefInfoCoherence(extRefInfo)); + //When + //Then + assertThrows(ScdException.class, () -> lnAdapter.extractExtRefFromExtRefInfo(extRefInfo)); + } + + @Test + void should_check_with_success_extRefInfo_coherence() throws Exception { + + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-cb/scd_get_cbs_test.xml"); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1"); + LDeviceAdapter lDeviceAdapter = iAdapter.getLDeviceAdapterByLdInst("LD_INST11"); + + AbstractLNAdapter lnAdapter = AbstractLNAdapter.builder() + .withLDeviceAdapter(lDeviceAdapter) + .withLnClass(TLLN0Enum.LLN_0.value()) + .build(); + + ExtRefInfo extRefInfo = DTO.createExtRefInfo(); + extRefInfo.getSignalInfo().setDesc(null); + extRefInfo.getSignalInfo().setPLN(null); + extRefInfo.getSignalInfo().setPServT(null); + extRefInfo.getSignalInfo().setPDA("da11.bda111.bda112.bda113"); + extRefInfo.getSignalInfo().setPDO("Do11.sdo11"); + extRefInfo.getSignalInfo().setIntAddr("INT_ADDR11"); + + ExtRefBindingInfo bindingInfo = DTO.createExtRefBindingInfo_Remote(); bindingInfo.setServiceType(null); bindingInfo.setIedName("IED_NAME1"); bindingInfo.setLdInst("LD_INST12"); bindingInfo.setLnInst("1"); bindingInfo.setLnClass("ANCR"); bindingInfo.setPrefix("PR"); - extRef = assertDoesNotThrow(() -> lnAdapter.checkExtRefInfoCoherence(extRefInfo)); - assertEquals(extRefInfo.getBindingInfo().getIedName(), extRef.getIedName()); + + extRefInfo.setBindingInfo(bindingInfo); ExtRefSourceInfo sourceInfo = new ExtRefSourceInfo(); - sourceInfo.setSrcCBName("UNKNOWN_CB"); + sourceInfo.setSrcCBName("rpt1"); extRefInfo.setSourceInfo(sourceInfo); - assertThrows(ScdException.class, () -> lnAdapter.checkExtRefInfoCoherence(extRefInfo)); - sourceInfo.setSrcCBName("rpt1"); + //When + //Then assertDoesNotThrow(() -> lnAdapter.checkExtRefInfoCoherence(extRefInfo)); } + @Test + void should_extract_ExtRef_from_ExtRefInfo() throws Exception { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-extref-cb/scd_get_cbs_test.xml"); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1"); + LDeviceAdapter lDeviceAdapter = iAdapter.getLDeviceAdapterByLdInst("LD_INST11"); + + AbstractLNAdapter lnAdapter = AbstractLNAdapter.builder() + .withLDeviceAdapter(lDeviceAdapter) + .withLnClass(TLLN0Enum.LLN_0.value()) + .build(); + + ExtRefInfo extRefInfo = DTO.createExtRefInfo(); + extRefInfo.setSourceInfo(null); + extRefInfo.getSignalInfo().setDesc(null); + extRefInfo.getSignalInfo().setPLN(null); + extRefInfo.getSignalInfo().setPServT(null); + extRefInfo.getSignalInfo().setPDA("da11.bda111.bda112.bda113"); + extRefInfo.getSignalInfo().setPDO("Do11.sdo11"); + extRefInfo.getSignalInfo().setIntAddr("INT_ADDR11"); + + ExtRefBindingInfo bindingInfo = DTO.createExtRefBindingInfo_Remote(); + bindingInfo.setServiceType(null); + bindingInfo.setIedName("IED_NAME1"); + bindingInfo.setLdInst("LD_INST12"); + bindingInfo.setLnInst("1"); + bindingInfo.setLnClass("ANCR"); + bindingInfo.setPrefix("PR"); + + extRefInfo.setBindingInfo(bindingInfo); + + //When + TExtRef extRef = assertDoesNotThrow(() -> lnAdapter.extractExtRefFromExtRefInfo(extRefInfo)); + + //Then + assertEquals(extRefInfo.getSignalInfo().getPDO(), extRef.getPDO()); + } + @ParameterizedTest @MethodSource("provideIncompleteExtRefInfo") void should_throw_exception_when_trying_update_extRefSource_with_wrong_arguments(ExtRefInfo incompleteExtrefInfo) throws Exception { @@ -288,6 +367,7 @@ void testUpdateExtRefSource() throws Exception { //Then assertThat(extRef.getSrcCBName()).isEqualTo(extRefInfo.getSourceInfo().getSrcCBName()); assertThat(extRef.getSrcLDInst()).isEqualTo(extRefInfo.getSourceInfo().getSrcLDInst()); + assertThat(extRef.getLnClass().contains(extRefInfo.getSourceInfo().getSrcLNClass())).isTrue(); } @@ -426,4 +506,25 @@ void elementXPath() { assertThat(result).isEqualTo("LN[@lnClass=\"LN_CLASS_H\" and @inst=\"1\" and @lnType=\"LN_TYPE\"]"); } + @Test + void getControlBlocks_should_find_ControlBlock_by_name() throws Exception { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-scd-extref-cb/scd_get_cbs_test.xml"); + SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); + IEDAdapter iAdapter = sclRootAdapter.getIEDAdapterByName("IED_NAME1"); + LDeviceAdapter lDeviceAdapter = iAdapter.getLDeviceAdapterByLdInst("LD_INST12"); + + AbstractLNAdapter lnAdapter = AbstractLNAdapter.builder() + .withLDeviceAdapter(lDeviceAdapter) + .withLnClass(TLLN0Enum.LLN_0.value()) + .build(); + List tDataSets = lnAdapter.getCurrentElem().getDataSet(); + //When + var tControls = lnAdapter.getControlBlocks(tDataSets, TServiceType.GOOSE); + // var tControls = lnAdapter.getControlBlocks("dataset121", TGSEControl.class); + + //Then + assertThat(tControls).isNotEmpty() + .hasSize(1); + } } diff --git a/sct-commons/src/test/resources/scd-extref-cb/scd_get_cbs_test.xml b/sct-commons/src/test/resources/scd-extref-cb/scd_get_cbs_test.xml index 7d0850bbb..f76fa8ba8 100644 --- a/sct-commons/src/test/resources/scd-extref-cb/scd_get_cbs_test.xml +++ b/sct-commons/src/test/resources/scd-extref-cb/scd_get_cbs_test.xml @@ -29,7 +29,7 @@ - +