Skip to content

Commit

Permalink
feat(#257): manage (update and/or create) monitoring LNs LSVS and LGO…
Browse files Browse the repository at this point in the history
…S for Control Blocks GOOSE and SMV

Signed-off-by: Aliou DIAITE <[email protected]>
  • Loading branch information
AliouDIAITE committed Mar 28, 2023
1 parent 7c2bdcd commit f3161e0
Show file tree
Hide file tree
Showing 13 changed files with 1,013 additions and 191 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.apache.commons.lang3.StringUtils;
import org.lfenergy.compas.scl2007b4.model.SCL;
import org.lfenergy.compas.scl2007b4.model.TCompasICDHeader;
import org.lfenergy.compas.scl2007b4.model.TExtRef;
import org.lfenergy.compas.scl2007b4.model.TIED;
import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings;
import org.lfenergy.compas.sct.commons.dto.SclReport;
Expand All @@ -27,6 +28,7 @@
import java.util.stream.Stream;

import static org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.*;
import static org.lfenergy.compas.sct.commons.util.Utils.isExtRefFeedBySameControlBlock;

@UtilityClass
public class ExtRefService {
Expand Down Expand Up @@ -226,4 +228,23 @@ private static Optional<SclReportItem> configureControlBlockNetwork(ControlBlock
return controlBlockAdapter.configureNetwork(appIdIterator.nextLong(), macAddressIterator.next(), settings.vlanId(), settings.vlanPriority(),
settings.minTime(), settings.maxTime());
}

/**
* Remove ExtRef hich are fed by same Control Block
*
* @param tExtRefs List of ExtRef
* @return list ExtRefs without duplication
*/
public static List<TExtRef> removeDuplicatedExtRefs(List<TExtRef> tExtRefs) {
List<TExtRef> tExtRefList = new ArrayList<>();
tExtRefs.forEach(tExtRef -> {
if (tExtRefList.isEmpty())
tExtRefList.add(tExtRef);
else {
if (tExtRefList.stream().noneMatch(t -> isExtRefFeedBySameControlBlock(tExtRef, t)))
tExtRefList.add(tExtRef);
}
});
return tExtRefList;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public class SclService {

private static final String UNKNOWN_LDEVICE_S_IN_IED_S = "Unknown LDevice (%s) in IED (%s)";
private static final String INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO = "Invalid or missing attributes in ExtRef binding info";
private static final String IED_TEST = "IEDTEST";

private SclService() {
throw new IllegalStateException("SclService class");
Expand Down Expand Up @@ -609,4 +610,20 @@ public static SclReport updateDoInRef(SCL scd) {
.toList();
return new SclReport(sclRootAdapter, sclReportItems);
}

/**
* Update and/or create Monitoring LNs (LSVS and LGOS) for bound GOOSE and SMV Control Blocks
*
* @param scd SCL file for which DOs InRef should be updated with matching ExtRef information
* @return SclReport Object that contain SCL file and set of errors
*/
public static SclReport manageMonitoringLns(SCL scd) {
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
List<SclReportItem> sclReportItems = sclRootAdapter.streamIEDAdapters()
.filter(iedAdapter -> !iedAdapter.getName().contains(IED_TEST))
.map(IEDAdapter::manageMonitoringLns)
.flatMap(List::stream)
.toList();
return new SclReport(sclRootAdapter, sclReportItems);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static org.lfenergy.compas.sct.commons.scl.ExtRefService.removeDuplicatedExtRefs;

/**
* A representation of the model object
* <em><b>{@link org.lfenergy.compas.scl2007b4.model.TAccessPoint AccessPoint}</b></em>.
Expand All @@ -35,7 +37,6 @@
public class AccessPointAdapter extends SclElementAdapter<IEDAdapter, TAccessPoint> {

public static final long MAX_OCCURRENCE_NO_LIMIT_VALUE = -1L;
private static final String CLIENT_IED_NAME = "The Client IED ";

/**
* Constructor
Expand Down Expand Up @@ -219,7 +220,7 @@ public Optional<SclReportItem> checkLimitationForBoundIedFcdas(List<TExtRef> tEx
* @param sclReportItems
* @param tExtRefs
*/
record ExtRefAnalyzeRecord(List<SclReportItem> sclReportItems, List<TExtRef> tExtRefs) {
public record ExtRefAnalyzeRecord(List<SclReportItem> sclReportItems, List<TExtRef> tExtRefs) {
}

/**
Expand All @@ -229,21 +230,14 @@ record ExtRefAnalyzeRecord(List<SclReportItem> sclReportItems, List<TExtRef> tEx
*/
public ExtRefAnalyzeRecord getAllCoherentExtRefForAnalyze() {
List<SclReportItem> sclReportItems = new ArrayList<>();
List<TExtRef> tExtRefList = new ArrayList<>();
streamLDeviceAdapters().map(lDeviceAdapter -> {
List<TExtRef> extRefs = lDeviceAdapter.getLN0Adapter().getExtRefs().stream().filter(TExtRef::isSetSrcCBName).collect(Collectors.toCollection(ArrayList::new));
sclReportItems.addAll(checkExtRefWithoutServiceType(extRefs, lDeviceAdapter.getLN0Adapter().getXPath()));
extRefs.removeIf(tExtRef -> !tExtRef.isSetServiceType());
return extRefs;
}).flatMap(Collection::stream).forEach(tExtRef -> {
if (tExtRefList.isEmpty())
tExtRefList.add(tExtRef);
else {
if (tExtRefList.stream().noneMatch(t -> isExtRefFeedBySameControlBlock(tExtRef, t)))
tExtRefList.add(tExtRef);
}
});
return new ExtRefAnalyzeRecord(sclReportItems, tExtRefList);
List<TExtRef> tExtRefList = streamLDeviceAdapters().map(lDeviceAdapter -> {
List<TExtRef> extRefs = lDeviceAdapter.getLN0Adapter().getExtRefs().stream().filter(TExtRef::isSetSrcCBName).collect(Collectors.toCollection(ArrayList::new));
sclReportItems.addAll(checkExtRefWithoutServiceType(extRefs, lDeviceAdapter.getLN0Adapter().getXPath()));
extRefs.removeIf(tExtRef -> !tExtRef.isSetServiceType());
return extRefs;
}).flatMap(Collection::stream)
.toList();
return new ExtRefAnalyzeRecord(sclReportItems, removeDuplicatedExtRefs(tExtRefList));
}

/**
Expand All @@ -262,25 +256,6 @@ private List<SclReportItem> checkExtRefWithoutServiceType(List<TExtRef> tExtRefs
.toList();
}

/**
* Checks if two ExtRefs fed by same Control Block for SCL limits analyze
* Nota : this equality is only for checking limitation check
*
* @param t1 extref to compare
* @param t2 extref to compare
* @return true if the two ExtRef are fed by same Control Block, otherwise false
*/
private 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())
&& t1.getServiceType().equals(t2.getServiceType());
}

/**
* Checks Control Blocks (Report, Goose, SMV) number limitation for bound IED
*
Expand All @@ -300,7 +275,6 @@ public List<SclReportItem> checkLimitationForBoundIEDControls(List<TExtRef> tExt
* Checks Control Block number limitation for bound IED
*
* @param tExtRefs list of ExtRefs referenced same ied
* @param msg message to display hen error occured
* @param servicesConfigEnum type of Control Block for which check is done
* @return Optional of encountered error or empty
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,12 @@
import org.lfenergy.compas.sct.commons.util.ServicesConfigEnum;
import org.lfenergy.compas.sct.commons.util.Utils;

import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Stream;

import static org.lfenergy.compas.sct.commons.scl.ExtRefService.removeDuplicatedExtRefs;

/**
* A representation of the model object
* <em><b>{@link org.lfenergy.compas.scl2007b4.model.TIED IED}</b></em>.
Expand Down Expand Up @@ -62,6 +61,9 @@
public class IEDAdapter extends SclElementAdapter<SclRootAdapter, TIED> {

private static final String MESSAGE_LDEVICE_INST_NOT_FOUND = "LDevice.inst '%s' not found in IED '%s'";
private static final String DO_GOCBREF = "GoCBRef";
private static final String DO_SVCBREF = "SvCBRef";
private static final String LDSUIED = "LDSUIED";

/**
* Constructor
Expand Down Expand Up @@ -91,10 +93,10 @@ public IEDAdapter(SclRootAdapter parentAdapter, TIED currentElem) {
public IEDAdapter(SclRootAdapter parentAdapter, String iedName) throws ScdException {
super(parentAdapter);
TIED ied = parentAdapter.getCurrentElem().getIED()
.stream()
.filter(tied -> tied.getName().equals(iedName))
.findFirst()
.orElseThrow(() -> new ScdException("Unknown IED name :" + iedName));
.stream()
.filter(tied -> tied.getName().equals(iedName))
.findFirst()
.orElseThrow(() -> new ScdException("Unknown IED name :" + iedName));
setCurrentElem(ied);
}

Expand Down Expand Up @@ -326,47 +328,50 @@ public Optional<TCompasBay> getPrivateCompasBay() {

/**
* Checks if Controls, DataSets and FCDAs of IED respect config limitation
*
* @return empty list if all IED respect limits, otherwise list of errors
*/
public List<SclReportItem> checkDataGroupCoherence() {
return streamAccessPointAdapters()
.flatMap(accessPointAdapter ->
Stream.concat(
accessPointAdapter.checkFCDALimitations().stream(),
Stream.of(
accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.DATASET),
accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.REPORT),
accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.GSE),
accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.SMV))
.flatMap(Optional::stream)
accessPointAdapter.checkFCDALimitations().stream(),
Stream.of(
accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.DATASET),
accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.REPORT),
accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.GSE),
accessPointAdapter.checkControlsLimitation(ServicesConfigEnum.SMV))
.flatMap(Optional::stream)
)
)
.toList();
}

/**
* Checks if Controls and FCDAs of source IEDs respect config limitation
*
* @return empty list if all IED respect limits, otherwise list of errors
*/
public List<SclReportItem> checkBindingDataGroupCoherence() {
return streamAccessPointAdapters()
return streamAccessPointAdapters()
.flatMap(accessPointAdapter -> {
AccessPointAdapter.ExtRefAnalyzeRecord extRefAnalyzeRecord = accessPointAdapter.getAllCoherentExtRefForAnalyze();
return Stream.of(
extRefAnalyzeRecord.sclReportItems().stream(),
accessPointAdapter.checkLimitationForBoundIedFcdas(extRefAnalyzeRecord.tExtRefs()).stream(),
accessPointAdapter.checkLimitationForBoundIEDControls(extRefAnalyzeRecord.tExtRefs()).stream())
.flatMap(Function.identity());
extRefAnalyzeRecord.sclReportItems().stream(),
accessPointAdapter.checkLimitationForBoundIedFcdas(extRefAnalyzeRecord.tExtRefs()).stream(),
accessPointAdapter.checkLimitationForBoundIEDControls(extRefAnalyzeRecord.tExtRefs()).stream())
.flatMap(Function.identity());
}).toList();
}

private Stream<AccessPointAdapter> streamAccessPointAdapters() {
return currentElem.getAccessPoint().stream()
.map(tAccessPoint -> new AccessPointAdapter(this, tAccessPoint));
.map(tAccessPoint -> new AccessPointAdapter(this, tAccessPoint));
}

/**
* Get value of private type COMPAS-ICDHeader
*
* @return COMPAS-ICDHeader private value if present, else empty Optional
*/
public Optional<TCompasICDHeader> getCompasICDHeader() {
Expand All @@ -375,10 +380,42 @@ public Optional<TCompasICDHeader> getCompasICDHeader() {

/**
* Get value of private type COMPAS-SystemVersion
*
* @return COMPAS-SystemVersion private value if present, else empty Optional
*/
public Optional<TCompasSystemVersion> getCompasSystemVersion() {
return PrivateService.extractCompasPrivate(currentElem, TCompasSystemVersion.class);
}

/**
* Update and/or create Monitoring LNs (LSVS and LGOS) into LDSUIED for each bound ExtRef of each LDevice
*
* @return a list of SclReport Objects that contains errors
*/
public List<SclReportItem> manageMonitoringLns() {
Optional<LDeviceAdapter> optionalLDeviceAdapter = findLDeviceAdapterByLdInst(LDSUIED);
if (optionalLDeviceAdapter.isPresent()) {
LDeviceAdapter lDeviceAdapter = optionalLDeviceAdapter.get();
List<SclReportItem> sclReportItems = new ArrayList<>();
sclReportItems.addAll(lDeviceAdapter.manageMonitoringLns(retrieveAllExtRefForServiceType(TServiceType.GOOSE), DO_GOCBREF, TSystemLNGroupEnum.LGOS));
sclReportItems.addAll(lDeviceAdapter.manageMonitoringLns(retrieveAllExtRefForServiceType(TServiceType.SMV), DO_SVCBREF, TSystemLNGroupEnum.LSVS));
return sclReportItems;
} else {
return Collections.emptyList();
}
}

private List<TExtRef> retrieveAllExtRefForServiceType(TServiceType tServiceType) {
List<TExtRef> tGseExtRefs = streamLDeviceAdapters()
.map(LDeviceAdapter::getLN0Adapter)
.map(LN0Adapter::getExtRefs)
.flatMap(List::stream)
.filter(tExtRef -> tExtRef.isSetServiceType() && tExtRef.isSetSrcCBName() &&
tServiceType.equals(tExtRef.getServiceType()))
.toList();

return removeDuplicatedExtRefs(tGseExtRefs);
}


}
Loading

0 comments on commit f3161e0

Please sign in to comment.