From 10a05da40ce30725d1c45a685ae3c3aaf3ff1287 Mon Sep 17 00:00:00 2001 From: Samir Romdhani Date: Wed, 9 Aug 2023 16:29:14 +0200 Subject: [PATCH] review feedback Signed-off-by: Samir Romdhani --- .../compas/sct/app/SclAutomationService.java | 15 ++-- .../SclAutomationServiceTest.java | 14 ++-- .../sct/commons/dto/ConnectedApDTO.java | 14 ++++ .../compas/sct/commons/dto/EnumTypeDTO.java | 8 ++ .../compas/sct/commons/dto/SubNetworkDTO.java | 57 +++++++------- .../sct/commons/dto/SubNetworkTypeDTO.java | 10 +++ .../compas/sct/commons/scl/ExtRefService.java | 4 +- .../compas/sct/commons/scl/SclService.java | 76 +++++++++---------- .../sct/commons/scl/SubstationService.java | 5 +- .../lfenergy/compas/sct/commons/dto/DTO.java | 7 +- .../sct/commons/dto/SubNetworkDTOTest.java | 55 +++++++------- .../sct/commons/scl/SclServiceTest.java | 73 ++++++++++-------- 12 files changed, 184 insertions(+), 154 deletions(-) create mode 100644 sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/EnumTypeDTO.java create mode 100644 sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkTypeDTO.java diff --git a/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java b/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java index 8d4e97326..234f86698 100644 --- a/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java +++ b/sct-app/src/main/java/org/lfenergy/compas/sct/app/SclAutomationService.java @@ -5,10 +5,10 @@ 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.SclService; import org.lfenergy.compas.sct.commons.scl.SubstationService; @@ -27,12 +27,12 @@ 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, List> 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 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"); @@ -48,14 +48,13 @@ private SclAutomationService() { * @throws ScdException */ public static SCL createSCD(@NonNull SCL ssd, @NonNull HeaderDTO headerDTO, List stds) throws ScdException { - SCL scd = SclService.initScl(Optional.ofNullable(headerDTO.getId()), - headerDTO.getVersion(), headerDTO.getRevision()); + SCL scd = SclService.initScl(headerDTO.getId(), headerDTO.getVersion(), headerDTO.getRevision()); if (!headerDTO.getHistoryItems().isEmpty()) { HeaderDTO.HistoryItem hItem = headerDTO.getHistoryItems().get(0); SclService.addHistoryItem(scd, hItem.getWho(), hItem.getWhat(), hItem.getWhy()); } SubstationService.addSubstation(scd, ssd); - SclService.importSTDElementsInSCD(scd, stds, comMap); + SclService.importSTDElementsInSCD(scd, stds, SUB_NETWORK_TYPES); SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scd); return scd; } diff --git a/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceTest.java b/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceTest.java index 001df3823..1feb4f25e 100644 --- a/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceTest.java +++ b/sct-app/src/test/java/org.lfenergy.compas.sct.app/SclAutomationServiceTest.java @@ -19,6 +19,7 @@ import java.lang.reflect.InvocationTargetException; import java.util.Arrays; import java.util.List; +import java.util.UUID; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -32,12 +33,13 @@ 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"); @@ -54,7 +56,7 @@ void createSCD_should_return_generatedSCD() throws Exception { } @Test - void createSCD_With_HItem() throws Exception { + void createSCD_With_HItem() { // Given HeaderDTO.HistoryItem historyItem = new HeaderDTO.HistoryItem(); historyItem.setWhat("what"); @@ -100,7 +102,7 @@ void createSCD_With_HItems() { } @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 @@ -110,7 +112,7 @@ void createSCD_SSD_Without_Substation() throws Exception { } @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"); @@ -125,7 +127,7 @@ void createSCD_should_throw_exception_when_null_ssd() throws Exception { } @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"); @@ -136,7 +138,7 @@ void createSCD_should_throw_exception_when_null_headerDTO() throws Exception { } @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"); diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ConnectedApDTO.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ConnectedApDTO.java index 61385eaa7..ebd776d11 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ConnectedApDTO.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ConnectedApDTO.java @@ -11,6 +11,8 @@ import lombok.Setter; import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter; +import java.util.Objects; + /** * A representation of the model object Connected AP. * @@ -53,4 +55,16 @@ public static ConnectedApDTO from(ConnectedAPAdapter connectedAPAdapter) { return connectedApDTO; } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof ConnectedApDTO that)) return false; + return Objects.equals(iedName, that.iedName) && Objects.equals(apName, that.apName); + } + + @Override + public int hashCode() { + return Objects.hash(iedName, apName); + } } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/EnumTypeDTO.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/EnumTypeDTO.java new file mode 100644 index 000000000..221e4590c --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/EnumTypeDTO.java @@ -0,0 +1,8 @@ +// SPDX-FileCopyrightText: 2023 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons.dto; + +public record EnumTypeDTO(Integer ord, String value) { +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTO.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTO.java index 148448461..cd6ffb39c 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTO.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTO.java @@ -8,16 +8,12 @@ import com.fasterxml.jackson.annotation.JsonValue; import lombok.Getter; import lombok.NoArgsConstructor; -import org.apache.commons.lang3.tuple.Pair; -import org.lfenergy.compas.sct.commons.scl.com.CommunicationAdapter; -import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter; +import org.lfenergy.compas.scl2007b4.model.TCommunication; +import org.lfenergy.compas.scl2007b4.model.TConnectedAP; +import org.lfenergy.compas.scl2007b4.model.TSubNetwork; import org.lfenergy.compas.sct.commons.scl.com.SubNetworkAdapter; -import java.util.HashSet; -import java.util.List; -import java.util.Map; -import java.util.Set; -import java.util.stream.Collectors; +import java.util.*; /** * A representation of the model object Sub Network. @@ -39,7 +35,7 @@ public class SubNetworkDTO { private String name; private SubnetworkType type; - private Set connectedAPs = new HashSet<>(); + private final Set connectedAPs = new HashSet<>(); /** * Constructor @@ -145,20 +141,21 @@ public static SubnetworkType fromValue(String text) { } /** - * Create default SubnetworkType in Communication node of SCL file - * @param iedName name of existing IED in SCL - * @param comAdapter Communication node Adapter object value - * @param comMap possible name of SubnetworkTypes and corresponding ConnectedAPs - * @return + * Create default Subnetwork in Communication node of SCL file + * @param iedName Name of existing IED in SCL + * @param communication Communication node in SCL + * @param subNetworkTypes Possible name of Subnetwork and corresponding ConnectedAPs + * @return List of Subnetwork */ - public static Set createDefaultSubnetwork(String iedName, CommunicationAdapter comAdapter, Map, List> comMap){ - Set subNetworkDTOS = new HashSet<>(); - comMap.forEach((subnetworkNameType, apNames) -> { - SubNetworkDTO subNetworkDTO = new SubNetworkDTO(subnetworkNameType.getLeft(), subnetworkNameType.getRight()); - apNames.forEach(s -> { - if(getStdConnectedApNames(comAdapter).contains(s)){ - ConnectedApDTO connectedApDTO = new ConnectedApDTO(iedName, s); - subNetworkDTO.addConnectedAP(connectedApDTO);} + public static List createDefaultSubnetwork(String iedName, TCommunication communication, List subNetworkTypes){ + List subNetworkDTOS = new ArrayList<>(); + subNetworkTypes.forEach(subnetwork -> { + SubNetworkDTO subNetworkDTO = new SubNetworkDTO(subnetwork.subnetworkName(), subnetwork.subnetworkType()); + subnetwork.accessPointNames().forEach(accessPointName -> { + if(getStdConnectedApNames(communication).contains(accessPointName)){ + ConnectedApDTO connectedApDTO = new ConnectedApDTO(iedName, accessPointName); + subNetworkDTO.addConnectedAP(connectedApDTO); + } }); subNetworkDTOS.add(subNetworkDTO); }); @@ -167,13 +164,15 @@ public static Set createDefaultSubnetwork(String iedName, Communi /** * Gets ConnectedAP name's from Communication node - * @param comAdapter Communication node object value - * @return + * @param communication Communication node object value + * @return List of ConnectedAP names */ - private static List getStdConnectedApNames(CommunicationAdapter comAdapter){ - return comAdapter.getSubNetworkAdapters().stream() - .map(SubNetworkAdapter::getConnectedAPAdapters) - .flatMap(connectedAPAdapters -> connectedAPAdapters.stream().map(ConnectedAPAdapter::getApName)) - .collect(Collectors.toList()); + private static List getStdConnectedApNames(TCommunication communication){ + return communication.getSubNetwork().stream() + .map(TSubNetwork::getConnectedAP) + .flatMap(List::stream) + .map(TConnectedAP::getApName) + .toList(); } + } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkTypeDTO.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkTypeDTO.java new file mode 100644 index 000000000..a247d4313 --- /dev/null +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/SubNetworkTypeDTO.java @@ -0,0 +1,10 @@ +// SPDX-FileCopyrightText: 2023 RTE FRANCE +// +// SPDX-License-Identifier: Apache-2.0 + +package org.lfenergy.compas.sct.commons.dto; + +import java.util.List; + +public record SubNetworkTypeDTO(String subnetworkName, String subnetworkType, List accessPointNames) { +} diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java index 2c7b4b232..c5a8c2529 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java @@ -59,7 +59,7 @@ public static List updateAllExtRefIedNames(SCL scd) { .filter(LN0Adapter::hasInputs) .map(LN0Adapter::getInputsAdapter) .map(inputsAdapter -> inputsAdapter.updateAllExtRefIedNames(icdSystemVersionToIed)) - .flatMap(List::stream).collect(Collectors.toList()); + .flatMap(List::stream).toList(); } private static List validateIed(SclRootAdapter sclRootAdapter) { @@ -152,7 +152,7 @@ private static List createDataSetAndControlBlocks(Stream *
  • Initialization functions
  • *
      - *
    1. {@link SclService#initScl(Optional, String, String) Initialize the SCL object}
    2. + *
    3. {@link SclService#initScl(UUID, String, String) Initialize the SCL object}
    4. *
    5. {@link SclService#addHistoryItem(SCL, String, String, String) Adds History object under THeader reference object}
    6. *
    7. {@link SclService#updateHeader(SCL, HeaderDTO) Update Header reference object}
    8. *
    @@ -47,7 +47,7 @@ *
  • Communication features
  • *
      *
    1. {@link SclService#getSubnetwork(SCL) Returns list of SubNetworkDTO }
    2. - *
    3. {@link SclService#addSubnetworks(SCL, Set, Optional) Adds the Subnetwork elements under TCommunication reference object}
    4. + *
    5. {@link SclService#addSubnetworks(SCL, List, Optional) Adds the Subnetwork elements under TCommunication reference object}
    6. *
    *
  • ExtRef features
  • *
      @@ -89,15 +89,14 @@ private SclService() { /** * Initialise SCD file with Header and Private SCLFileType * - * @param hId optional SCL Header ID, if empty random UUID will be created + * @param hId SCL Header ID * @param hVersion SCL Header Version * @param hRevision SCL Header Revision * @return SCL SCD object * @throws ScdException throws when inconsistance in SCL file */ - public static SCL initScl(final Optional hId, final String hVersion, final String hRevision) throws ScdException { - UUID headerId = hId.orElseGet(UUID::randomUUID); - SclRootAdapter scdAdapter = new SclRootAdapter(headerId.toString(), hVersion, hRevision); + public static SCL initScl(final UUID hId, final String hVersion, final String hRevision) throws ScdException { + SclRootAdapter scdAdapter = new SclRootAdapter(hId.toString(), hVersion, hRevision); scdAdapter.addPrivate(PrivateService.createPrivate(TCompasSclFileType.SCD)); return scdAdapter.getCurrentElem(); } @@ -109,13 +108,11 @@ public static SCL initScl(final Optional hId, final String hVersion, final * @param who Who realize the action * @param what What kind of action is realized * @param why Why this action is done - * @return SCL SCD object */ - public static SCL addHistoryItem(SCL scd, String who, String what, String why) { + public static void addHistoryItem(SCL scd, String who, String what, String why) { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); HeaderAdapter headerAdapter = sclRootAdapter.getHeaderAdapter(); headerAdapter.addHistoryItem(who, what, why); - return sclRootAdapter.getCurrentElem(); } /** @@ -159,23 +156,22 @@ public static SCL updateHeader(@NonNull SCL scd, @NonNull HeaderDTO headerDTO) { * @param scd SCL file in which IED should be added * @param iedName name of IED to add in SCL * @param icd ICD containing IED to add and related DataTypeTemplate - * @return SCL SCD object * @throws ScdException throws when inconsistency between IED to add and SCL file content */ - public static SCL addIED(SCL scd, String iedName, SCL icd) throws ScdException { - return new SclRootAdapter(scd).addIED(icd, iedName).getParentAdapter().getCurrentElem(); + public static void addIED(SCL scd, String iedName, SCL icd) throws ScdException { + new SclRootAdapter(scd).addIED(icd, iedName); } /** * Adds new SubNetworks in SCL file from ICD file * * @param scd SCL file in which SubNetworks should be added - * @param subNetworks list of SubNetworks DTO contenting SubNetwork and ConnectedAp parameter names + * @param subNetworks List of SubNetworks DTO contenting SubNetwork and ConnectedAp parameter names * @param icd ICD file from which SubNetworks functional data are copied from - * @return optional of TCommunication Communication node of SCL file. + * @return SCL scd object * @throws ScdException throws when no Communication in SCL and createIfNotExists == false */ - public static Optional addSubnetworks(SCL scd, Set subNetworks, Optional icd) throws ScdException { + public static SCL addSubnetworks(SCL scd, List subNetworks, Optional icd) throws ScdException { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); CommunicationAdapter communicationAdapter; if (!subNetworks.isEmpty()) { @@ -197,9 +193,9 @@ public static Optional addSubnetworks(SCL scd, SetidEnum from DataTypeTemplate of SCL file * - * @param scd SCL file in which EnumType should be found - * @param idEnum ID of EnumType for which values are retrieved + * @param scd SCL file in which EnumType should be found + * @param idEnum ID of EnumType for which values are retrieved * @return list of couple EnumType value and it's order - * @throws ScdException throws when unkonown EnumType + * @throws ScdException throws when unknown EnumType */ - public static Set> getEnumTypeElements(SCL scd, String idEnum) throws ScdException { + public static Set getEnumTypeElements(SCL scd, String idEnum) throws ScdException { SclRootAdapter sclRootAdapter = new SclRootAdapter(scd); DataTypeTemplateAdapter dataTypeTemplateAdapter = sclRootAdapter.getDataTypeTemplateAdapter(); EnumTypeAdapter enumTypeAdapter = dataTypeTemplateAdapter.getEnumTypeAdapterById(idEnum) .orElseThrow(() -> new ScdException("Unknown EnumType Id: " + idEnum)); return enumTypeAdapter.getCurrentElem().getEnumVal().stream() - .map(tEnumVal -> Pair.of(tEnumVal.getOrd(), tEnumVal.getValue())) + .map(tEnumVal -> new EnumTypeDTO(tEnumVal.getOrd(), tEnumVal.getValue())) .collect(Collectors.toSet()); } @@ -481,20 +477,19 @@ public static Set> getEnumTypeElements(SCL scd, String idE *
    1. import connectedAP and rename ConnectedAP/@iedName in Communication node in SCD file
    2. * * - * @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 comMap couple of Subnetwork name and possible corresponding ConnectAP names - * @return updated SCD object - * @throws ScdException throws when inconsistency between Substation of SCL content and gien STD files as : - *
        - *
      • ICD_SYSTEM_VERSION_UUID in IED/Private of STD is not present in COMPAS-ICDHeader in Substation/../LNode of SCL
      • - *
      • There are several STD files corresponding to ICD_SYSTEM_VERSION_UUID of COMPAS-ICDHeader in Substation/../LNode of SCL
      • - *
      • There is no STD file found corresponding to COMPAS-ICDHeader in Substation/../LNode of SCL
      • - *
      • COMPAS-ICDHeader is not the same in Substation/../LNode of SCL and in IED/Private of STD
      • - *
      • COMPAS_ICDHEADER in Substation/../LNode of SCL not found in IED/Private of STD
      • - *
      + * @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 : + *
        + *
      • ICD_SYSTEM_VERSION_UUID in IED/Private of STD is not present in COMPAS-ICDHeader in Substation/../LNode of SCL
      • + *
      • There are several STD files corresponding to ICD_SYSTEM_VERSION_UUID of COMPAS-ICDHeader in Substation/../LNode of SCL
      • + *
      • There is no STD file found corresponding to COMPAS-ICDHeader in Substation/../LNode of SCL
      • + *
      • COMPAS-ICDHeader is not the same in Substation/../LNode of SCL and in IED/Private of STD
      • + *
      • COMPAS_ICDHEADER in Substation/../LNode of SCL not found in IED/Private of STD
      • + *
      */ - public static SCL importSTDElementsInSCD(@NonNull SCL scd, List stds, Map, List> comMap) throws ScdException { + public static void importSTDElementsInSCD(SCL scd, List stds, List subNetworkTypes) throws ScdException { //Check SCD and STD compatibilities Map mapICDSystemVersionUuidAndSTDFile = PrivateService.createMapICDSystemVersionUuidAndSTDFile(stds); @@ -522,12 +517,11 @@ public static SCL importSTDElementsInSCD(@NonNull SCL scd, List stds, Map

      subNetworkDTOSet = SubNetworkDTO.createDefaultSubnetwork(iedName, comAdapter, comMap); + TCommunication communication = stdRootAdapter.getCurrentElem().getCommunication(); + List subNetworkDTOSet = SubNetworkDTO.createDefaultSubnetwork(iedName, communication, subNetworkTypes); addSubnetworks(scdRootAdapter.getCurrentElem(), subNetworkDTOSet, Optional.of(std)); } }); - return scdRootAdapter.getCurrentElem(); } @@ -570,7 +564,7 @@ public static List updateLDeviceStatus(SCL scd) { .map(LDeviceAdapter::getLN0Adapter) .map(ln0Adapter -> ln0Adapter.updateLDeviceStatus(iedNameLdInstList)) .flatMap(Optional::stream) - .collect(Collectors.toList()); + .toList(); } /** @@ -587,7 +581,7 @@ public static List analyzeDataGroups(SCL scd) { list.addAll(iedAdapter.checkDataGroupCoherence()); list.addAll(iedAdapter.checkBindingDataGroupCoherence()); return list; - }).flatMap(Collection::stream).collect(Collectors.toList()); + }).flatMap(Collection::stream).toList(); } /** @@ -603,7 +597,7 @@ public static List updateDoInRef(SCL scd) { .map(LDeviceAdapter::getLN0Adapter) .map(LN0Adapter::updateDoInRef) .flatMap(List::stream) - .collect(Collectors.toList()); + .toList(); } /** diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java index 995dade2f..8e92407dd 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SubstationService.java @@ -43,11 +43,10 @@ private SubstationService() { * Adds or Updates Substation section in SCL * @param scd SCL file in which Substation should be added/updated * @param ssd SCL file from which Substation should be copied - * @return SCL SCD object * @throws ScdException throws when SCD contents already another Substation, or with different name, or contents * more than one Substation */ - public static SCL addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdException { + public static void addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdException { if (scd.getSubstation().size() > 1) { throw new ScdException(String.format("SCD file must have 0 or 1 Substation, but got %d", scd.getSubstation().size())); } @@ -57,7 +56,6 @@ public static SCL addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdEx TSubstation ssdTSubstation = ssd.getSubstation().get(0); if (scd.getSubstation().isEmpty()) { scd.getSubstation().add(ssdTSubstation); - return scd; } else { TSubstation scdTSubstation = scd.getSubstation().get(0); if (scdTSubstation.getName().equalsIgnoreCase(ssdTSubstation.getName())) { @@ -65,7 +63,6 @@ public static SCL addSubstation(@NonNull SCL scd, @NonNull SCL ssd) throws ScdEx for (TVoltageLevel tvl : ssdTSubstation.getVoltageLevel()) { updateVoltageLevel(scdSubstationAdapter, tvl); } - return scdSubstationAdapter.getParentAdapter().getCurrentElem(); } else throw new ScdException("SCD file must have only one Substation and the Substation name from SSD file is" + " different from the one in SCD file. The files are rejected."); diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java index a31c47d99..32b3f4731 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/DTO.java @@ -4,13 +4,10 @@ package org.lfenergy.compas.sct.commons.dto; -import org.apache.commons.lang3.tuple.Pair; import org.lfenergy.compas.scl2007b4.model.*; import java.time.LocalDateTime; -import java.util.Arrays; import java.util.List; -import java.util.Map; import java.util.UUID; public class DTO { @@ -313,5 +310,7 @@ public static HeaderDTO.HistoryItem createHeaderItem(String now) { return historyItem; } - public static final Map, List> 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 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"))); } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTOTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTOTest.java index e9471bc07..ffd5623bd 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTOTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/dto/SubNetworkDTOTest.java @@ -4,20 +4,19 @@ package org.lfenergy.compas.sct.commons.dto; -import org.apache.commons.lang3.tuple.Pair; import org.junit.jupiter.api.Test; -import org.lfenergy.compas.sct.commons.scl.com.CommunicationAdapter; +import org.lfenergy.compas.scl2007b4.model.TCommunication; +import org.lfenergy.compas.scl2007b4.model.TConnectedAP; +import org.lfenergy.compas.scl2007b4.model.TSubNetwork; import org.lfenergy.compas.sct.commons.scl.com.ConnectedAPAdapter; import org.lfenergy.compas.sct.commons.scl.com.SubNetworkAdapter; import org.mockito.Mockito; -import java.util.Arrays; -import java.util.List; -import java.util.Map; -import java.util.Set; +import java.util.*; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assertions.*; +import static org.mockito.Mockito.when; class SubNetworkDTOTest { @@ -35,11 +34,11 @@ void testConstructor(){ void testFrom(){ SubNetworkAdapter subNetworkAdapter = Mockito.mock(SubNetworkAdapter.class); ConnectedAPAdapter connectedAPAdapter = Mockito.mock(ConnectedAPAdapter.class); - Mockito.when(subNetworkAdapter.getConnectedAPAdapters()).thenReturn(List.of(connectedAPAdapter)); - Mockito.when(subNetworkAdapter.getName()).thenReturn("sName"); - Mockito.when(subNetworkAdapter.getType()).thenReturn(SubNetworkDTO.SubnetworkType.IP.toString()); - Mockito.when(connectedAPAdapter.getApName()).thenReturn(DTO.AP_NAME); - Mockito.when(connectedAPAdapter.getIedName()).thenReturn(DTO.HOLDER_IED_NAME); + when(subNetworkAdapter.getConnectedAPAdapters()).thenReturn(List.of(connectedAPAdapter)); + when(subNetworkAdapter.getName()).thenReturn("sName"); + when(subNetworkAdapter.getType()).thenReturn(SubNetworkDTO.SubnetworkType.IP.toString()); + when(connectedAPAdapter.getApName()).thenReturn(DTO.AP_NAME); + when(connectedAPAdapter.getIedName()).thenReturn(DTO.HOLDER_IED_NAME); SubNetworkDTO subNetworkDTO = SubNetworkDTO.from(subNetworkAdapter); assertEquals("sName",subNetworkDTO.getName()); @@ -49,23 +48,23 @@ void testFrom(){ } @Test - void testCreateDefaultSubnetwork() { - CommunicationAdapter comAdapter = Mockito.mock(CommunicationAdapter.class); - SubNetworkAdapter subNetworkAdapter = Mockito.mock(SubNetworkAdapter.class); - ConnectedAPAdapter connectedAPAdapter = Mockito.mock(ConnectedAPAdapter.class); - - Mockito.when(comAdapter.getSubNetworkAdapters()).thenReturn(List.of(subNetworkAdapter)); - Mockito.when(subNetworkAdapter.getConnectedAPAdapters()).thenReturn(List.of(connectedAPAdapter)); - Mockito.when(subNetworkAdapter.getName()).thenReturn("sName"); - Mockito.when(subNetworkAdapter.getType()).thenReturn(SubNetworkDTO.SubnetworkType.IP.toString()); - Mockito.when(connectedAPAdapter.getApName()).thenReturn("PROCESS_AP"); - Mockito.when(connectedAPAdapter.getIedName()).thenReturn("IEDName"); - - final Map, List> 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")); - - Set subNetworkDTOS = SubNetworkDTO.createDefaultSubnetwork("IEDName", comAdapter, comMap); + void createDefaultSubnetwork_should_return_filtered_subnetwork_list() { + //When + TCommunication communication = Mockito.mock(TCommunication.class); + TSubNetwork subNetwork1 = new TSubNetwork(); + subNetwork1.setName("sName"); + subNetwork1.setName(SubNetworkDTO.SubnetworkType.IP.toString()); + TConnectedAP connectedAP1 = new TConnectedAP(); + connectedAP1.setApName("PROCESS_AP"); + connectedAP1.setIedName("IEDName"); + subNetwork1.getConnectedAP().add(connectedAP1); + when(communication.getSubNetwork()).thenReturn(List.of(subNetwork1)); + List subNetworkTypes =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"))); + //When + List subNetworkDTOS = SubNetworkDTO.createDefaultSubnetwork("IEDName", communication, subNetworkTypes); + //Then assertThat(subNetworkDTOS).hasSize(2); SubNetworkDTO expectedSubNetwork = subNetworkDTOS.stream().filter(subNetworkDTO -> !subNetworkDTO.getConnectedAPs().isEmpty()).findFirst().orElse(new SubNetworkDTO()); assertThat(expectedSubNetwork.getConnectedAPs()).hasSize(1); diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java index 91cf6df10..f83d89e91 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/SclServiceTest.java @@ -142,7 +142,7 @@ void addSubnetworks_should_add_subnetwork() { connectedApDTO.setIedName("IED_NAME1"); subNetworkDTO.addConnectedAP(connectedApDTO); //When Then - assertThatCode(() -> SclService.addSubnetworks(scd, Set.of(subNetworkDTO), Optional.of(icd)).get()).doesNotThrowAnyException(); + assertThatCode(() -> SclService.addSubnetworks(scd, List.of(subNetworkDTO), Optional.of(icd))).doesNotThrowAnyException(); assertIsMarshallable(scd); } @@ -156,7 +156,7 @@ void addSubnetworks_should_not_add_subnetwork_when_withoutCommunicationTagInIcd( //TODO not should appear in given section, only one When step assertThatCode(() -> SclService.addIED(scd, "IED_NAME1", icd)).doesNotThrowAnyException(); //When Then - assertThatCode(() -> SclService.addSubnetworks(scd, new HashSet<>(), Optional.of(icd))).doesNotThrowAnyException(); + assertThatCode(() -> SclService.addSubnetworks(scd, List.of(), Optional.of(icd))).doesNotThrowAnyException(); String marshalledScd = assertIsMarshallable(scd); assertThat(marshalledScd).doesNotContain(" SclService.addIED(scd, "IED_NAME1", icd)).doesNotThrowAnyException(); //TODO not should appear in given section, only one When step - Set subNetworkDTOSet = new HashSet<>(SclService.getSubnetwork(icd)); + List subNetworkDTOSet = SclService.getSubnetwork(icd); //When Then assertThatCode(() -> SclService.addSubnetworks(scd, subNetworkDTOSet, Optional.of(icd))).doesNotThrowAnyException(); String marshalledScd = assertIsMarshallable(scd); @@ -188,7 +188,7 @@ void addSubnetworks_should_add_subnetwork_element_when_withoutImportingIcdAddres //TODO not should appear in given section, only one When step assertThatCode(() -> SclService.addIED(scd, "IED_NAME1", icd)).doesNotThrowAnyException(); //When Then - Set subNetworkDTOSet = new HashSet<>(SclService.getSubnetwork(icd)); + List subNetworkDTOSet = SclService.getSubnetwork(icd); assertThatCode(() -> SclService.addSubnetworks(scd, subNetworkDTOSet, Optional.empty())).doesNotThrowAnyException(); String marshalledScd = assertIsMarshallable(scd); assertThat(marshalledScd).doesNotContain("

      ", "PhysConn"); @@ -211,7 +211,7 @@ void getSubnetwork_should_return_list() { connectedApDTO.setIedName("IED_NAME1"); subNetworkDTO.addConnectedAP(connectedApDTO); //TODO not should appear in given section, only one When step - assertThatCode(() -> SclService.addSubnetworks(scd, Set.of(subNetworkDTO), Optional.of(icd))).doesNotThrowAnyException(); + assertThatCode(() -> SclService.addSubnetworks(scd, List.of(subNetworkDTO), Optional.of(icd))).doesNotThrowAnyException(); //When List subNetworkDTOS = SclService.getSubnetwork(scd); //Then @@ -746,26 +746,26 @@ void getDAI_should_filter_updatable_DA_with_sGroup_Val_without_ConfSg() { } @Test - void initScl_shouldNotThrowError() { - SCL scd = assertDoesNotThrow(() -> SclService.initScl(Optional.empty(), "hVersion", "hRevision")); - assertIsMarshallable(scd); + void initScl_shouldThrowError_when_headerId_isIncorrect() { + assertThatThrownBy(() -> SclService.initScl(UUID.fromString(""), "hVersion", "hRevision")) + .hasMessageContaining("Invalid UUID"); } @Test void initScl_shouldNotThrowError_when_hId_provided() { // Given - UUID hid = UUID.randomUUID(); + UUID headerId = UUID.randomUUID(); // When Then - SCL scd = assertDoesNotThrow(() -> SclService.initScl(Optional.of(hid), "hVersion", "hRevision")); + SCL scd = assertDoesNotThrow(() -> SclService.initScl(headerId, "hVersion", "hRevision")); assertIsMarshallable(scd); } @Test void initScl_should_create_Private_SCL_FILETYPE() { // Given - UUID hid = UUID.randomUUID(); + UUID headerId = UUID.randomUUID(); // When Then - SCL scd = assertDoesNotThrow(() -> SclService.initScl(Optional.of(hid), "hVersion", "hRevision")); + SCL scd = assertDoesNotThrow(() -> SclService.initScl(headerId, "hVersion", "hRevision")); assertThat(scd.getPrivate()).isNotEmpty(); assertThat(scd.getPrivate().get(0).getType()).isEqualTo(COMPAS_SCL_FILE_TYPE.getPrivateType()); assertIsMarshallable(scd); @@ -774,7 +774,7 @@ void initScl_should_create_Private_SCL_FILETYPE() { @Test void updateHeader_should_update_header_tag() { //Given - SCL scd = assertDoesNotThrow(() -> SclService.initScl(Optional.empty(), "hVersion", "hRevision")); + SCL scd = assertDoesNotThrow(() -> SclService.initScl(UUID.randomUUID(), "hVersion", "hRevision")); UUID hId = UUID.fromString(scd.getHeader().getId()); HeaderDTO headerDTO = DTO.createHeaderDTO(hId); //When @@ -805,15 +805,24 @@ void updateDAI_should_not_throw_error() { } @Test - void getEnumTypeElements_should_return_list() { + void getEnumTypeElements_should_return_exception() { + //Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); + //When Then + assertThatThrownBy(() -> SclService.getEnumTypeElements(scd, "unknownID")) + .isInstanceOf(ScdException.class) + .hasMessage("Unknown EnumType Id: unknownID"); + } + + @Test + void getEnumTypeElements_should_return_enumTypelist() { //Given SCL scd = SclTestMarshaller.getSCLFromFile("/scl-srv-import-ieds/ied_1_test.xml"); - //TODO not should appear in given section - assertThatThrownBy(() -> SclService.getEnumTypeElements(scd, "unknwnID")) - .isInstanceOf(ScdException.class); //When Then var enumList = assertDoesNotThrow(() -> SclService.getEnumTypeElements(scd, "RecCycModKind")); - assertThat(enumList).isNotEmpty(); + assertThat(enumList).hasSize(1) + .extracting(EnumTypeDTO::ord, EnumTypeDTO::value) + .containsExactly(Tuple.tuple(1, "Completed-diff")); } @Test @@ -822,10 +831,10 @@ void importSTDElementsInSCD_should_std_files_is_scd() { 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 - SCL expectedScd = assertDoesNotThrow(() -> SclService.importSTDElementsInSCD(scd, List.of(std), DTO.comMap)); - assertThat(expectedScd.getIED()).hasSize(1); - assertThat(expectedScd.getDataTypeTemplates()).hasNoNullFieldsOrProperties(); - assertThat(expectedScd.getCommunication().getSubNetwork()).hasSize(2); + assertDoesNotThrow(() -> SclService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)); + assertThat(scd.getIED()).hasSize(1); + assertThat(scd.getDataTypeTemplates()).hasNoNullFieldsOrProperties(); + assertThat(scd.getCommunication().getSubNetwork()).hasSize(2); assertIsMarshallable(scd); } @@ -836,12 +845,12 @@ void importSTDElementsInSCD_shouldNotThrowException_when_with_Multiple_STD() { 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"); - SCL expectedScd = assertDoesNotThrow(() -> SclService.importSTDElementsInSCD(scd, List.of(std0, std1, std2), DTO.comMap)); - assertThat(expectedScd.getIED()).hasSize(3); - assertThat(expectedScd.getDataTypeTemplates()).hasNoNullFieldsOrProperties(); - assertThat(expectedScd.getCommunication().getSubNetwork()).hasSize(2); - assertThat(expectedScd.getCommunication().getSubNetwork().get(0).getConnectedAP()).hasSizeBetween(1, 3); - assertThat(expectedScd.getCommunication().getSubNetwork().get(1).getConnectedAP()).hasSizeBetween(1, 3); + assertDoesNotThrow(() -> SclService.importSTDElementsInSCD(scd, List.of(std0, std1, std2), DTO.SUB_NETWORK_TYPES)); + assertThat(scd.getIED()).hasSize(3); + assertThat(scd.getDataTypeTemplates()).hasNoNullFieldsOrProperties(); + assertThat(scd.getCommunication().getSubNetwork()).hasSize(2); + assertThat(scd.getCommunication().getSubNetwork().get(0).getConnectedAP()).hasSizeBetween(1, 3); + assertThat(scd.getCommunication().getSubNetwork().get(1).getConnectedAP()).hasSizeBetween(1, 3); assertIsMarshallable(scd); } @@ -853,7 +862,7 @@ void importSTDElementsInSCD_shouldThrowException_when_Several_STD_Match_Compas_I SCL std1 = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std.xml"); //When Then List stds = List.of(std, std1); - assertThatThrownBy(() -> SclService.importSTDElementsInSCD(scd, stds, DTO.comMap)) + assertThatThrownBy(() -> SclService.importSTDElementsInSCD(scd, stds, DTO.SUB_NETWORK_TYPES)) .isInstanceOf(ScdException.class); assertIsMarshallable(scd); } @@ -864,7 +873,7 @@ void importSTDElementsInSCD_should_not_throw_exception_when_SCD_file_contains_sa 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.comMap)).doesNotThrowAnyException(); + assertThatCode(() -> SclService.importSTDElementsInSCD(scd, List.of(std), DTO.SUB_NETWORK_TYPES)).doesNotThrowAnyException(); assertIsMarshallable(scd); } @@ -875,7 +884,7 @@ void importSTDElementsInSCD_should_throw_exception_when_Compas_ICDHeader_Not_Mat SCL std = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/std_with_same_ICDSystemVersionUUID.xml"); //When Then List stds = List.of(std); - assertThatThrownBy(() -> SclService.importSTDElementsInSCD(scd, stds, DTO.comMap)) + assertThatThrownBy(() -> SclService.importSTDElementsInSCD(scd, stds, DTO.SUB_NETWORK_TYPES)) .isInstanceOf(ScdException.class); assertIsMarshallable(scd); } @@ -885,7 +894,7 @@ void importSTDElementsInSCD_should_throw_exception_when_No_STD_Match() { //Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-ied-dtt-com-import-stds/ssd.xml"); //When Then - assertThatCode(() -> SclService.importSTDElementsInSCD(scd, List.of(), DTO.comMap)) + assertThatCode(() -> SclService.importSTDElementsInSCD(scd, List.of(), DTO.SUB_NETWORK_TYPES)) .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"); }