Skip to content

Commit

Permalink
Merge pull request #364 from com-pas/feat/351-rsr-894-update-compasfl…
Browse files Browse the repository at this point in the history
…ow-and-extref-prebindings

feat(#351): RSR-894 Update Compasflow and extref prebindings based on Lnode
  • Loading branch information
massifben authored Dec 15, 2023
2 parents 752dff8 + ca976d0 commit 1724e0e
Show file tree
Hide file tree
Showing 11 changed files with 420 additions and 202 deletions.
Original file line number Diff line number Diff line change
@@ -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.*;
Expand All @@ -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 {
Expand All @@ -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<TExtRef> filterDuplicatedExtRefs(List<TExtRef> tExtRefs) {
List<TExtRef> 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.<br/>
Expand Down Expand Up @@ -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 -> {
Expand All @@ -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<TopoKey, TBay> 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) {
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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);

}
Original file line number Diff line number Diff line change
Expand Up @@ -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<TExtRef> getExtRefs(TInputs inputs) {
if (inputs == null || !inputs.isSetExtRef()) {
return Stream.empty();
}
return inputs.getExtRef().stream();
public Stream<TExtRef> 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<TCompasFlow> getCompasFlows(TLDevice tlDevice) {
return getInputs(tlDevice).stream()
.flatMap(tInputs -> PrivateUtils.extractCompasPrivates(tlDevice.getLN0().getInputs(), TCompasFlow.class));
}

/**
Expand All @@ -43,12 +55,12 @@ public Stream<TCompasFlow> 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<TExtRef> getMatchingExtRef(TInputs inputs, TCompasFlow tCompasFlow) {
return getExtRefs(inputs)
public Stream<TExtRef> getMatchingExtRefs(TLDevice tlDevice, TCompasFlow tCompasFlow) {
return getExtRefs(tlDevice)
.filter(tExtRef -> isMatchingExtRef(tCompasFlow, tExtRef));
}

Expand Down Expand Up @@ -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<TExtRef> filterDuplicatedExtRefs(List<TExtRef> tExtRefs) {
List<TExtRef> filteredList = new ArrayList<>();
tExtRefs.forEach(tExtRef -> {
if (filteredList.stream().noneMatch(t -> isExtRefFeedBySameControlBlock(tExtRef, t)))
filteredList.add(tExtRef);
});
return filteredList;
}

private Optional<TInputs> getInputs(TLDevice tlDevice){
if (!tlDevice.isSetLN0() || !tlDevice.getLN0().isSetInputs()) {
return Optional.empty();
}
return Optional.of(tlDevice.getLN0().getInputs());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
* <em><b>{@link org.lfenergy.compas.scl2007b4.model.TAccessPoint AccessPoint}</b></em>.
Expand Down Expand Up @@ -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));
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -104,13 +103,13 @@ public List<SclReportItem> updateAllExtRefIedNames(Map<String, IEDAdapter> 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();
}
};
Expand Down Expand Up @@ -209,7 +208,7 @@ public List<SclReportItem> updateAllSourceDataSetsAndControlBlocks(Set<FcdaForDa
if (StringUtils.isBlank(currentBayUuid)) {
return List.of(getIedAdapter().buildFatalReportItem(MESSAGE_IED_MISSING_COMPAS_BAY_UUID));
}
return extRefService.getExtRefs(currentElem)
return currentElem.getExtRef().stream()
.filter(this::areBindingAttributesPresent)
.filter(this::isExternalBound)
.filter(this::matchingCompasFlowIsActiveOrUntested)
Expand Down Expand Up @@ -374,7 +373,7 @@ private SclRootAdapter getSclRootAdapter() {
* @return list ExtRefs without duplication
*/
public List<TExtRef> filterDuplicatedExtRefs() {
return ExtRefEditorService.filterDuplicatedExtRefs(extRefService.getExtRefs(currentElem).toList());
return new ExtRefService().filterDuplicatedExtRefs(currentElem.getExtRef());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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.*;
Expand Down Expand Up @@ -371,23 +366,4 @@ public static <T> T copySclElement(T object, Class<T> 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());
}

}
Loading

0 comments on commit 1724e0e

Please sign in to comment.