Skip to content

Commit

Permalink
remove restriction on AccessPoint name
Browse files Browse the repository at this point in the history
  • Loading branch information
samirromdhani committed Jan 15, 2024
1 parent aea5dd9 commit ba860cf
Show file tree
Hide file tree
Showing 8 changed files with 158 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,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
Expand Up @@ -103,6 +103,57 @@ 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 -> {
// add SubNetwork if not exist
if(scd.getCommunication() == null) {
scd.setCommunication(new TCommunication());
}
TSubNetwork tSubNetwork = scd.getCommunication().getSubNetwork()
.stream()
.filter(subNetwork -> subNetwork.getName().equals(icdSubNetwork.getName()))
.findFirst()
.orElseGet(() -> {
if (scd.getIED().stream().filter(ied -> Objects.equals(ied.getName(), iedName))
.flatMap(tied -> tied.getAccessPoint().stream())
.noneMatch(tAccessPoint -> tAccessPoint.getName().equals(icdConnectedAP.getApName()))) {
throw new ScdException("Unknown AccessPoint :" + icdConnectedAP.getApName() + " in IED :" + iedName);
}
TSubNetwork newSubNetwork = new TSubNetwork();
newSubNetwork.setName(icdSubNetwork.getName());
newSubNetwork.setType(icdSubNetwork.getType());
scd.getCommunication().getSubNetwork().add(newSubNetwork);
return newSubNetwork;
});
// add ConnectedAP to SubNetwork if not exist
String apName = icdConnectedAP.getApName();
TConnectedAP tConnectedAP = tSubNetwork.getConnectedAP().stream()
.filter(connectedAP -> Objects.equals(connectedAP.getIedName(), iedName)
&& Objects.equals(connectedAP.getApName(), apName))
.findFirst()
.orElseGet(() -> {
TConnectedAP newConnectedAP = new TConnectedAP();
newConnectedAP.setIedName(iedName);
newConnectedAP.setApName(apName);
tSubNetwork.getConnectedAP().add(newConnectedAP);
return newConnectedAP;
});
//copy Address And PhysConn From Icd to Scd
icd.getCommunication().getSubNetwork().stream()
.flatMap(subNetwork -> subNetwork.getConnectedAP().stream())
.filter(connectedAP -> connectedAP.getApName().equals(tConnectedAP.getApName()))
.findFirst()
.ifPresent(connectedAP -> {
Optional.ofNullable(connectedAP.getAddress()).ifPresent(tConnectedAP::setAddress);
tConnectedAP.getPhysConn().addAll(connectedAP.getPhysConn());
});
}))
);
}

@Override
public void updateDAI(SCL scd, String iedName, String ldInst, DataAttributeRef dataAttributeRef) throws ScdException {
long startTime = System.nanoTime();
Expand Down Expand Up @@ -139,7 +190,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 +218,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
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ public interface SclEditor {
*/
void addSubnetworks(SCL scd, List<SubNetworkDTO> subNetworks, SCL icd) throws ScdException;

/**
* Add or update SubNetworks in SCL file from ICD file
* @param scd SCL file in which SubNetworks should be added
* @param icd ICD file from which SubNetworks functional data are copied from
*/
void addSubnetworks(SCL scd, SCL icd, String iedName) throws ScdException;

/**
* Updates DAI based on given data in <em>dataAttributeRef</em>
*
Expand Down Expand Up @@ -118,7 +125,6 @@ public interface SclEditor {
*
* @param scd SCL object in which content of STD files are imported
* @param stds list of STD files contenting datas to import into SCD
* @param subNetworkTypes couple of Subnetwork name and possible corresponding ConnectedAP names
* @throws ScdException throws when inconsistency between Substation of SCL content and gien STD files as :
* <ul>
* <li>ICD_SYSTEM_VERSION_UUID in IED/Private of STD is not present in COMPAS-ICDHeader in Substation/../LNode of SCL</li>
Expand All @@ -128,7 +134,7 @@ public interface SclEditor {
* <li>COMPAS_ICDHEADER in Substation/../LNode of SCL not found in IED/Private of STD</li>
* </ul>
*/
void importSTDElementsInSCD(SCL scd, List<SCL> stds, List<SubNetworkTypeDTO> subNetworkTypes) throws ScdException;
void importSTDElementsInSCD(SCL scd, List<SCL> stds) throws ScdException;

/**
* Activate used LDevice and Deactivate unused LDevice in {@link TLNode <em><b>TLNode </b></em>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
import org.lfenergy.compas.sct.commons.scl.ln.LNAdapter;
import org.lfenergy.compas.sct.commons.testhelpers.MarshallerWrapper;
import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;
import org.lfenergy.compas.sct.commons.scl.ied.*;
import org.lfenergy.compas.sct.commons.testhelpers.*;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;

Expand Down Expand Up @@ -174,6 +172,55 @@ void addSubnetworks_whenNoCommunicationTagInIcd_should_not_add_subnetwork() {
assertThat(marshalledScd).doesNotContain("<Communication");
}

@Test
void addSubnetworks_shouldNotUpdateScd_When_NoCommunicationInICDExist() {
//Givens
SCL scd = SclTestMarshaller.getSCLFromFile("/scl_update_communication/scl_without_communication.xml");
SCL icd = SclTestMarshaller.getSCLFromFile("/scl_update_communication/scl_without_communication.xml");
assertThat(scd.getCommunication()).isNull();
//When
sclService.addSubnetworks(scd, icd, "IED_NAME1");
//Then
String marshalledScd = assertIsMarshallable(scd);
assertThat(scd.getCommunication()).isNull();
assertThat(marshalledScd).doesNotContain("<Communication");
}

@Test
void addSubnetworks_shouldAddSubNetwork_And_ConnectedAp_And_copyAddressAndPhysConnFromIcd() {
//Givens
SCL scd = SclTestMarshaller.getSCLFromFile("/scl_update_communication/scl_without_communication.xml");
SCL icd = SclTestMarshaller.getSCLFromFile("/scl_update_communication/scl_with_communication.xml");
assertThat(scd.getCommunication()).isNull();
//When
sclService.addSubnetworks(scd, icd, "IED_NAME1");
//Then
String marshalledScd = assertIsMarshallable(scd);
assertThat(scd.getCommunication()).isNotNull();
assertThat(marshalledScd).contains("<Communication");
// assertion succeeds as subNetwork.connectedAP.address and subNetwork.connectedAP.physConn fields are compared.
assertThat(scd.getCommunication())
.usingRecursiveComparison()
.comparingOnlyFields("subNetwork.connectedAP.address", "subNetwork.connectedAP.physConn")
.isEqualTo(icd.getCommunication());
}

@Test
void addSubnetworks_shouldDoNothing_When_SubNetworkAlreadyExist() {
//Givens
SCL scdBefore = SclTestMarshaller.getSCLFromFile("/scl_update_communication/scl_with_communication.xml");
SCL scd = SclTestMarshaller.getSCLFromFile("/scl_update_communication/scl_with_communication.xml");
SCL icd = SclTestMarshaller.getSCLFromFile("/scl_update_communication/scl_with_communication.xml");
icd.getCommunication().getSubNetwork().get(0).getConnectedAP().get(0).getPhysConn().clear();
icd.getCommunication().getSubNetwork().get(0).getConnectedAP().get(0).setAddress(null);
icd.getCommunication().getSubNetwork().get(0).getConnectedAP().get(0).unsetGSE();
//When
sclService.addSubnetworks(scd, icd, "IED_NAME1");
//Then
String marshalledScd = assertIsMarshallable(scd);
assertThat(marshalledScd).contains("<Communication");
}

@Test
void testInitScl_With_headerId_shouldNotThrowError() {
//Given
Expand Down Expand Up @@ -240,7 +287,7 @@ void testImportSTDElementsInSCD_whenCalledWithOneSTD_shouldNotThrowException() {
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml");
SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
//When Then
assertThatCode(() -> sclService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES))
assertThatCode(() -> sclService.importSTDElementsInSCD(scd, List.of(std)))
.doesNotThrowAnyException();
assertThat(scd.getIED()).hasSize(1);
assertThat(scd.getDataTypeTemplates()).hasNoNullFieldsOrProperties();
Expand All @@ -256,7 +303,7 @@ void importSTDElementsInSCD_whenCalledWithMultipleSTD_shouldNotThrowException()
SCL std1 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_SITESITE1SCU1.xml");
SCL std2 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_SITESITE1SCU2.xml");
//When Then
assertThatCode(() -> sclService.importSTDElementsInSCD(scd, List.of(std0, std1, std2), DTO.SUB_NETWORK_TYPES))
assertThatCode(() -> sclService.importSTDElementsInSCD(scd, List.of(std0, std1, std2)))
.doesNotThrowAnyException();
assertThat(scd.getIED()).hasSize(3);
assertThat(scd.getDataTypeTemplates()).hasNoNullFieldsOrProperties();
Expand All @@ -274,7 +321,7 @@ void importSTDElementsInSCD_whenManySTDMatchCompasICDHeader_shouldThrowException
SCL std2 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
List<SCL> stds = List.of(std1, std2);
//When Then
assertThatThrownBy(() -> sclService.importSTDElementsInSCD(scd, stds, DTO.SUB_NETWORK_TYPES))
assertThatThrownBy(() -> sclService.importSTDElementsInSCD(scd, stds))
.isInstanceOf(ScdException.class);
assertIsMarshallable(scd);
}
Expand All @@ -285,7 +332,7 @@ void importSTDElementsInSCD_whenSCDFileContainsSameICDHeaderInTwoDifferentFuncti
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd_with_same_compas_icd_header_in_different_functions.xml");
SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
//When Then
assertThatCode(() -> sclService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)).doesNotThrowAnyException();
assertThatCode(() -> sclService.importSTDElementsInSCD(scd, List.of(std))).doesNotThrowAnyException();
assertIsMarshallable(scd);
}

Expand All @@ -296,7 +343,7 @@ void importSTDElementsInSCD_whenCompasICDHeaderNotMatch__shouldThrowException()
SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_with_same_ICDSystemVersionUUID.xml");
List<SCL> stdList = List.of(std);
//When Then
assertThatThrownBy(() -> sclService.importSTDElementsInSCD(scd, stdList, DTO.SUB_NETWORK_TYPES))
assertThatThrownBy(() -> sclService.importSTDElementsInSCD(scd, stdList))
.isInstanceOf(ScdException.class)
.hasMessageContaining("COMPAS-ICDHeader is not the same in Substation and in IED");
assertIsMarshallable(scd);
Expand All @@ -308,7 +355,7 @@ void importSTDElementsInSCD_whenNoSTDMatch_shouldThrowException() {
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml");
List<SCL> stdList = List.of();
//When Then
assertThatCode(() -> sclService.importSTDElementsInSCD(scd, stdList, DTO.SUB_NETWORK_TYPES))
assertThatCode(() -> sclService.importSTDElementsInSCD(scd, stdList))
.isInstanceOf(ScdException.class)
.hasMessage("There is no STD file found corresponding to headerId = f8dbc8c1-2db7-4652-a9d6-0b414bdeccfa, headerVersion = 01.00.00, headerRevision = 01.00.00 and ICDSystemVersionUUID = IED4d4fe1a8cda64cf88a5ee4176a1a0eef");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import org.lfenergy.compas.scl2007b4.model.*;

import java.time.LocalDateTime;
import java.util.List;
import java.util.UUID;

public class DTO {
Expand Down Expand Up @@ -301,7 +300,4 @@ public static HeaderDTO.HistoryItem createHeaderItem(String now) {
return historyItem;
}

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.MMS.toString(), List.of("ADMIN_AP", "TATA_AP_EFFACEC")));
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!-- SPDX-FileCopyrightText: 2024 RTE FRANCE -->
<!-- -->
<!-- SPDX-License-Identifier: Apache-2.0 -->

<SCL xmlns="http://www.iec.ch/61850/2003/SCL" version="2007" revision="B" release="4">
<Header id="HeaderID" version="version" revision="Revision" toolID="toolID"/>
<Communication>
<SubNetwork name="SubNetworkName" type="8-MMS">
<ConnectedAP iedName="IED_NAME1" apName="ConnectedAP_Name">
<Address>
<P type="IP">1.2.3.4</P>
</Address>
<GSE ldInst="LD_INST11" cbName="LD_INST11_GSE">
<Address>
<P type="APPID">11</P>
</Address>
</GSE>
<PhysConn type="Connection">
<P type="Plug">PL</P>
</PhysConn>
</ConnectedAP>
</SubNetwork>
</Communication>
<IED name="IED_NAME1">
<AccessPoint name="ConnectedAP_Name"/>
</IED>
</SCL>
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<!-- SPDX-FileCopyrightText: 2024 RTE FRANCE -->
<!-- -->
<!-- SPDX-License-Identifier: Apache-2.0 -->

<SCL xmlns="http://www.iec.ch/61850/2003/SCL" version="2007" revision="B" release="4">
<Header id="HeaderID" version="version" revision="Revision" toolID="toolID"/>
<IED name="IED_NAME1">
<AccessPoint name="ConnectedAP_Name"/>
</IED>
</SCL>

0 comments on commit ba860cf

Please sign in to comment.