Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merge develop into main #195

Merged
merged 5 commits into from
Nov 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,20 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>${maven.plugin.javadoc}</version>
<executions>
<execution>
<id>attach-javadocs</id>
<phase>package</phase>
<goals>
<goal>aggregate</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
Expand Down
5 changes: 5 additions & 0 deletions sct-app/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@
<version>3.6.28</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.assertj</groupId>
<artifactId>assertj-core</artifactId>
<version>3.23.1</version>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,11 @@ public class SclAutomationService {
*/
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"));
Pair.of("RSPACE_ADMIN_NETWORK", SubNetworkDTO.SubnetworkType.IP.toString()), Arrays.asList("ADMIN_AP", "TATA_AP_EFFACEC"));

private SclAutomationService(){throw new IllegalStateException("SclAutomationService class"); }
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
Expand All @@ -48,13 +50,14 @@ public class SclAutomationService {
*/
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());
if(!headerDTO.getHistoryItems().isEmpty()) {
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());
}
SubstationService.addSubstation(scdAdapter.getCurrentElem(), ssd);
SclService.importSTDElementsInSCD(scdAdapter, stds, comMap);
SclService.removeAllControlBlocksAndDatasetsAndExtRefSrcBindings(scdAdapter.getCurrentElem());
return scdAdapter;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.lfenergy.compas.scl2007b4.model.LN0;
import org.lfenergy.compas.scl2007b4.model.SCL;
import org.lfenergy.compas.sct.commons.dto.HeaderDTO;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
import org.lfenergy.compas.sct.commons.scl.ied.LDeviceAdapter;
import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Arrays;
import java.util.HashSet;
import java.util.Set;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.junit.jupiter.api.Assertions.*;
import static org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller.assertIsMarshallable;

Expand All @@ -24,7 +31,7 @@ class SclAutomationServiceTest {
private HeaderDTO headerDTO;

@BeforeEach
void init(){
void init() {
headerDTO = new HeaderDTO();
headerDTO.setRevision("hRevision");
headerDTO.setVersion("hVersion");
Expand Down Expand Up @@ -63,7 +70,7 @@ void createSCD_With_HItem() throws Exception {
SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std1, std2, std3));
// Then
assertNotNull(expectedSCD.getCurrentElem().getHeader().getId());
assertEquals(1 ,expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size());
assertEquals(1, expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size());
assertEquals(1, expectedSCD.getCurrentElem().getSubstation().size());
assertIsMarshallable(expectedSCD.getCurrentElem());
}
Expand All @@ -85,7 +92,7 @@ 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));
SclRootAdapter expectedSCD = SclAutomationService.createSCD(ssd, headerDTO, Set.of(std1, std2, std3));
// Then
assertNotNull(expectedSCD.getCurrentElem().getHeader().getId());
assertEquals(1, expectedSCD.getCurrentElem().getHeader().getHistory().getHitem().size());
Expand All @@ -98,8 +105,68 @@ void createSCD_SSD_Without_Substation() throws Exception {
// Given
SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd_without_substations.xml");
// When & Then
Set<SCL> stdListEmpty = new HashSet<>();
assertThrows(ScdException.class,
() -> SclAutomationService.createSCD(ssd, headerDTO, new HashSet<>()) );
() -> SclAutomationService.createSCD(ssd, headerDTO, stdListEmpty));
}

@Test
void createSCD_should_throw_exception_when_null_ssd() throws Exception {
// 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);

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

@Test
void createSCD_should_throw_exception_when_null_headerDTO() throws Exception {
// Given
SCL ssd = SclTestMarshaller.getSCLFromFile("/scd-substation-import-ssd/ssd.xml");
SCL std1 = SclTestMarshaller.getSCLFromFile("/std_1.xml");
Set<SCL> stdList = Set.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 {
// 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));
// Then
LN0 ln0 = expectedSCD.streamIEDAdapters()
.findFirst()
.map(iedAdapter -> iedAdapter.getLDeviceAdapterByLdInst("lDeviceInst1").orElseThrow())
.map(LDeviceAdapter::getLN0Adapter)
.map(SclElementAdapter::getCurrentElem)
.orElseThrow(() -> new RuntimeException("Test shouldn't fail here, please check your XML input file"));

assertThat(ln0.getDataSet()).isEmpty();
assertThat(ln0.getInputs().getExtRef()).hasSize(2);
assertFalse(ln0.getInputs().getExtRef().get(0).isSetSrcLDInst());
assertIsMarshallable(expectedSCD.getCurrentElem());
}

@Test
void class_should_not_be_instantiable() {
// Given
Constructor<?>[] constructors = SclAutomationService.class.getDeclaredConstructors();
assertThat(constructors).hasSize(1);
Constructor<?> constructor = constructors[0];
constructor.setAccessible(true);
// When & Then
assertThatThrownBy(constructor::newInstance)
.isInstanceOf(InvocationTargetException.class)
.getCause().isInstanceOf(UnsupportedOperationException.class);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,11 @@
import lombok.NoArgsConstructor;
import lombok.Setter;
import org.apache.commons.lang3.StringUtils;
import org.lfenergy.compas.scl2007b4.model.TExtRef;
import org.lfenergy.compas.scl2007b4.model.TLLN0Enum;
import org.lfenergy.compas.scl2007b4.model.TServiceType;
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.exception.ScdException;
import org.lfenergy.compas.sct.commons.scl.dtt.DATypeAdapter;
import org.lfenergy.compas.sct.commons.scl.dtt.DOTypeAdapter;
import org.lfenergy.compas.sct.commons.scl.dtt.DataTypeTemplateAdapter;

import java.util.Comparator;
import java.util.Objects;
Expand Down Expand Up @@ -181,4 +183,29 @@ public String toString() {
'}';

}

/**
* updates bindingInfo from given data
* @param signalInfo contains DAType info to set
* @param doTypeInfo contains DOType info leading to DA
* @throws ScdException thrown when inconsistency between DOType and DAType
*/
public void updateDAInfos(ExtRefSignalInfo signalInfo, DataTypeTemplateAdapter.DOTypeInfo doTypeInfo) throws ScdException {
DaTypeName daTypeName = new DaTypeName(signalInfo.getPDA());
String extDaName = daTypeName.getName();
DOTypeAdapter lastDoTypeAdapter = doTypeInfo.getDoTypeAdapter();
TDA da = lastDoTypeAdapter.getDAByName(extDaName).orElseThrow(() ->
new ScdException(String.format("%s: Unknown DA (%s) in DOType (%s) ", doTypeInfo.getDoTypeName(), extDaName, doTypeInfo.getDoTypeId())));
if (da.getBType() != TPredefinedBasicTypeEnum.STRUCT && !daTypeName.getStructNames().isEmpty()
|| da.getBType() == TPredefinedBasicTypeEnum.STRUCT && daTypeName.getStructNames().isEmpty()) {
throw new ScdException(String.format("Invalid ExtRef signal: no coherence between pDO(%s) and pDA(%s)",
signalInfo.getPDO(), signalInfo.getPDA()));
}
String daTypeId = da.getType();
DATypeAdapter daTypeAdapter = lastDoTypeAdapter.getParentAdapter().getDATypeAdapterById(daTypeId).orElseThrow(() ->
new IllegalArgumentException(String.format("%s: Unknown DA (%s), or no reference to its type", daTypeName, extDaName)));
daTypeAdapter.check(daTypeName);
daTypeName.setFc(da.getFc());
this.daName = daTypeName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -264,9 +264,7 @@ public static List<ExtRefBindingInfo> getExtRefBinders(SCL scd, String iedName,
.build();

// check for signal existence
// The below throws exception if the signal doesn't exist
//TODO: create method which purpose is only ckecking instead of this one
abstractLNAdapter.getExtRefsBySignalInfo(signalInfo);
abstractLNAdapter.isExtRefExist(signalInfo);

// find potential binders for the signalInfo
return sclRootAdapter.streamIEDAdapters()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
* A representation of the model object
Expand Down Expand Up @@ -195,13 +196,7 @@ protected String elementXPath() {
* @return <em>Boolean</em> value of check result
*/
public boolean containsDAWithDAName(String da){
return currentElem.getSDOOrDA()
.stream()
.filter(unNaming -> unNaming.getClass().equals(TDA.class))
.map(TDA.class::cast)
.anyMatch(
tda -> tda.getName().equals(da)
);
return getTdaStream().anyMatch(tda -> tda.getName().equals(da));
}

/**
Expand All @@ -210,10 +205,7 @@ public boolean containsDAWithDAName(String da){
* @return <em>Boolean</em> value of check result
*/
public boolean containsDAWithEnumTypeId(String enumTypeId) {
return currentElem.getSDOOrDA()
.stream()
.filter(unNaming -> unNaming.getClass().equals(TDA.class))
.map(TDA.class::cast)
return getTdaStream()
.anyMatch(
tda -> tda.getBType().equals(TPredefinedBasicTypeEnum.ENUM) &&
tda.getType().equals(enumTypeId)
Expand All @@ -227,7 +219,7 @@ public boolean containsDAWithEnumTypeId(String enumTypeId) {
* @throws ScdException when inconsistency are found in th SCL's
* DataTypeTemplate (unknown reference for example). Which should normally not happens.
*/
Pair<String,DOTypeAdapter> findPathDoType2DA(String daName) throws ScdException {
public Pair<String,DOTypeAdapter> findPathDoTypeToDA(String daName) throws ScdException {
if(containsDAWithDAName(daName)){
// Attention : Do this check before calling this function
// It is not interesting to no have the DO/SDO that references this DoType
Expand Down Expand Up @@ -266,7 +258,7 @@ Pair<String,DOTypeAdapter> findPathDoType2DA(String daName) throws ScdException
* @throws ScdException when inconsistency are found in th SCL's
* DataTypeTemplate (unknown reference for example). Which should normally not happens.
*/
Pair<String,DOTypeAdapter> findPathSDO2DA(String sdoName, String daName) throws ScdException {
Pair<String,DOTypeAdapter> findPathSDOToDA(String sdoName, String daName) throws ScdException {
String errMsg = String.format("No coherence or path between DO/SDO(%s) and DA(%s)", sdoName,daName);
Optional<TSDO> opSdo = getSDOByName(sdoName);
if(opSdo.isEmpty()) {
Expand All @@ -280,7 +272,7 @@ Pair<String,DOTypeAdapter> findPathSDO2DA(String sdoName, String daName) throws
if(doTypeAdapter.containsDAWithDAName(daName)){
return Pair.of(opSdo.get().getName(),doTypeAdapter);
}
return doTypeAdapter.findPathDoType2DA(daName);
return doTypeAdapter.findPathDoTypeToDA(daName);
}

/**
Expand All @@ -289,10 +281,7 @@ Pair<String,DOTypeAdapter> findPathSDO2DA(String sdoName, String daName) throws
* @return <em>Boolean</em> value of check result
*/
public boolean containsDAStructWithDATypeId(String daTypeId) {
return currentElem.getSDOOrDA()
.stream()
.filter(unNaming -> unNaming.getClass().equals(TDA.class))
.map(TDA.class::cast)
return getTdaStream()
.anyMatch(
tda -> TPredefinedBasicTypeEnum.STRUCT.equals(tda.getBType()) &&
tda.getType().equals(daTypeId)
Expand Down Expand Up @@ -422,12 +411,30 @@ public Optional<TSDO> getSDOByName(String sdoName) {
* @return optional of <em>TDA</em> object or empty if unknown DA name
*/
public Optional<TDA> getDAByName(String name) {
for(TUnNaming tUnNaming : currentElem.getSDOOrDA()){
if(tUnNaming.getClass() == TDA.class && ((TDA)tUnNaming).getName().equals(name)){
return Optional.of((TDA)tUnNaming);
}
TDOType tdoType = currentElem;
if (!containsDAWithDAName(name)) {
tdoType = findPathDoTypeToDA(name)
.getValue()
.getCurrentElem();
}
return Optional.empty();
return tdoType.getSDOOrDA()
.stream()
.filter(unNaming -> unNaming.getClass().equals(TDA.class)
&& ((TDA)unNaming).getName().equals(name))
.map(TDA.class::cast)
.findFirst();
}

/**
* Retrieves all TDA in DOType
* @return stream of TDA
*/
private Stream<TDA> getTdaStream() {
return getCurrentElem()
.getSDOOrDA()
.stream()
.filter(unNaming -> unNaming.getClass().equals(TDA.class))
.map(TDA.class::cast);
}

/**
Expand Down
Loading