Skip to content

Commit

Permalink
Merge pull request #381 from com-pas/develop
Browse files Browse the repository at this point in the history
Update Main
  • Loading branch information
samirromdhani authored Feb 28, 2024
2 parents ebd4fdb + 702a8d8 commit 0917cb5
Show file tree
Hide file tree
Showing 25 changed files with 1,247 additions and 176 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@
<sonar.coverage.exclusions>sct-coverage/**</sonar.coverage.exclusions>
<aggregate.report.dir>../sct-coverage/target/site/jacoco-aggregate/jacoco.xml</aggregate.report.dir>
<sonar.coverage.jacoco.xmlReportPaths>${basedir}/${aggregate.report.dir}</sonar.coverage.jacoco.xmlReportPaths>
<compas-core.version>0.18.0</compas-core.version>
<compas-core.version>0.19.0</compas-core.version>
<compas-scl-xsd.version>0.0.4</compas-scl-xsd.version>
<maven.plugin.javadoc>3.4.1</maven.plugin.javadoc>
<maven-source-plugin.version>3.2.1</maven-source-plugin.version>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
import org.lfenergy.compas.sct.commons.api.SclEditor;
import org.lfenergy.compas.sct.commons.api.SubstationEditor;
import org.lfenergy.compas.sct.commons.dto.HeaderDTO;
import org.lfenergy.compas.sct.commons.dto.SubNetworkDTO;
import org.lfenergy.compas.sct.commons.dto.SubNetworkTypeDTO;
import org.lfenergy.compas.sct.commons.exception.ScdException;

import java.util.*;
Expand All @@ -33,14 +31,6 @@ public class SclAutomationService {
private final SubstationEditor substationEditor;
private final ControlBlockEditor controlBlockEditor;

/**
* Possible Subnetwork and ConnectedAP names which should be used in generated SCD in order a have global coherence
* Configuration based on used framework can be used to externalize this datas
*/
public static final List<SubNetworkTypeDTO> SUB_NETWORK_TYPES = List.of(
new SubNetworkTypeDTO("RSPACE_PROCESS_NETWORK", SubNetworkDTO.SubnetworkType.MMS.toString(), List.of("PROCESS_AP", "TOTO_AP_GE")),
new SubNetworkTypeDTO("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString(), List.of("ADMIN_AP", "TATA_AP_EFFACEC")));

/**
* Create an SCD file from specified parameters, it calls all functions defined in the process one by one, every step
* return an SCD file which will be used by the next step.
Expand All @@ -57,7 +47,7 @@ public SCL createSCD(@NonNull SCL ssd, @NonNull HeaderDTO headerDTO, List<SCL> s
sclEditor.addHistoryItem(scd, hItem.getWho(), hItem.getWhat(), hItem.getWhy());
}
substationEditor.addSubstation(scd, ssd);
sclEditor.importSTDElementsInSCD(scd, stds, SUB_NETWORK_TYPES);
sclEditor.importSTDElementsInSCD(scd, stds);
controlBlockEditor.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scd);
return scd;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ void createSCD_without_headerHistory_should_return_generatedSCD() throws Invocat
verify(sclEditor, times(1)).initScl(headerDTO.getId(), headerDTO.getVersion(), headerDTO.getRevision());
verify(sclEditor, times(0)).addHistoryItem(any(SCL.class), anyString(), anyString(), anyString());
verify(substationEditor, times(1)).addSubstation(any(SCL.class), any(SCL.class));
verify(sclEditor, times(1)).importSTDElementsInSCD(any(SCL.class), anyList(), anyList());
verify(sclEditor, times(1)).importSTDElementsInSCD(any(SCL.class), anyList());
verify(controlBlockEditor, times(1)).removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(any(SCL.class));
}

Expand Down Expand Up @@ -112,7 +112,7 @@ void createSCD_with_headerHistory_should_return_generatedSCD() throws Invocation
verify(sclEditor, times(1)).initScl(headerDTO.getId(), headerDTO.getVersion(), headerDTO.getRevision());
verify(sclEditor, times(1)).addHistoryItem(any(SCL.class), eq(historyItem.getWho()), eq(historyItem.getWhat()), eq(historyItem.getWhy()));
verify(substationEditor, times(1)).addSubstation(any(SCL.class), any(SCL.class));
verify(sclEditor, times(1)).importSTDElementsInSCD(any(SCL.class), anyList(), anyList());
verify(sclEditor, times(1)).importSTDElementsInSCD(any(SCL.class), anyList());
verify(controlBlockEditor, times(1)).removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(any(SCL.class));
}

Expand Down Expand Up @@ -167,7 +167,7 @@ void createSCD_when_sclEditor_importSTDElementsInSCD_Fail_should_throw_exception
doNothing().when(sclEditor).addHistoryItem(any(SCL.class), any(), any(), any());
doNothing().when(substationEditor).addSubstation(any(SCL.class), any(SCL.class));
doThrow(new ScdException("importSTDElementsInSCD fail"))
.when(sclEditor).importSTDElementsInSCD(any(SCL.class), anyList(), anyList());
.when(sclEditor).importSTDElementsInSCD(any(SCL.class), anyList());
// When Then
assertThatThrownBy(() -> sclAutomationService.createSCD(ssd, headerDTO, List.of(std)))
.isInstanceOf(ScdException.class)
Expand All @@ -183,7 +183,7 @@ void createSCD_when_controlBlockEditor_removeAllControlBlocksAndDatasetsAndExtRe
when(sclEditor.initScl(any(UUID.class), anyString(), anyString())).thenReturn((SCL) BeanUtils.cloneBean(scl));
doNothing().when(sclEditor).addHistoryItem(any(SCL.class), any(), any(), any());
doNothing().when(substationEditor).addSubstation(any(SCL.class), any(SCL.class));
doNothing().when(sclEditor).importSTDElementsInSCD(any(SCL.class), anyList(), anyList());
doNothing().when(sclEditor).importSTDElementsInSCD(any(SCL.class), anyList());
doThrow(new ScdException("removeAllControlBlocksAndDatasetsAndExtRefSrcBindings fail"))
.when(controlBlockEditor).removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(any(SCL.class));
// When Then
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// SPDX-FileCopyrightText: 2024 RTE FRANCE
//
// SPDX-License-Identifier: Apache-2.0

package org.lfenergy.compas.sct.commons;

import org.lfenergy.compas.scl2007b4.model.*;

import static org.lfenergy.compas.sct.commons.util.CommonConstants.MOD_DO_NAME;
import static org.lfenergy.compas.sct.commons.util.CommonConstants.STVAL_DA_NAME;

public class DataTypeTemplatesService {

final LnodeTypeService lnodeTypeService = new LnodeTypeService();
final DoTypeService doTypeService = new DoTypeService();
final DoService doService = new DoService();

/**
* verify if DO(name=Mod)/DA(name=stVal) exists in DataTypeTemplate
* @param dtt TDataTypeTemplates where Data object and Data attribute exists
* @param lNodeTypeId LNode Type ID where Data object exists
* DataTypeTemplates model :
* <DataTypeTemplates>
* <LNodeType lnClass="LNodeTypeClass" id="LNodeTypeID">
* <DO name="Mod" type="DOModTypeID" ../>
* </LNodeType>
* ...
* <DOType cdc="DOTypeCDC" id="DOModTypeID">
* <DA name="stVal" ../>
* </DOType>
* </DataTypeTemplates>
* @return true if the Data Object (Mod) and Data attribute (stVal) present, false otherwise
*/
public boolean isDoModAndDaStValExist(TDataTypeTemplates dtt, String lNodeTypeId) {
return lnodeTypeService.findLnodeType(dtt, lNodeType -> lNodeTypeId.equals(lNodeType.getId()))
.map(lNodeType -> doService.findDo(lNodeType, tdo -> MOD_DO_NAME.equals(tdo.getName()))
.map(tdo -> doTypeService.findDoType(dtt, doType -> tdo.getType().equals(doType.getId()))
.map(doType -> doType.getSDOOrDA().stream()
.filter(sdoOrDa -> sdoOrDa.getClass().equals(TDA.class))
.map(TDA.class::cast)
.anyMatch(tda -> STVAL_DA_NAME.equals(tda.getName())))
.orElse(false))
.orElse(false))
.orElse(false);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ public class ExtRefEditorService implements ExtRefEditor {
"7", "THT"
);

private final IedService iedService;
private final LdeviceService ldeviceService;
private final ExtRefService extRefService;
private final DataTypeTemplatesService dataTypeTemplatesService;

/**
* Provides valid IED sources according to EPF configuration.<br/>
Expand Down Expand Up @@ -78,6 +80,37 @@ private static List<TIED> getIedSources(SclRootAdapter sclRootAdapter, TCompasBa
.toList();
}

/**
* Provides a list of ExtRef and associated Bay <br/>
* - The location of ExtRef should be in LDevice (inst=LDEPF) <br/>
* - ExtRef that lacks Bay or ICDHeader Private is not returned <br/>
*
* @param sclReportItems List of SclReportItem
* @return list of ExtRef and associated Bay
*/
private List<ExtRefInfo.ExtRefWithBayReference> getExtRefWithBayReferenceInLDEPF(TDataTypeTemplates dataTypeTemplates, TIED tied, final TLDevice tlDevice, final List<SclReportItem> sclReportItems) {
List<ExtRefInfo.ExtRefWithBayReference> extRefBayReferenceList = new ArrayList<>();
String lDevicePath = "SCL/IED[@name=\""+ tied.getName() + "\"]/AccessPoint/Server/LDevice[@inst=\"" + tlDevice.getInst() + "\"]";
Optional<TCompasBay> tCompasBay = PrivateUtils.extractCompasPrivate(tied, TCompasBay.class);
if (tCompasBay.isEmpty()) {
sclReportItems.add(SclReportItem.error(lDevicePath, "The IED has no Private Bay"));
if (PrivateUtils.extractCompasPrivate(tied, TCompasICDHeader.class).isEmpty()) {
sclReportItems.add(SclReportItem.error(lDevicePath, "The IED has no Private compas:ICDHeader"));
}
return Collections.emptyList();
}

if (dataTypeTemplatesService.isDoModAndDaStValExist(dataTypeTemplates, tlDevice.getLN0().getLnType())) {
extRefBayReferenceList.addAll(tlDevice.getLN0()
.getInputs()
.getExtRef().stream()
.map(extRef -> new ExtRefInfo.ExtRefWithBayReference(tied.getName(), tCompasBay.get(), extRef)).toList());
} else {
sclReportItems.add(SclReportItem.error(lDevicePath, "DO@name=Mod/DA@name=stVal not found in DataTypeTemplate"));
}
return extRefBayReferenceList;
}

/**
* Verify if an Extref matches the EPF Channel or not.
*
Expand Down Expand Up @@ -266,29 +299,27 @@ public List<SclReportItem> updateAllExtRefIedNames(SCL scd) {
@Override
public List<SclReportItem> manageBindingForLDEPF(SCL scd, EPF epf) {
List<SclReportItem> sclReportItems = new ArrayList<>();
if (!epf.isSetChannels()) return sclReportItems;
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
sclRootAdapter.streamIEDAdapters()
.filter(iedAdapter -> !iedAdapter.getName().contains("TEST"))
.map(iedAdapter -> iedAdapter.findLDeviceAdapterByLdInst(LDEVICE_LDEPF))
.flatMap(Optional::stream)
.forEach(lDeviceAdapter -> lDeviceAdapter.getExtRefBayReferenceForActifLDEPF(sclReportItems)
.forEach(extRefBayRef -> epf.getChannels().getChannel().stream().filter(tChannel -> doesExtRefMatchLDEPFChannel(extRefBayRef.extRef(), tChannel))
.findFirst().ifPresent(channel -> {
List<TIED> iedSources = getIedSources(sclRootAdapter, extRefBayRef.compasBay(), channel);
if (iedSources.size() == 1) {
updateLDEPFExtRefBinding(extRefBayRef.extRef(), iedSources.get(0), channel);
sclReportItems.addAll(updateLDEPFDos(lDeviceAdapter, extRefBayRef.extRef(), channel));
} else {
if (iedSources.size() > 1) {
sclReportItems.add(SclReportItem.warning(null, "There is more than one IED source to bind the signal " +
"/IED@name=" + extRefBayRef.iedName() + "/LDevice@inst=LDEPF/LN0" +
"/ExtRef@desc=" + extRefBayRef.extRef().getDesc()));
}
// If the source IED is not found, there will be no update or report message.
}
}))
);
if (!epf.isSetChannels()) return sclReportItems;
iedService.getFilteredIeds(scd, ied -> !ied.getName().contains("TEST"))
.forEach(tied -> ldeviceService.findLdevice(tied, tlDevice -> LDEVICE_LDEPF.equals(tlDevice.getInst()))
.ifPresent(tlDevice -> getExtRefWithBayReferenceInLDEPF(scd.getDataTypeTemplates(), tied, tlDevice, sclReportItems)
.forEach(extRefBayRef -> epf.getChannels().getChannel().stream().filter(tChannel -> doesExtRefMatchLDEPFChannel(extRefBayRef.extRef(), tChannel))
.findFirst().ifPresent(channel -> {
List<TIED> iedSources = getIedSources(sclRootAdapter, extRefBayRef.compasBay(), channel);
if (iedSources.size() == 1) {
updateLDEPFExtRefBinding(extRefBayRef.extRef(), iedSources.get(0), channel);
LDeviceAdapter lDeviceAdapter = new LDeviceAdapter(new IEDAdapter(sclRootAdapter, tied.getName()), tlDevice);
sclReportItems.addAll(updateLDEPFDos(lDeviceAdapter, extRefBayRef.extRef(), channel));
} else {
if (iedSources.size() > 1) {
sclReportItems.add(SclReportItem.warning(null, "There is more than one IED source to bind the signal " +
"/IED@name=" + extRefBayRef.iedName() + "/LDevice@inst=LDEPF/LN0" +
"/ExtRef@desc=" + extRefBayRef.extRef().getDesc()));
}
// If the source IED is not found, there will be no update or report message.
}
}))));
return sclReportItems;
}

Expand Down Expand Up @@ -404,7 +435,6 @@ private String computeDaiValue(AbstractLNAdapter<?> lnAdapter, TExtRef extRef, S

@Override
public void debindCompasFlowsAndExtRefsBasedOnVoltageLevel(SCL scd) {
LdeviceService ldeviceService = new LdeviceService();
scd.getSubstation()
.stream()
.flatMap(tSubstation -> tSubstation.getVoltageLevel().stream())
Expand All @@ -420,14 +450,11 @@ public void debindCompasFlowsAndExtRefsBasedOnVoltageLevel(SCL scd) {
.filter(TCompasFlow::isSetFlowSourceVoltageLevel)
.filter(TCompasFlow::isSetExtRefiedName)
.forEach(tCompasFlow -> {
if (flowSource == null) {
//debind all compas flow
extRefService.clearCompasFlowBinding(tCompasFlow);
} else if (!tCompasFlow.getFlowSourceVoltageLevel().equals(flowSource)) {
//debind extRef
if (!tCompasFlow.getFlowSourceVoltageLevel().equals(flowSource)) {
//debind extRefs correspondind to compas flow
extRefService.getMatchingExtRefs(tlDevice, tCompasFlow)
.forEach(extRefService::clearExtRefBinding);
//debind compas flow
//debind all compas flow
extRefService.clearCompasFlowBinding(tCompasFlow);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,10 +81,8 @@ public void addIED(SCL scd, String iedName, SCL icd) throws ScdException {

@Override
public void addSubnetworks(SCL scd, List<SubNetworkDTO> subNetworks, SCL icd) throws ScdException {
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
CommunicationAdapter communicationAdapter;
if (!subNetworks.isEmpty()) {
communicationAdapter = sclRootAdapter.getCommunicationAdapter(true);
CommunicationAdapter communicationAdapter = new SclRootAdapter(scd).getCommunicationAdapter(true);
for (SubNetworkDTO subNetworkDTO : subNetworks) {
String snName = subNetworkDTO.getName();
String snType = subNetworkDTO.getType();
Expand All @@ -103,6 +101,23 @@ public void addSubnetworks(SCL scd, List<SubNetworkDTO> subNetworks, SCL icd) th
}
}

@Override
public void addSubnetworks(SCL scd, SCL icd, String iedName) throws ScdException {
Optional.ofNullable(icd.getCommunication()).ifPresent(tCommunication ->
tCommunication.getSubNetwork().forEach(icdSubNetwork ->
icdSubNetwork.getConnectedAP().forEach(icdConnectedAP -> {
// init Communication if not exist
CommunicationAdapter communicationAdapter = new SclRootAdapter(scd).getCommunicationAdapter(true);
// add SubNetwork if not exist, add ConnectedAP to SubNetwork if not exist
SubNetworkAdapter subNetworkAdapter = communicationAdapter
.addSubnetwork(icdSubNetwork.getName(), icdSubNetwork.getType(), iedName, icdConnectedAP.getApName());
// copy Address And PhysConn From Icd to Scd
subNetworkAdapter.getConnectedAPAdapter(iedName, icdConnectedAP.getApName())
.copyAddressAndPhysConnFromIcd(icd);
})
));
}

@Override
public void updateDAI(SCL scd, String iedName, String ldInst, DataAttributeRef dataAttributeRef) throws ScdException {
long startTime = System.nanoTime();
Expand Down Expand Up @@ -139,7 +154,7 @@ public void updateDAI(SCL scd, String iedName, String ldInst, DataAttributeRef d
}

@Override
public void importSTDElementsInSCD(SCL scd, List<SCL> stds, List<SubNetworkTypeDTO> subNetworkTypes) throws ScdException {
public void importSTDElementsInSCD(SCL scd, List<SCL> stds) throws ScdException {

//Check SCD and STD compatibilities
Map<String, PrivateLinkedToStds> mapICDSystemVersionUuidAndSTDFile = PrivateUtils.createMapICDSystemVersionUuidAndSTDFile(stds);
Expand Down Expand Up @@ -167,9 +182,7 @@ public void importSTDElementsInSCD(SCL scd, List<SCL> stds, List<SubNetworkTypeD
scdRootAdapter.addIED(std, iedName);

//import connectedAP and rename ConnectedAP/@iedName
TCommunication communication = stdRootAdapter.getCurrentElem().getCommunication();
List<SubNetworkDTO> subNetworkDTOSet = SubNetworkDTO.createDefaultSubnetwork(iedName, communication, subNetworkTypes);
addSubnetworks(scdRootAdapter.getCurrentElem(), subNetworkDTOSet, std);
addSubnetworks(scdRootAdapter.getCurrentElem(), std, iedName);
}
});
}
Expand Down
Loading

0 comments on commit 0917cb5

Please sign in to comment.