Skip to content

Commit 7a7f680

Browse files
authored
Merge pull request #268 from com-pas/develop
New release
2 parents adebd26 + 2e44581 commit 7a7f680

30 files changed

+1671
-271
lines changed

.github/workflows/release-project.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ name: Release Project
66

77
on:
88
release:
9-
types: [ released ]
9+
types: [ published ]
1010

1111
jobs:
1212
publish:
@@ -42,4 +42,4 @@ jobs:
4242
- name: Deploy with Maven to GitHub Packages
4343
run: mvn --batch-mode -s custom_maven_settings.xml clean deploy
4444
env:
45-
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
45+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// SPDX-FileCopyrightText: 2023 RTE FRANCE
2+
//
3+
// SPDX-License-Identifier: Apache-2.0
4+
5+
package org.lfenergy.compas.sct.commons.dto;
6+
7+
import java.util.List;
8+
9+
/**
10+
* Represents a list of LDEPF settings
11+
* This is a functional interface whose functional method is getLDEPFSettings
12+
* the type of the input to the operation
13+
*
14+
* @param <T> the type of the result of the LDEPFSettings
15+
*
16+
* @see org.lfenergy.compas.sct.commons.util.SettingLDEPFCsvHelper
17+
*/
18+
@FunctionalInterface
19+
public interface LDEPFSettings<T> {
20+
21+
/**
22+
* This method provides list of LDEPF settings
23+
*/
24+
List<T> getSettings();
25+
}

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/dto/ResumedDataTemplate.java

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.fasterxml.jackson.annotation.JsonIgnore;
88
import lombok.*;
99
import org.lfenergy.compas.scl2007b4.model.*;
10+
import org.lfenergy.compas.sct.commons.scl.ied.AbstractLNAdapter;
1011
import org.lfenergy.compas.sct.commons.util.SclConstructorHelper;
1112

1213
import java.util.ArrayList;
@@ -50,12 +51,25 @@ public class ResumedDataTemplate {
5051
@NonNull
5152
private DaTypeName daName = new DaTypeName("");
5253

54+
/**
55+
* Constructor
56+
*/
57+
public ResumedDataTemplate(AbstractLNAdapter<?> lnAdapter, String doName, String daName) {
58+
this.lnClass = lnAdapter.getLNClass();
59+
this.lnInst = lnAdapter.getLNInst();
60+
this.prefix = lnAdapter.getPrefix();
61+
this.lnType = lnAdapter.getLnType();
62+
this.doName = new DoTypeName(doName);
63+
this.daName = new DaTypeName(daName);
64+
}
65+
5366
/**
5467
* Copies summarized DataTypeTemplate information to another one
68+
*
5569
* @param dtt input
5670
* @return Updated ResumedDataTemplate object
5771
*/
58-
public static ResumedDataTemplate copyFrom(ResumedDataTemplate dtt){
72+
public static ResumedDataTemplate copyFrom(ResumedDataTemplate dtt) {
5973
ResumedDataTemplate resumedDataTemplate = new ResumedDataTemplate();
6074
resumedDataTemplate.prefix = dtt.prefix;
6175
resumedDataTemplate.lnClass = dtt.lnClass;

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ExtRefService.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import org.apache.commons.lang3.StringUtils;
99
import org.lfenergy.compas.scl2007b4.model.SCL;
1010
import org.lfenergy.compas.scl2007b4.model.TCompasICDHeader;
11+
import org.lfenergy.compas.scl2007b4.model.TExtRef;
1112
import org.lfenergy.compas.scl2007b4.model.TIED;
1213
import org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings;
1314
import org.lfenergy.compas.sct.commons.dto.SclReport;
@@ -27,6 +28,7 @@
2728
import java.util.stream.Stream;
2829

2930
import static org.lfenergy.compas.sct.commons.dto.ControlBlockNetworkSettings.*;
31+
import static org.lfenergy.compas.sct.commons.util.Utils.isExtRefFeedBySameControlBlock;
3032

3133
@UtilityClass
3234
public class ExtRefService {
@@ -226,4 +228,19 @@ private static Optional<SclReportItem> configureControlBlockNetwork(ControlBlock
226228
return controlBlockAdapter.configureNetwork(appIdIterator.nextLong(), macAddressIterator.next(), settings.vlanId(), settings.vlanPriority(),
227229
settings.minTime(), settings.maxTime());
228230
}
231+
232+
233+
/**
234+
* Remove ExtRef which are fed by same Control Block
235+
*
236+
* @return list ExtRefs without duplication
237+
*/
238+
public static List<TExtRef> filterDuplicatedExtRefs(List<TExtRef> tExtRefs) {
239+
List<TExtRef> filteredList = new ArrayList<>();
240+
tExtRefs.forEach(tExtRef -> {
241+
if (filteredList.stream().noneMatch(t -> isExtRefFeedBySameControlBlock(tExtRef, t)))
242+
filteredList.add(tExtRef);
243+
});
244+
return filteredList;
245+
}
229246
}

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/SclService.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ public class SclService {
8080

8181
private static final String UNKNOWN_LDEVICE_S_IN_IED_S = "Unknown LDevice (%s) in IED (%s)";
8282
private static final String INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO = "Invalid or missing attributes in ExtRef binding info";
83+
private static final String IED_TEST_NAME = "IEDTEST";
8384

8485
private SclService() {
8586
throw new IllegalStateException("SclService class");
@@ -609,4 +610,20 @@ public static SclReport updateDoInRef(SCL scd) {
609610
.toList();
610611
return new SclReport(sclRootAdapter, sclReportItems);
611612
}
613+
614+
/**
615+
* Update and/or create Monitoring LNs (LSVS and LGOS) for bound GOOSE and SMV Control Blocks
616+
*
617+
* @param scd SCL file for which LNs (LSVS and LGOS) should be updated and/or created in each LDevice LDSUIED with matching ExtRef information
618+
* @return SclReport Object that contain SCL file and set of errors
619+
*/
620+
public static SclReport manageMonitoringLns(SCL scd) {
621+
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
622+
List<SclReportItem> sclReportItems = sclRootAdapter.streamIEDAdapters()
623+
.filter(iedAdapter -> !iedAdapter.getName().contains(IED_TEST_NAME))
624+
.map(IEDAdapter::manageMonitoringLns)
625+
.flatMap(List::stream)
626+
.toList();
627+
return new SclReport(sclRootAdapter, sclReportItems);
628+
}
612629
}

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/AccessPointAdapter.java

Lines changed: 17 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import java.util.stream.Collectors;
1818
import java.util.stream.Stream;
1919

20+
import static org.lfenergy.compas.sct.commons.scl.ExtRefService.filterDuplicatedExtRefs;
21+
2022
/**
2123
* A representation of the model object
2224
* <em><b>{@link org.lfenergy.compas.scl2007b4.model.TAccessPoint AccessPoint}</b></em>.
@@ -35,7 +37,6 @@
3537
public class AccessPointAdapter extends SclElementAdapter<IEDAdapter, TAccessPoint> {
3638

3739
public static final long MAX_OCCURRENCE_NO_LIMIT_VALUE = -1L;
38-
private static final String CLIENT_IED_NAME = "The Client IED ";
3940

4041
/**
4142
* Constructor
@@ -219,7 +220,7 @@ public Optional<SclReportItem> checkLimitationForBoundIedFcdas(List<TExtRef> tEx
219220
* @param sclReportItems
220221
* @param tExtRefs
221222
*/
222-
record ExtRefAnalyzeRecord(List<SclReportItem> sclReportItems, List<TExtRef> tExtRefs) {
223+
public record ExtRefAnalyzeRecord(List<SclReportItem> sclReportItems, List<TExtRef> tExtRefs) {
223224
}
224225

225226
/**
@@ -229,21 +230,20 @@ record ExtRefAnalyzeRecord(List<SclReportItem> sclReportItems, List<TExtRef> tEx
229230
*/
230231
public ExtRefAnalyzeRecord getAllCoherentExtRefForAnalyze() {
231232
List<SclReportItem> sclReportItems = new ArrayList<>();
232-
List<TExtRef> tExtRefList = new ArrayList<>();
233-
streamLDeviceAdapters().map(lDeviceAdapter -> {
234-
List<TExtRef> extRefs = lDeviceAdapter.getLN0Adapter().getExtRefs().stream().filter(TExtRef::isSetSrcCBName).collect(Collectors.toCollection(ArrayList::new));
235-
sclReportItems.addAll(checkExtRefWithoutServiceType(extRefs, lDeviceAdapter.getLN0Adapter().getXPath()));
236-
extRefs.removeIf(tExtRef -> !tExtRef.isSetServiceType());
237-
return extRefs;
238-
}).flatMap(Collection::stream).forEach(tExtRef -> {
239-
if (tExtRefList.isEmpty())
240-
tExtRefList.add(tExtRef);
241-
else {
242-
if (tExtRefList.stream().noneMatch(t -> isExtRefFeedBySameControlBlock(tExtRef, t)))
243-
tExtRefList.add(tExtRef);
244-
}
245-
});
246-
return new ExtRefAnalyzeRecord(sclReportItems, tExtRefList);
233+
List<TExtRef> tExtRefList = streamLDeviceAdapters()
234+
.map(LDeviceAdapter::getLN0Adapter)
235+
.map(ln0Adapter -> {
236+
List<TExtRef> extRefs = new ArrayList<>();
237+
if (ln0Adapter.hasInputs()) {
238+
extRefs.addAll(ln0Adapter.getInputsAdapter().filterDuplicatedExtRefs()
239+
.stream().filter(TExtRef::isSetSrcCBName).collect(Collectors.toCollection(ArrayList::new)));
240+
sclReportItems.addAll(checkExtRefWithoutServiceType(extRefs, ln0Adapter.getXPath()));
241+
extRefs.removeIf(tExtRef -> !tExtRef.isSetServiceType());
242+
}
243+
return extRefs;
244+
}).flatMap(Collection::stream)
245+
.toList();
246+
return new ExtRefAnalyzeRecord(sclReportItems, filterDuplicatedExtRefs(tExtRefList));
247247
}
248248

249249
/**
@@ -262,25 +262,6 @@ private List<SclReportItem> checkExtRefWithoutServiceType(List<TExtRef> tExtRefs
262262
.toList();
263263
}
264264

265-
/**
266-
* Checks if two ExtRefs fed by same Control Block for SCL limits analyze
267-
* Nota : this equality is only for checking limitation check
268-
*
269-
* @param t1 extref to compare
270-
* @param t2 extref to compare
271-
* @return true if the two ExtRef are fed by same Control Block, otherwise false
272-
*/
273-
private static boolean isExtRefFeedBySameControlBlock(TExtRef t1, TExtRef t2) {
274-
String srcLNClass1 = (t1.isSetSrcLNClass()) ? t1.getSrcLNClass().get(0) : TLLN0Enum.LLN_0.value();
275-
String srcLNClass2 = (t2.isSetSrcLNClass()) ? t2.getSrcLNClass().get(0) : TLLN0Enum.LLN_0.value();
276-
return Utils.equalsOrBothBlank(t1.getIedName(), t2.getIedName())
277-
&& Utils.equalsOrBothBlank(t1.getSrcLDInst(), t2.getSrcLDInst())
278-
&& srcLNClass1.equals(srcLNClass2)
279-
&& Utils.equalsOrBothBlank(t1.getSrcLNInst(), t2.getSrcLNInst())
280-
&& Utils.equalsOrBothBlank(t1.getSrcPrefix(), t2.getSrcPrefix())
281-
&& t1.getServiceType().equals(t2.getServiceType());
282-
}
283-
284265
/**
285266
* Checks Control Blocks (Report, Goose, SMV) number limitation for bound IED
286267
*
@@ -300,7 +281,6 @@ public List<SclReportItem> checkLimitationForBoundIEDControls(List<TExtRef> tExt
300281
* Checks Control Block number limitation for bound IED
301282
*
302283
* @param tExtRefs list of ExtRefs referenced same ied
303-
* @param msg message to display hen error occured
304284
* @param servicesConfigEnum type of Control Block for which check is done
305285
* @return Optional of encountered error or empty
306286
*/

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ied/DOIAdapter.java

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import org.lfenergy.compas.scl2007b4.model.*;
88
import org.lfenergy.compas.sct.commons.dto.ExtrefTarget;
9+
import org.lfenergy.compas.sct.commons.dto.ResumedDataTemplate;
910
import org.lfenergy.compas.sct.commons.dto.SclReportItem;
1011
import org.lfenergy.compas.sct.commons.scl.ObjectReference;
1112
import org.lfenergy.compas.sct.commons.scl.SclElementAdapter;
@@ -109,36 +110,45 @@ public AbstractDAIAdapter<?> toAdapter(TDAI childTDAI) {
109110
* @return a filled SclReportItem if an error occurs, empty SclReportItem otherwise
110111
*/
111112
public Optional<SclReportItem> updateDaiFromExtRef(List<TExtRef> tExtRefs) {
113+
Optional<SclReportItem> optionalSclReportItem;
112114
Optional<TExtRef> tExtRefMinOptional = tExtRefs.stream().min(EXTREF_DESC_SUFFIX_COMPARATOR);
113-
114115
if (tExtRefMinOptional.isPresent() && extractDescSuffix(tExtRefMinOptional.get().getDesc()) == 1) {
115116
TExtRef tExtRefMin = tExtRefMinOptional.get();
116-
findDataAdapterByName(DA_NAME_SET_SRC_REF)
117-
.orElse(addDAI(DA_NAME_SET_SRC_REF, true))
118-
.setVal(createInRefValNominalString(tExtRefMin));
117+
String valueSrcRef = createInRefValNominalString(tExtRefMin);
118+
optionalSclReportItem = updateDAI(DA_NAME_SET_SRC_REF, valueSrcRef);
119119
if (tExtRefMin.isSetSrcCBName()) {
120-
findDataAdapterByName(DA_NAME_SET_SRC_CB)
121-
.orElse(addDAI(DA_NAME_SET_SRC_CB, true))
122-
.setVal(createInRefValTestString(tExtRefMin));
120+
String valueSrcCb = createInRefValTestString(tExtRefMin);
121+
optionalSclReportItem = updateDAI(DA_NAME_SET_SRC_CB, valueSrcCb);
123122
}
124123

125124
Optional<TExtRef> tExtRefMaxOptional = tExtRefs.stream().max(EXTREF_DESC_SUFFIX_COMPARATOR);
126125
if (tExtRefMaxOptional.isPresent() && extractDescSuffix(tExtRefMaxOptional.get().getDesc()) > 1) {
127126
TExtRef tExtRefMax = tExtRefMaxOptional.get();
128-
findDataAdapterByName(DA_NAME_SET_TST_REF)
129-
.orElse(addDAI(DA_NAME_SET_TST_REF, true))
130-
.setVal(createInRefValNominalString(tExtRefMax));
127+
String valueTstRef = createInRefValNominalString(tExtRefMax);
128+
optionalSclReportItem = updateDAI(DA_NAME_SET_TST_REF, valueTstRef);
131129
if (tExtRefMax.isSetSrcCBName()) {
132-
findDataAdapterByName(DA_NAME_SET_TST_CB)
133-
.orElse(addDAI(DA_NAME_SET_TST_CB, true))
134-
.setVal(createInRefValTestString(tExtRefMax));
130+
String valueTstCb = createInRefValTestString(tExtRefMax);
131+
optionalSclReportItem = updateDAI(DA_NAME_SET_TST_CB, valueTstCb);
135132
}
136133
}
137134
} else {
138-
return Optional.of(SclReportItem.warning(getXPath(), "The DOI %s can't be bound with an ExtRef".formatted(getXPath())));
135+
optionalSclReportItem = Optional.of(SclReportItem.warning(getXPath(), "The DOI %s can't be bound with an ExtRef".formatted(getXPath())));
139136
}
140137

138+
return optionalSclReportItem;
139+
}
140+
141+
private Optional<SclReportItem> updateDAI(String daName, String value) {
142+
ResumedDataTemplate daiFilterSrcRef = new ResumedDataTemplate(getParentAdapter(), getName(), daName);
143+
Optional<ResumedDataTemplate> foundDais = getParentAdapter().getDAI(daiFilterSrcRef, true).stream().findFirst();
144+
if (foundDais.isEmpty()) {
145+
return Optional.of(SclReportItem.warning(getXPath() + "/DAI@name=\"" + daName + "\"/Val", "The DAI cannot be updated"));
146+
}
147+
ResumedDataTemplate filterForUpdate = foundDais.get();
148+
filterForUpdate.setVal(value);
149+
getParentAdapter().updateDAI(filterForUpdate);
141150
return Optional.empty();
151+
142152
}
143153

144154
private static int extractDescSuffix(String desc) throws NumberFormatException {

0 commit comments

Comments
 (0)