Skip to content

Commit 5d46fa8

Browse files
committed
fix(#601): RSR-1589 - fix NPE when using TAccessPoint getServer
Signed-off-by: massifben <105049157+massifben@users.noreply.github.com>
1 parent be44d68 commit 5d46fa8

2 files changed

Lines changed: 64 additions & 37 deletions

File tree

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

Lines changed: 39 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -127,34 +127,37 @@ private Stream<SclReportItem> configureNetworkForControlBlocks(SCL scl, Map<CbKe
127127
.flatMap(tied -> {
128128
List<Long> excludedMacAddresses = findExcludedMacAddresses(scl, tied, tcbType);
129129
Iterator<Long> authorizedMacAdressList = macAddresseList.stream().filter(mac -> !excludedMacAddresses.contains(mac)).iterator();
130-
return ldeviceService.getLdevices(tied)
131-
.flatMap(lDevice -> controlService.getControls(lDevice.getLN0(), ControlBlockEnum.from(tcbType).getControlBlockClass())
132-
.map(tControl -> {
133-
TAccessPoint accessPoint = tied.getAccessPoint().stream().filter(ap -> ap.getServer().getLDevice().stream().anyMatch(tlDevice -> tlDevice.getLdName().equals(lDevice.getLdName()))).findFirst().orElseThrow();
134-
String apName = accessPoint.getName();
135-
IedApLd iedApLd = new IedApLd(tied, apName, lDevice);
136-
CriteriaOrError criteriaOrError = getCriteria(tied, tcbType, tControl.getName());
137-
if (criteriaOrError.errorMessage != null) {
138-
return Optional.of(SclReportItem.error("""
139-
/SCL/IED[@name="%s"]""".formatted(tied.getName()), criteriaOrError.errorMessage));
140-
}
141-
142-
Settings settings = cbComSettings.settingsByCriteria.get(criteriaOrError.criteria);
143-
if (settings == null) {
144-
return newError(iedApLd, tControl, "Cannot configure communication for this ControlBlock because: No controlBlock communication settings found with these " + criteriaOrError.criteria);
145-
}
146-
AppId reuseAppId = appIdsToReuse.get(new CbKey(tied.getName(), lDevice.getInst(), tControl.getName()));
147-
Mac reuseMac = macsToReuse.get(new CbKey(tied.getName(), lDevice.getInst(), tControl.getName()));
148-
TCommunication tCommunication = scl.getCommunication();
149-
150-
Optional<TConnectedAP> optionalTConnectedAP = subNetworkService.getSubNetworks(tCommunication)
151-
.flatMap(tSubNetwork -> connectedAPService.getFilteredConnectedAP(tSubNetwork, connectedAP -> tied.getName().equals(connectedAP.getIedName()) && apName.equals(connectedAP.getApName())))
152-
.findFirst();
153-
if (optionalTConnectedAP.isEmpty()) {
154-
return newError(iedApLd, tControl, "Cannot configure communication for ControlBlock because no ConnectedAP found for AccessPoint");
155-
}
156-
return configureControlBlockNetwork(tCommunication, settings, appIdIterator, authorizedMacAdressList, tControl, iedApLd, reuseAppId, reuseMac);
157-
}).flatMap(Optional::stream));
130+
return tied.getAccessPoint().stream()
131+
.filter(TAccessPoint::isSetServer)
132+
.flatMap(tAccessPoint -> tAccessPoint.getServer().getLDevice().stream()
133+
.flatMap(lDevice ->
134+
controlService.getControls(lDevice.getLN0(), ControlBlockEnum.from(tcbType).getControlBlockClass())
135+
.map(tControl -> {
136+
String apName = tAccessPoint.getName();
137+
IedApLd iedApLd = new IedApLd(tied, apName, lDevice);
138+
CriteriaOrError criteriaOrError = getCriteria(tied, tcbType, tControl.getName());
139+
if (criteriaOrError.errorMessage != null) {
140+
return Optional.of(SclReportItem.error("""
141+
/SCL/IED[@name="%s"]""".formatted(tied.getName()), criteriaOrError.errorMessage));
142+
}
143+
144+
Settings settings = cbComSettings.settingsByCriteria.get(criteriaOrError.criteria);
145+
if (settings == null) {
146+
return newError(iedApLd, tControl, "Cannot configure communication for this ControlBlock because: No controlBlock communication settings found with these " + criteriaOrError.criteria);
147+
}
148+
AppId reuseAppId = appIdsToReuse.get(new CbKey(tied.getName(), lDevice.getInst(), tControl.getName()));
149+
Mac reuseMac = macsToReuse.get(new CbKey(tied.getName(), lDevice.getInst(), tControl.getName()));
150+
TCommunication tCommunication = scl.getCommunication();
151+
152+
Optional<TConnectedAP> optionalTConnectedAP = subNetworkService.getSubNetworks(tCommunication)
153+
.flatMap(tSubNetwork -> connectedAPService.getFilteredConnectedAP(tSubNetwork, connectedAP -> tied.getName().equals(connectedAP.getIedName()) && apName.equals(connectedAP.getApName())))
154+
.findFirst();
155+
if (optionalTConnectedAP.isEmpty()) {
156+
return newError(iedApLd, tControl, "Cannot configure communication for ControlBlock because no ConnectedAP found for AccessPoint");
157+
}
158+
return configureControlBlockNetwork(tCommunication, settings, appIdIterator, authorizedMacAdressList, tControl, iedApLd, reuseAppId, reuseMac);
159+
})
160+
.flatMap(Optional::stream)));
158161
});
159162
}
160163

@@ -196,9 +199,8 @@ private Stream<Long> getExtRefAddress(SCL scl, TIED tied) {
196199
.flatMap(tConnectedAP -> Stream.concat(tConnectedAP.getGSE().stream(), tConnectedAP.getSMV().stream()))
197200
.filter(cBlock -> cBlock.getCbName().equals(cbKey.cbName()) && cBlock.getLdInst().equals(cbKey.LDInst()))))
198201
.filter(TControlBlock::isSetAddress)
199-
.flatMap(cBlock -> {
200-
return Utils.extractFromP(MAC_ADDRESS_P_TYPE, cBlock.getAddress().getP()).stream();
201-
})
202+
.map(cBlock -> Utils.extractFromP(MAC_ADDRESS_P_TYPE, cBlock.getAddress().getP()))
203+
.flatMap(Optional::stream)
202204
.map(Utils::macAddressToLong);
203205
}
204206

@@ -299,7 +301,7 @@ private Map<CbKey, AppId> computeAppIdsToReuse(SCL scd, List<TSubNetwork> subnet
299301
.flatMap(tSubNetwork -> tSubNetwork.getConnectedAP().stream())
300302
.flatMap(tConnectedAP -> Stream.concat(tConnectedAP.getGSE().stream(), tConnectedAP.getSMV().stream())
301303
.flatMap(tControlBlock -> AppId.from(tControlBlock.getAddress())
302-
.map(appId-> new SimpleEntry<>(new CbKey(tConnectedAP.getIedName(), tControlBlock.getLdInst(), tControlBlock.getCbName()), appId))
304+
.map(appId -> new SimpleEntry<>(new CbKey(tConnectedAP.getIedName(), tControlBlock.getLdInst(), tControlBlock.getCbName()), appId))
303305
.stream()
304306
)
305307
)
@@ -379,7 +381,7 @@ public CriteriaOrError getCriteria(TIED tied, TCBType cbType, String cbName) {
379381
return new CriteriaOrError(null, "No private COMPAS-SystemVersion found in this IED");
380382
}
381383
if (StringUtils.isBlank(compasSystemVersion.get().getMainSystemVersion())
382-
|| (StringUtils.isBlank(compasSystemVersion.get().getMinorSystemVersion()))) {
384+
|| (StringUtils.isBlank(compasSystemVersion.get().getMinorSystemVersion()))) {
383385
return new CriteriaOrError(null, "Missing MainSystemVersion or MinorSystemVersion attribute in COMPAS-SystemVersion private of IED");
384386
}
385387
String systemVersionWithoutV = removeVFromSystemVersion(compasSystemVersion.get());
@@ -554,23 +556,23 @@ static Optional<AppId> from(TAddress address) {
554556
}
555557
return Utils.extractFromP(APPID_P_TYPE, address.getP())
556558
.map(appId -> Integer.parseInt(appId, HEXADECIMAL_BASE))
557-
.map(AppId::new);
559+
.map(AppId::new);
558560
}
559561
}
560562

561563
/**
562564
* MAC-Address
563565
*
564-
* @param mac MAC-Address
566+
* @param mac MAC-Address
565567
*/
566568
record Mac(long mac) {
567569
static Optional<Mac> from(TAddress address) {
568570
if (address == null) {
569571
return Optional.empty();
570572
}
571573
return Utils.extractFromP(MAC_ADDRESS_P_TYPE, address.getP())
572-
.map(Utils::macAddressToLong)
573-
.map(Mac::new);
574+
.map(Utils::macAddressToLong)
575+
.map(Mac::new);
574576
}
575577
}
576578
}

sct-commons/src/test/java/org/lfenergy/compas/sct/commons/ControlBlockEditorServiceTest.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -799,6 +799,31 @@ void configureNetworkForAllControlBlocks_when_missing_IED_privates_should_return
799799
assertThat(sclReportItems).extracting(SclReportItem::message).allSatisfy(message -> assertThat(message).containsAnyOf("COMPAS-ICDHeader", "COMPAS-SystemVersion"));
800800
}
801801

802+
@Test
803+
void configureNetworkForAllControlBlocks_when_AccessPoint_ha_no_Server_should_not_throw_exception() {
804+
// Given
805+
SCL scd = SclTestMarshaller.getSCLFromResource("scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
806+
TAccessPoint accessPointWithoutServer = new TAccessPoint();
807+
accessPointWithoutServer.setName("AP_ADMIN");
808+
scd.getIED().getFirst().getAccessPoint().addFirst(accessPointWithoutServer);
809+
CBCom cbCom = createCbCom();
810+
// When
811+
List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom, List.of());
812+
// Then
813+
assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isTrue();
814+
TGSE gse1 = getCommunicationGSE(scd, "IED_NAME2", "CB_LD_INST21_GSI");
815+
assertThat(gse1.getLdInst()).isEqualTo("LD_INST21");
816+
assertThat(SclDuration.from(gse1.getMinTime())).isEqualTo(new SclDuration("10", "s", "m"));
817+
assertThat(SclDuration.from(gse1.getMaxTime())).isEqualTo(new SclDuration("2000", "s", "m"));
818+
assertThat(gse1.getAddress().getP()).extracting(TP::getType, TP::getValue).containsExactlyInAnyOrder(
819+
Tuple.tuple("VLAN-PRIORITY", "1"),
820+
Tuple.tuple("APPID", "0000"),
821+
Tuple.tuple("MAC-Address", "01-0C-CD-01-00-00"),
822+
Tuple.tuple("VLAN-ID", "12D")
823+
);
824+
SclTestMarshaller.assertSclValidateXsd(scd);
825+
}
826+
802827
private static Stream<Arguments> provideRemovePrivateInfo() {
803828
return Stream.of(
804829
Arguments.of((Consumer<TIED>) tied -> PrivateUtils.removePrivates(tied, PrivateEnum.COMPAS_SYSTEM_VERSION)),

0 commit comments

Comments
 (0)