Skip to content

Commit fa10565

Browse files
committed
feat(#574): MAC addressing in IEDs and Control Blocks
Signed-off-by: redaneuhaus <242222272+redaneuhaus@users.noreply.github.com>
1 parent 2893a83 commit fa10565

9 files changed

Lines changed: 1179 additions & 58 deletions

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

Lines changed: 162 additions & 50 deletions
Large diffs are not rendered by default.

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

Lines changed: 173 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -373,12 +373,11 @@ void configureNetworkForAllControlBlocks_should_create_GSE_with_incremental_appi
373373
}
374374

375375
@Test
376-
void configureNetworkForAllControlBlocks_should_restart_Mac_adress() {
376+
void configureNetworkForAllControlBlocks_should_have_unique_mac_in_ied() {
377377
// Given
378-
SCL scd = SclTestMarshaller.getSCLFromResource("scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_network_configuration.xml");
378+
SCL scd = SclTestMarshaller.getSCLFromResource("scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_unique_mac_in_ied.xml");
379379
CBCom cbCom = createCbCom();
380-
cbCom.getMacRanges().getMacRange().getFirst().setStart("01-0C-CD-01-00-00");
381-
cbCom.getMacRanges().getMacRange().getFirst().setEnd("01-0C-CD-01-00-01");
380+
cbCom.getMacRanges().getMacRange().getFirst().setEnd("01-0C-CD-01-00-05");
382381

383382
// When
384383
List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
@@ -401,12 +400,174 @@ void configureNetworkForAllControlBlocks_should_restart_Mac_adress() {
401400
Tuple.tuple("VLAN-ID", "12D"),
402401
Tuple.tuple("VLAN-PRIORITY", "1"),
403402
Tuple.tuple("APPID", "0002"),
404-
Tuple.tuple("MAC-Address", "01-0C-CD-01-00-00"),
403+
Tuple.tuple("MAC-Address", "01-0C-CD-01-00-02"),
405404
Tuple.tuple("VLAN-ID", "12E"),
406-
Tuple.tuple("VLAN-PRIORITY", "2")
405+
Tuple.tuple("VLAN-PRIORITY", "2"),
406+
Tuple.tuple("APPID", "0003"),
407+
Tuple.tuple("MAC-Address", "01-0C-CD-01-00-03"),
408+
Tuple.tuple("VLAN-ID", "12D"),
409+
Tuple.tuple("VLAN-PRIORITY", "1"),
410+
Tuple.tuple("APPID", "0004"),
411+
Tuple.tuple("MAC-Address", "01-0C-CD-01-00-04"),
412+
Tuple.tuple("VLAN-ID", "12D"),
413+
Tuple.tuple("VLAN-PRIORITY", "1")
407414
);
408415
}
409416

417+
@Test
418+
void configureNetworkForAllControlBlocks_should_reuse_mac() {
419+
// Given
420+
SCL scd = SclTestMarshaller.getSCLFromResource("scd-extref-create-dataset-and-controlblocks/test_reuse_mac_address.xml");
421+
CBCom cbCom = createCbCom();
422+
cbCom.getMacRanges().getMacRange().getFirst().setStart("00-00-00-00-00-01");
423+
cbCom.getMacRanges().getMacRange().getFirst().setEnd("00-00-00-00-00-03");
424+
// When
425+
List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
426+
// Then
427+
assertThat(sclReportItems).isEmpty();
428+
assertThat(scd.getCommunication().getSubNetwork())
429+
.flatExtracting(TSubNetwork::getConnectedAP)
430+
.flatExtracting(TConnectedAP::getGSE)
431+
.extracting(TControlBlock::getCbName, this::extractMacAddress)
432+
.containsExactlyInAnyOrder(
433+
Tuple.tuple("CB1", "00-00-00-00-00-01"),
434+
Tuple.tuple("CB2", "00-00-00-00-00-02"),
435+
Tuple.tuple("CB3", "00-00-00-00-00-01"));
436+
}
437+
438+
@Test
439+
void configureNetworkForAllControlBlocks_should_exclude_only_concerned_addresses() {
440+
// Given
441+
SCL scd = SclTestMarshaller.getSCLFromResource("scd-extref-create-dataset-and-controlblocks/test_exclude_only_concerned_address_of_ied_having_extref.xml");
442+
CBCom cbCom = createCbCom();
443+
cbCom.getMacRanges().getMacRange().getFirst().setStart("00-00-00-00-00-01");
444+
cbCom.getMacRanges().getMacRange().getFirst().setEnd("00-00-00-00-00-03");
445+
// When
446+
List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
447+
// Then
448+
assertThat(sclReportItems).isEmpty();
449+
assertThat(scd.getCommunication().getSubNetwork())
450+
.flatExtracting(TSubNetwork::getConnectedAP)
451+
.flatExtracting(TConnectedAP::getGSE)
452+
.extracting(TControlBlock::getCbName, this::extractMacAddress)
453+
.containsExactlyInAnyOrder(
454+
Tuple.tuple("CB1a", "00-00-00-00-00-01"),
455+
Tuple.tuple("CB1b", "00-00-00-00-00-02"),
456+
Tuple.tuple("CB2", "00-00-00-00-00-02"));
457+
}
458+
459+
@Test
460+
void configureNetworkForAllControlBlocks_should_get_only_mac_used_by_extref_of_extref_ied() {
461+
// Given
462+
SCL scd = SclTestMarshaller.getSCLFromResource("scd-extref-create-dataset-and-controlblocks/test_exclude_only_mac_addresses_used_by_extref_of_extref_ied.xml");
463+
CBCom cbCom = createCbCom();
464+
cbCom.getMacRanges().getMacRange().getFirst().setStart("00-00-00-00-00-01");
465+
cbCom.getMacRanges().getMacRange().getFirst().setEnd("00-00-00-00-00-03");
466+
// When
467+
List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
468+
// Then
469+
assertThat(sclReportItems).isEmpty();
470+
assertThat(scd.getCommunication().getSubNetwork())
471+
.flatExtracting(TSubNetwork::getConnectedAP)
472+
.flatExtracting(TConnectedAP::getGSE)
473+
.extracting(TControlBlock::getCbName, this::extractMacAddress)
474+
.containsExactlyInAnyOrder(
475+
Tuple.tuple("CB1a", "00-00-00-00-00-01"),
476+
Tuple.tuple("CB1b", "00-00-00-00-00-02"),
477+
Tuple.tuple("CB2", "00-00-00-00-00-02"));
478+
}
479+
480+
@Test
481+
void configureNetworkForAllControlBlocks_should_exclude_mac() {
482+
// Given
483+
SCL scd = SclTestMarshaller.getSCLFromResource("scd-extref-create-dataset-and-controlblocks/test_exclude_mac_address_of_extref.xml");
484+
CBCom cbCom = createCbCom();
485+
cbCom.getMacRanges().getMacRange().getFirst().setStart("00-00-00-00-00-01");
486+
cbCom.getMacRanges().getMacRange().getFirst().setEnd("00-00-00-00-00-03");
487+
// When
488+
List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
489+
// Then
490+
assertThat(sclReportItems).isEmpty();
491+
assertThat(scd.getCommunication().getSubNetwork())
492+
.flatExtracting(TSubNetwork::getConnectedAP)
493+
.flatExtracting(TConnectedAP::getGSE)
494+
.extracting(TControlBlock::getCbName, this::extractMacAddress)
495+
.containsExactlyInAnyOrder(
496+
Tuple.tuple("CB1", "00-00-00-00-00-01"),
497+
Tuple.tuple("CB2", "00-00-00-00-00-02"));
498+
}
499+
500+
@Test
501+
void configureNetworkForAllControlBlocks_should_exclude_mac_of_all_extref_of_target_ied() {
502+
// Given
503+
SCL scd = SclTestMarshaller.getSCLFromResource("scd-extref-create-dataset-and-controlblocks/test_exclude_mac_address_of_all_extref_of_target_ied.xml");
504+
CBCom cbCom = createCbCom();
505+
cbCom.getMacRanges().getMacRange().getFirst().setStart("00-00-00-00-00-01");
506+
cbCom.getMacRanges().getMacRange().getFirst().setEnd("00-00-00-00-00-03");
507+
// When
508+
List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
509+
// Then
510+
assertThat(sclReportItems).isEmpty();
511+
assertThat(scd.getCommunication().getSubNetwork())
512+
.flatExtracting(TSubNetwork::getConnectedAP)
513+
.flatExtracting(TConnectedAP::getGSE)
514+
.extracting(TControlBlock::getCbName, this::extractMacAddress)
515+
.containsExactlyInAnyOrder(
516+
Tuple.tuple("CB1", "00-00-00-00-00-01"),
517+
Tuple.tuple("CB2", "00-00-00-00-00-02"),
518+
Tuple.tuple("CB3", "00-00-00-00-00-03"));
519+
}
520+
521+
@Test
522+
void configureNetworkForAllControlBlocks_should_exclude_mac_of_all_cb_of_target_ied() {
523+
// Given
524+
SCL scd = SclTestMarshaller.getSCLFromResource("scd-extref-create-dataset-and-controlblocks/test_exclude_mac_address_of_all_cb_of_target_ied.xml");
525+
CBCom cbCom = createCbCom();
526+
cbCom.getMacRanges().getMacRange().getFirst().setStart("00-00-00-00-00-01");
527+
cbCom.getMacRanges().getMacRange().getFirst().setEnd("00-00-00-00-00-03");
528+
// When
529+
List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
530+
// Then
531+
assertThat(sclReportItems).isEmpty();
532+
assertThat(scd.getCommunication().getSubNetwork())
533+
.flatExtracting(TSubNetwork::getConnectedAP)
534+
.flatExtracting(TConnectedAP::getGSE)
535+
.extracting(TControlBlock::getCbName, this::extractMacAddress)
536+
.containsExactlyInAnyOrder(
537+
Tuple.tuple("CB1", "00-00-00-00-00-01"),
538+
Tuple.tuple("CB3", "00-00-00-00-00-02"));
539+
}
540+
541+
private String extractMacAddress(TControlBlock ctrlb) {
542+
if (ctrlb.getAddress() == null) {
543+
throw new IllegalArgumentException("GSE/SMV must have an address");
544+
}
545+
return ctrlb.getAddress().getP().stream()
546+
.filter(p -> p.getType().equals("MAC-Address"))
547+
.map(TP::getValue)
548+
.findFirst()
549+
.orElseThrow();
550+
}
551+
552+
@Test
553+
void configureNetworkForAllControlBlocks_should_not_address_if_not_enought_mac_available() {
554+
// Given
555+
SCL scd = SclTestMarshaller.getSCLFromResource("scd-extref-create-dataset-and-controlblocks/scd_create_controlblock_unique_mac_in_ied.xml");
556+
CBCom cbCom = createCbCom();
557+
cbCom.getMacRanges().getMacRange().getFirst().setEnd("01-0C-CD-01-00-03");
558+
559+
// When
560+
List<SclReportItem> sclReportItems = controlBlockEditorService.configureNetworkForAllControlBlocks(scd, cbCom);
561+
562+
// Then
563+
assertThat(sclReportItems.stream().noneMatch(SclReportItem::isError)).isFalse();
564+
assertThat(sclReportItems).hasSize(1)
565+
.extracting(SclReportItem::message, SclReportItem::xpath)
566+
.containsExactly(Tuple.tuple("Cannot configure communication for this ControlBlock because range of mac addresses is exhausted",
567+
"""
568+
/SCL/IED[@name="IED_NAME4"]/AccessPoint[@name="AP_NAME"]/Server/LDevice[@inst="LD_INST41"]/LN0/GSEControl[@name="CB_LD_INST41_GMI"]"""));
569+
}
570+
410571
@ParameterizedTest
411572
@MethodSource("provideConfigureNetworkForAllControlBlocksErrors")
412573
void configureNetworkForAllControlBlocks_should_fail_when_no_settings_for_this_controlBlock(CBCom cbCom, String expectedMessage, String expectedXPath) {
@@ -629,8 +790,12 @@ void configureNetworkForAllControlBlocks_when_missing_IED_privates_should_return
629790
//Then
630791
assertThat(sclReportItems).hasSize(3);
631792
assertThat(sclReportItems).extracting(SclReportItem::isError, SclReportItem::xpath)
632-
.containsOnly(Tuple.tuple(true, """
633-
/SCL/IED[@name="IED_NAME2"]/AccessPoint[@name="AP_NAME"]/Server/LDevice[@inst="LD_INST21"]"""));
793+
.contains(Tuple.tuple(true, """
794+
/SCL/IED[@name="IED_NAME2"]"""),
795+
Tuple.tuple(true, """
796+
/SCL/IED[@name="IED_NAME2"]"""),
797+
Tuple.tuple(true, """
798+
/SCL/IED[@name="IED_NAME2"]"""));
634799
assertThat(sclReportItems).extracting(SclReportItem::message).allSatisfy(message -> assertThat(message).containsAnyOf("COMPAS-ICDHeader", "COMPAS-SystemVersion"));
635800
}
636801

0 commit comments

Comments
 (0)