Skip to content

Commit

Permalink
Merge pull request #310 from com-pas/develop
Browse files Browse the repository at this point in the history
Merge develop into main
  • Loading branch information
samirromdhani authored Aug 14, 2023
2 parents df8ff61 + 8b8c2ce commit cd893b9
Show file tree
Hide file tree
Showing 36 changed files with 648 additions and 838 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,11 @@
package org.lfenergy.compas.sct.app;

import lombok.NonNull;
import org.apache.commons.lang3.tuple.Pair;
import org.lfenergy.compas.scl2007b4.model.SCL;
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 org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
import org.lfenergy.compas.sct.commons.scl.SclService;
import org.lfenergy.compas.sct.commons.scl.SubstationService;

Expand All @@ -22,42 +21,41 @@
* The following features are supported:
* </p>
* <ul>
* <li>{@link SclAutomationService#createSCD(SCL, HeaderDTO, Set) Adds all elements under the <b>SCL </b> object from given <b>SSD </b> and <b>STD </b> files}
* <li>{@link SclAutomationService#createSCD(SCL, HeaderDTO, List) Adds all elements under the <b>SCL </b> object from given <b>SSD </b> and <b>STD </b> files}
* </ul>
*/
public class SclAutomationService {

/**
* Possible Subnetwork and ConnectAP names which should be used in generated SCD in order a have global coherence
* 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
*/
private static final Map<Pair<String, String>, List<String>> comMap = Map.of(
Pair.of("RSPACE_PROCESS_NETWORK", SubNetworkDTO.SubnetworkType.MMS.toString()), Arrays.asList("PROCESS_AP", "TOTO_AP_GE"),
Pair.of("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString()), Arrays.asList("ADMIN_AP", "TATA_AP_EFFACEC"));
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")));

private SclAutomationService() {
throw new UnsupportedOperationException("This is a utility class and cannot be instantiated");
}

/**
* Create a SCD file from specified parameters, it calls all functions defined in the process one by one, every step
* return a SCD file which will be used by the next step.
* 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.
* @param ssd : (mandatory) file contains substation datas
* @param headerDTO : (mandatory) object which hold header datas and historys' one
* @param stds : (optional) list of STD files containing IED datas (IED, Communication and DataTypeTemplate)
* @return a SCD file encapsuled in object SclRootAdapter
* @param stds : list of STD files containing IED datas (IED, Communication and DataTypeTemplate)
* @return an SCD object
* @throws ScdException
*/
public static SclRootAdapter createSCD(@NonNull SCL ssd, @NonNull HeaderDTO headerDTO, Set<SCL> stds) throws ScdException {
SclRootAdapter scdAdapter = SclService.initScl(Optional.ofNullable(headerDTO.getId()),
headerDTO.getVersion(), headerDTO.getRevision());
public static SCL createSCD(@NonNull SCL ssd, @NonNull HeaderDTO headerDTO, List<SCL> stds) throws ScdException {
SCL scd = SclService.initScl(headerDTO.getId(), headerDTO.getVersion(), headerDTO.getRevision());
if (!headerDTO.getHistoryItems().isEmpty()) {
HeaderDTO.HistoryItem hItem = headerDTO.getHistoryItems().get(0);
SclService.addHistoryItem(scdAdapter.getCurrentElem(), hItem.getWho(), hItem.getWhat(), hItem.getWhy());
SclService.addHistoryItem(scd, hItem.getWho(), hItem.getWhat(), hItem.getWhy());
}
SubstationService.addSubstation(scdAdapter.getCurrentElem(), ssd);
SclService.importSTDElementsInSCD(scdAdapter, stds, comMap);
SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scdAdapter.getCurrentElem());
return scdAdapter;
SubstationService.addSubstation(scd, ssd);
SclService.importSTDElementsInSCD(scd, stds, SUB_NETWORK_TYPES);
SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scd);
return scd;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;
import java.util.List;
import java.util.UUID;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
Expand All @@ -33,29 +33,30 @@ class SclAutomationServiceTest {
@BeforeEach
void init() {
headerDTO = new HeaderDTO();
headerDTO.setId(UUID.randomUUID());
headerDTO.setRevision("hRevision");
headerDTO.setVersion("hVersion");
}

@Test
void createSCD_should_return_generatedSCD() throws Exception {
void createSCD_should_return_generatedSCD() {
// Given
SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/scd.xml");
SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml");
// When
SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std));
SCL scd = SclAutomationService.createSCD(ssd, headerDTO, List.of(std));
// Then
assertNotNull(expectedSCD.getCurrentElem().getHeader().getId());
assertNull(expectedSCD.getCurrentElem().getHeader().getHistory());
assertEquals(1, expectedSCD.getCurrentElem().getSubstation().size());
assertEquals(1, expectedSCD.getCurrentElem().getIED().size());
assertNotNull(expectedSCD.getCurrentElem().getDataTypeTemplates());
assertEquals(2, expectedSCD.getCurrentElem().getCommunication().getSubNetwork().size());
assertIsMarshallable(expectedSCD.getCurrentElem());
assertNotNull(scd.getHeader().getId());
assertNull(scd.getHeader().getHistory());
assertEquals(1, scd.getSubstation().size());
assertEquals(1, scd.getIED().size());
assertNotNull(scd.getDataTypeTemplates());
assertEquals(2, scd.getCommunication().getSubNetwork().size());
assertIsMarshallable(scd);
}

@Test
void createSCD_With_HItem() throws Exception {
void createSCD_With_HItem() {
// Given
HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem();
historyItem.setWhat("what");
Expand All @@ -67,16 +68,16 @@ void createSCD_With_HItem() throws Exception {
SCL std2 = SclTestMarshaller.getSCLFromFile("/std_2.xml");
SCL std3 = SclTestMarshaller.getSCLFromFile("/std_3.xml");
// When
SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std1, std2, std3));
SCL scd = SclAutomationService.createSCD(ssd, headerDTO, List.of(std1, std2, std3));
// Then
assertNotNull(expectedSCD.getCurrentElem().getHeader().getId());
assertEquals(1, expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size());
assertEquals(1, expectedSCD.getCurrentElem().getSubstation().size());
assertIsMarshallable(expectedSCD.getCurrentElem());
assertNotNull(scd.getHeader().getId());
assertEquals(1, scd.getHeader().getHistory().getHitem().size());
assertEquals(1, scd.getSubstation().size());
assertIsMarshallable(scd);
}

@Test
void createSCD_With_HItems() throws Exception {
void createSCD_With_HItems() {
// Given
HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem();
historyItem.setWhat("what");
Expand All @@ -92,59 +93,59 @@ void createSCD_With_HItems() throws Exception {
SCL std2 = SclTestMarshaller.getSCLFromFile("/std_2.xml");
SCL std3 = SclTestMarshaller.getSCLFromFile("/std_3.xml");
// When
SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std1, std2, std3));
SCL scd = SclAutomationService.createSCD(ssd, headerDTO, List.of(std1, std2, std3));
// Then
assertNotNull(expectedSCD.getCurrentElem().getHeader().getId());
assertEquals(1, expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size());
assertEquals("what", expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().get(0).getWhat());
assertIsMarshallable(expectedSCD.getCurrentElem());
assertNotNull(scd.getHeader().getId());
assertEquals(1, scd.getHeader().getHistory().getHitem().size());
assertEquals("what", scd.getHeader().getHistory().getHitem().get(0).getWhat());
assertIsMarshallable(scd);
}

@Test
void createSCD_SSD_Without_Substation() throws Exception {
void createSCD_SSD_Without_Substation() {
// Given
SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd_without_substations.xml");
// When & Then
Set<SCL> stdListEmpty = new HashSet<>();
List<SCL> stdListEmpty = List.of();
assertThrows(ScdException.class,
() -> SclAutomationService.createSCD(ssd, headerDTO, stdListEmpty));
}

@Test
void createSCD_should_throw_exception_when_null_ssd() throws Exception {
void createSCD_should_throw_exception_when_null_ssd() {
// Given
HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem();
historyItem.setWhat("what");
historyItem.setWho("me");
historyItem.setWhy("because");
headerDTO.getHistoryItems().add(historyItem);
SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml");
Set<SCL> stdList = Set.of(std1);
List<SCL> stdList = List.of(std1);

// When & Then
assertThrows(NullPointerException.class, () -> SclAutomationService.createSCD(null, headerDTO, stdList));
}

@Test
void createSCD_should_throw_exception_when_null_headerDTO() throws Exception {
void createSCD_should_throw_exception_when_null_headerDTO() {
// Given
SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml");
SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml");
Set<SCL> stdList = Set.of(std1);
List<SCL> stdList = List.of(std1);

// When & Then
assertThrows(NullPointerException.class, () -> SclAutomationService.createSCD(ssd, null, stdList));
}

@Test
void createSCD_should_delete_ControlBlocks_DataSet_and_ExtRef_src_attributes() throws Exception {
void createSCD_should_delete_ControlBlocks_DataSet_and_ExtRef_src_attributes() {
// Given
SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml");
SCL std = SclTestMarshaller.getSCLFromFile("/scl-remove-controlBlocks-dataSet-extRefSrc/scl-with-control-blocks.xml");
// When
SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std));
SCL scd = SclAutomationService.createSCD(ssd, headerDTO, List.of(std));
// Then
LN0 ln0 = expectedSCD.streamIEDAdapters()
LN0 ln0 = new SclRootAdapter(scd).streamIEDAdapters()
.findFirst()
.map(iedAdapter -> iedAdapter.findLDeviceAdapterByLdInst("lDeviceInst1").orElseThrow())
.map(LDeviceAdapter::getLN0Adapter)
Expand All @@ -154,7 +155,7 @@ void createSCD_should_delete_ControlBlocks_DataSet_and_ExtRef_src_attributes() t
assertThat(ln0.getDataSet()).isEmpty();
assertThat(ln0.getInputs().getExtRef()).hasSize(2);
assertFalse(ln0.getInputs().getExtRef().get(0).isSetSrcLDInst());
assertIsMarshallable(expectedSCD.getCurrentElem());
assertIsMarshallable(scd);
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,53 +4,33 @@

package org.lfenergy.compas.sct.commons.dto;


import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter;

import java.util.Objects;

/**
* A representation of the model object <em><b>Connected AP</b></em>.
*
* <p>
* The following features are supported:
* </p>
* <ul>
* <li>{@link ConnectedApDTO#getApName() <em>Ap Name</em>}</li>
* <li>{@link ConnectedApDTO#getIedName() <em>Ied Name</em>}</li>
* <li>{@link ConnectedApDTO#apName()} () <em>Ap Name</em>}</li>
* <li>{@link ConnectedApDTO#iedName()} () <em>Ied Name</em>}</li>
* </ul>
*
* @see org.lfenergy.compas.scl2007b4.model.TConnectedAP
*/
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
public class ConnectedApDTO {
private String iedName;
private String apName;

/**
* Create ConnectedApDTO from constructor
* @param connectedAPAdapter object containing data to use
*/
public ConnectedApDTO(ConnectedAPAdapter connectedAPAdapter) {
this.iedName = connectedAPAdapter.getIedName();
this.apName = connectedAPAdapter.getApName();
}
public record ConnectedApDTO(String iedName, String apName) {

/**
* Convert ConnectedAPAdapter object to dto ConnectedApDTO
*
* @param connectedAPAdapter object to convert
* @return dto ConnectedApDTO
*/
public static ConnectedApDTO from(ConnectedAPAdapter connectedAPAdapter) {
ConnectedApDTO connectedApDTO = new ConnectedApDTO();
connectedApDTO.iedName = connectedAPAdapter.getIedName();
connectedApDTO.apName = connectedAPAdapter.getApName();

return connectedApDTO;
return new ConnectedApDTO(connectedAPAdapter.getIedName(), connectedAPAdapter.getApName());
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: 2023 RTE FRANCE
//
// SPDX-License-Identifier: Apache-2.0

package org.lfenergy.compas.sct.commons.dto;

public record EnumValDTO(Integer ord, String value) {
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
// SPDX-FileCopyrightText: 2022 RTE FRANCE
// SPDX-FileCopyrightText: 2022 2023 RTE FRANCE
//
// SPDX-License-Identifier: Apache-2.0

package org.lfenergy.compas.sct.commons.dto;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.ToString;
public record SclReportItem(String xpath, String message, boolean isError) {

@Getter
@EqualsAndHashCode
@AllArgsConstructor
@ToString
public final class SclReportItem {
private final String xpath;
private final String message;
private final boolean isFatal;

public static SclReportItem fatal(String xpath, String message) {
public static SclReportItem error(String xpath, String message) {
return new SclReportItem(xpath, message, true);
}

Expand Down
Loading

0 comments on commit cd893b9

Please sign in to comment.