Skip to content

Commit 78853d1

Browse files
authored
Merge pull request #51 from com-pas/dai-management
Dai management
2 parents 317054b + ff94116 commit 78853d1

File tree

138 files changed

+5566
-2328
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

138 files changed

+5566
-2328
lines changed

doc/compas-sct.md

Lines changed: 105 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ The below package diagram shows different part of the tool architecture.
1717
Hence, we can distinguish four major parts:
1818

1919
* **[sct-commons](#SCT-COMMONS)** : a library that contents shared functionalities for the bound SCL object.
20-
* **[sct-service](#SCT-SERVICE)** : It computes all needed operations and uses sct-data for database access.
2120
* **[sct-data](#SCT-DATA)** : It holds data models and database connectivity services.
2221
* **[sct-app](#SCT-APPLICATION)** : *TODO*.
2322

@@ -39,21 +38,36 @@ abstraction defined below :
3938
protected P parentAdapter;
4039
protected T currentElem;
4140

42-
public SclElementAdapter(P parentAdapter) {
41+
protected SclElementAdapter(P parentAdapter) {
4342
this.parentAdapter = parentAdapter;
4443
}
4544

46-
public SclElementAdapter(P parentAdapter, T currentElem) {
45+
protected SclElementAdapter(P parentAdapter, T currentElem) {
46+
if(currentElem == null){
47+
throw new IllegalArgumentException("The SCL element to adapt must be defined");
48+
}
4749
this.parentAdapter = parentAdapter;
50+
this.customInit();
4851
setCurrentElem(currentElem);
4952
}
5053

54+
55+
protected boolean amRootElement(){
56+
return parentAdapter == null;
57+
}
58+
59+
protected void customInit() {
60+
// do nothing
61+
}
5162
public final void setCurrentElem(T currentElem){
52-
Assert.isTrue(amChildElementRef(currentElem),"No relation between SCL parent and child elements");
5363
this.currentElem = currentElem;
64+
if(!amRootElement() && !amChildElementRef()){
65+
throw new IllegalArgumentException("No relation between SCL parent element and child");
66+
}
5467
}
5568

56-
protected abstract boolean amChildElementRef(T sclElement);
69+
protected abstract boolean amChildElementRef();
70+
5771
}
5872

5973
The root element adapter (entry point) is special as it does not have any parent adapter, hence, its method `amChildElementRef(T)`
@@ -82,23 +96,101 @@ should always return `true`:
8296
[...]
8397
}
8498

85-
86-
8799
## SCT DATA
88100
Data models and connectivity to database are defined here. Data access layer is an abstract layer that defined connectivity
89101
interfaces. This layer manages a database with single table (SQL-Like database) or single collection (NoSQL-Like database).
90-
The concrete data access layers are implemented in specific packages
102+
The concrete data access layers are implemented in specific packages. A data model can implement the following interface
103+
104+
```
105+
public interface IScd <ID> {
106+
ID getId();
107+
byte[] getRawXml();
108+
ID getHeaderId();
109+
String getHeaderRevision();
110+
String getHeaderVersion();
111+
String filename();
112+
}
113+
```
91114

92115
* ### SQL-Like Database
93116
An implementation of the sct-data connectivity interface with custom data models. This allows the application to work with sql-like database.
94117
The libraries ares use for SQL-Like databases, those that support XML type (PostgreSql, Oracle, etc)
95118

96119
* ### NoSQL-Like Database
97120
Like SQL-like part, this package contains the sct-data connector interfaces implementation for NoSQL-Like databases (BaseX, existDB, etc )
98-
that support XML processing
121+
that support XML processing.
122+
123+
This can also be a local repository connector (file system). For example, with meta-data headerID, headerVersion, headerRevision and filename
124+
one can implement the connector to have the below output (with the constraint of having a single file in /pathTo/headerId/headerVersion/headerRevision):
125+
126+
```
127+
myRepo
128+
├───<headerID>
129+
│ ├───<headerVersion1>
130+
│ │ └───<headerRevision1>
131+
│ │ | ├───<fileName1.scd>
132+
│ │ └───<headerRevision2>
133+
│ │ ├───<fileName2.scd>
134+
```
99135

100-
## SCT SERVICE
101-
This module implements all needed specification as functions (methods in Java). As shown in package diagram,
102-
it interacts with sct-data (database access) and sct-commons (delegate SCL manipulation).
103136
## SCT APPLICATION
104-
**TODO**
137+
**TODO**
138+
> In progress
139+
140+
### Tips for memory consumption's optimization
141+
For large SCL file, it is not a good idea to load the whole file in memory. JAXB is capable of processing XML file by chunks.
142+
The need to load the whole SCL file relies on the fact that XML validation processes needs the entire file content.
143+
To go through that process we must take advantage of the XSD constraints and build minimal SCL file from the large one.
144+
The most "important" tags in the SCL file are: Header, Substation, Communication, IED and DataTypeTemplate. By looking closely in the XSD file, one can realize
145+
the below dependencies' logic :
146+
* Substation is grammatically independent
147+
* IED depends on DataTypeTemplate
148+
* Communication depends on IED (IED name, Access Point, ...)
149+
150+
Hence, with this in mind, one can reconstruct a minimal SCL file by focusing on the chunk of interest then realize creation/update operations
151+
on the file and validate it against the XSD file.
152+
153+
For example: Updating IED
154+
155+
From SCD header's information, create a minimal valid SCD file
156+
```
157+
<SCL version="2007" revision="B" release="4" xmlns="http://www.iec.ch/61850/2003/SCL">
158+
<Header id="hId" version="2007" revision="B" toolID="COMPAS"/>
159+
</SCL>
160+
```
161+
As IED depends on DataTypeTemplate, extract the IED chunk with the whole DataTypeTemplate chunk from the large file and
162+
import it in the temporary SCD file
163+
```
164+
<SCL version="2007" revision="B" release="4" xmlns="http://www.iec.ch/61850/2003/SCL">
165+
<Header id="hId" version="2007" revision="B" toolID="COMPAS"/>
166+
<IED name="IED_NAME">
167+
<AccessPoint>....</AccessPoint>
168+
</IED>
169+
<DataTypeTemplate>....</DataTypeTemplate>
170+
</SCL>
171+
```
172+
Operations can now be realized and validated on this minimal file (which has the same structure as an ICD file).
173+
Any validation on the minimal file guaranties a valid integration of those chunks into the large file.
174+
175+
> **WARNING:** This concern only update/creation operations on SCL file.
176+
177+
Operations on the tag Substation are not complicated (those are similar to SSD files).
178+
179+
For Communication tag, a minimal valid IED tag with child tag Access point can suffice. If the IED's logical nodes
180+
are concerned in the process, one should think of bringing along the DataTypeTemplate chunk.
181+
182+
```
183+
<SCL xmlns="http://www.iec.ch/61850/2003/SCL" version="2007" revision="B" release="4">
184+
<Header id="cccc"></Header>
185+
<Communication>
186+
<SubNetwork name="tt">
187+
<ConnectedAP iedName="IED" apName="AP"></ConnectedAP>
188+
</SubNetwork>
189+
</Communication>
190+
<IED name="IED"> <!-- minimal valid IED to avoid using DataTypeTemplate-->
191+
<AccessPoint name="AP"></AccessPoint>
192+
</IED>
193+
</SCL>
194+
```
195+
Combination like this can heavily optimize memory consumption while manipulating large SCD file.
196+

doc/drawio/compas-sct.drawio

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
<mxfile host="app.diagrams.net" modified="2021-08-23T14:01:51.473Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.107 Safari/537.36 Edg/92.0.902.55" etag="uZeMYTGyEtbajDSc3TgE" version="14.9.8" type="device"><diagram id="3wWlgGhNNHLo4Hu9hpyk" name="Page-1">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</diagram></mxfile>
1+
<mxfile host="app.diagrams.net" modified="2022-01-11T09:05:14.268Z" agent="5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.57" etag="oE0U5b2gp_jQ03X_KlPB" version="15.9.4" type="device"><diagram id="3wWlgGhNNHLo4Hu9hpyk" name="Page-1">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</diagram></mxfile>
-841 Bytes
Loading

pom.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,13 @@
4141
<groupId>org.junit.jupiter</groupId>
4242
<artifactId>junit-jupiter-api</artifactId>
4343
<version>5.7.2</version>
44+
<scope>test</scope>
4445
</dependency>
4546
<dependency>
4647
<groupId>org.junit.jupiter</groupId>
4748
<artifactId>junit-jupiter-engine</artifactId>
4849
<version>5.7.2</version>
50+
<scope>test</scope>
4951
</dependency>
5052
<dependency>
5153
<groupId>org.lfenergy.compas.core</groupId>
@@ -73,8 +75,6 @@
7375
<module>sct-commons</module>
7476
<module>sct-coverage</module>
7577
<module>sct-data</module>
76-
<module>sct-data-pg</module>
77-
<module>sct-service</module>
7878
</modules>
7979

8080
<build>

sct-commons/pom.xml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,12 @@
9494
<artifactId>jakarta.annotation-api</artifactId>
9595
<version>1.3.5</version>
9696
</dependency>
97+
<dependency>
98+
<groupId>org.glassfish.jaxb</groupId>
99+
<artifactId>jaxb-runtime</artifactId>
100+
<version>2.3.1</version>
101+
<scope>compile</scope>
102+
</dependency>
97103
</dependencies>
98104
<build>
99105
<plugins>

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/Utils.java

Lines changed: 17 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -16,45 +16,38 @@ private Utils() {
1616
}
1717

1818
public static String entering(){
19-
StringBuilder stringBuilder = new StringBuilder();
20-
stringBuilder.append(">>> ");
21-
stringBuilder.append("Entering: ");
22-
stringBuilder.append("-::");
23-
stringBuilder.append(getMethodName());
24-
return stringBuilder.toString();
19+
return ">>> " +
20+
"Entering: " +
21+
"-::" +
22+
getMethodName();
2523
}
2624

2725
public static String leaving(Long startTime){
2826
if(startTime == null || startTime <= 0){
2927
return leaving();
3028
}
31-
StringBuilder stringBuilder = new StringBuilder();
32-
stringBuilder.append("<<< ");
33-
stringBuilder.append("Leaving: ");
34-
stringBuilder.append("-::");
35-
stringBuilder.append(getMethodName());
36-
stringBuilder.append(" - Timer duration: ");
37-
stringBuilder.append((System.nanoTime() - startTime)/Math.pow(10,9));
38-
stringBuilder.append(" sec.");
39-
return stringBuilder.toString();
29+
return "<<< " +
30+
"Leaving: " +
31+
"-::" +
32+
getMethodName() +
33+
" - Timer duration: " +
34+
(System.nanoTime() - startTime) / Math.pow(10, 9) +
35+
" sec.";
4036
}
4137

4238
public static String getMethodName() {
4339
try {
4440
return (new Throwable()).getStackTrace()[2].getMethodName();
4541
} catch (Exception e){
46-
// do nothing
42+
return "-";
4743
}
48-
return "-";
4944
}
5045

5146
public static String leaving(){
52-
StringBuilder stringBuilder = new StringBuilder();
53-
stringBuilder.append("<<< ");
54-
stringBuilder.append("Leaving: ");
55-
stringBuilder.append("::");
56-
stringBuilder.append(getMethodName());
57-
return stringBuilder.toString();
47+
return "<<< " +
48+
"Leaving: " +
49+
"::" +
50+
getMethodName();
5851
}
5952

6053
/**
@@ -66,6 +59,7 @@ public static Field getField(Class<?> clazz, String name) {
6659
try {
6760
field = clazz.getDeclaredField(name);
6861
} catch (Exception e) {
62+
log.error("Cannot find field name {}", name, e);
6963
}
7064
clazz = clazz.getSuperclass();
7165
}

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

Lines changed: 12 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -22,29 +22,21 @@
2222

2323
import java.util.ArrayList;
2424
import java.util.List;
25-
import java.util.Objects;
2625
import java.util.stream.Collectors;
2726

2827

2928
@Getter
3029
@Setter
3130
@NoArgsConstructor
32-
public abstract class ControlBlock<T extends ControlBlock> {
31+
public abstract class ControlBlock<T extends ControlBlock> extends LNodeMetaDataEmbedder {
3332

3433
protected String id; /// appID or smvID
3534
protected String name;
3635
protected String dataSetRef;
3736
protected String desc;
38-
protected long confRev;
37+
protected Long confRev;
3938
protected List<TControlWithIEDName.IEDName> iedNames = new ArrayList<>();
4039
protected TPredefinedTypeOfSecurityEnum securityEnable = TPredefinedTypeOfSecurityEnum.NONE;
41-
// summarized info about the LN holding this CB
42-
protected String iedName;
43-
protected String ldInst;
44-
protected String prefix;
45-
protected String lnClass;
46-
protected String lnInst;
47-
4840

4941
protected abstract Class<T> getClassType();
5042
public abstract TServiceType getServiceType();
@@ -61,15 +53,11 @@ public T cast(Object obj){
6153
public void validateCB() throws ScdException {
6254

6355
if(id == null || id.isBlank()){
64-
throw new ScdException("Control block ID is missing");
56+
throw new ScdException("A required field is missing: ID ");
6557
}
6658

6759
if(name == null || name.isBlank()){
68-
throw new ScdException("Control block Name is missing");
69-
}
70-
71-
if(dataSetRef != null && dataSetRef.isBlank()){
72-
throw new ScdException("Control block datSet is missing");
60+
throw new ScdException("A required field is missing: name");
7361
}
7462

7563
if(iedNames.stream().anyMatch( iedName -> iedName == null ||
@@ -81,17 +69,22 @@ public void validateCB() throws ScdException {
8169

8270
public void validateDestination(SclRootAdapter sclRootAdapter) throws ScdException {
8371
for(TControlWithIEDName.IEDName iedName : iedNames){
84-
IEDAdapter iedAdapter =sclRootAdapter.getIEDAdapter(iedName.getValue());
72+
IEDAdapter iedAdapter =sclRootAdapter.getIEDAdapterByName(iedName.getValue());
8573
LDeviceAdapter lDeviceAdapter = iedAdapter.getLDeviceAdapterByLdInst(iedName.getLdInst())
8674
.orElseThrow(
8775
() -> new ScdException(
8876
String.format(
89-
"Unknown LDevice [%s] in IED [%s]", iedName.getLdInst(),iedName.getValue()
77+
"Control block destination: Unknown LDevice [%s] in IED [%s]",
78+
iedName.getLdInst(),iedName.getValue()
9079
)
9180
)
9281
);
9382
if(!iedName.getLnClass().isEmpty()) {
94-
lDeviceAdapter.getLNAdapter(iedName.getLnClass().get(0),iedName.getLnInst(), iedName.getPrefix());
83+
try {
84+
lDeviceAdapter.getLNAdapter(iedName.getLnClass().get(0), iedName.getLnInst(), iedName.getPrefix());
85+
} catch (ScdException e){
86+
throw new ScdException("Control block destination: " + e.getMessage());
87+
}
9588
} else {
9689
Utils.setField(iedName,"lnClass",null);
9790
}

0 commit comments

Comments
 (0)