Modernize bgp-flowspec
[bgpcep.git] / bgp / extensions / flowspec / src / test / java / org / opendaylight / protocol / bgp / flowspec / SimpleFlowspecIpv4NlriParserTest.java
index 278afc9a00b672bc193d921a8807ed5460ec6a88..47a26dc4c6361f55c6b861c94a96d1ccc20f57c0 100644 (file)
@@ -12,18 +12,18 @@ import static org.junit.Assert.assertEquals;
 import static org.mockito.ArgumentMatchers.any;
 import static org.mockito.Mockito.doReturn;
 
-import com.google.common.collect.Lists;
-import com.google.common.collect.Sets;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
-import java.util.Collections;
 import java.util.List;
 import java.util.Optional;
+import java.util.Set;
 import org.junit.Before;
 import org.junit.Test;
+import org.junit.runner.RunWith;
 import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import org.mockito.junit.MockitoJUnitRunner;
+import org.opendaylight.protocol.bgp.flowspec.FlowspecTypeRegistries.SAFI;
 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractNumericOperandParser;
 import org.opendaylight.protocol.bgp.flowspec.handlers.AbstractOperandParser;
 import org.opendaylight.protocol.bgp.flowspec.handlers.BitmaskOperandParser;
@@ -82,23 +82,22 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flow
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecCase;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.AttributesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesReachBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.AttributesUnreachBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.reach.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.attributes.unreach.mp.unreach.nlri.WithdrawnRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.Ipv4AddressFamily;
 import org.opendaylight.yangtools.yang.common.Uint16;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.opendaylight.yangtools.yang.common.Uint8;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
-import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
+import org.opendaylight.yangtools.yang.data.spi.node.ImmutableNodes;
 
+@RunWith(MockitoJUnitRunner.StrictStubs.class)
 public class SimpleFlowspecIpv4NlriParserTest {
 
     private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
@@ -157,17 +156,12 @@ public class SimpleFlowspecIpv4NlriParserTest {
         0x0c, (byte) 0x81, (byte) 0x0e
     };
 
-    private final SimpleFlowspecExtensionProviderContext flowspecContext = new SimpleFlowspecExtensionProviderContext();
-    private final FlowspecActivator fsa = new FlowspecActivator(this.flowspecContext);
-    private final SimpleFlowspecIpv4NlriParser fsParser = new SimpleFlowspecIpv4NlriParser(
-        flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
-            SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
+    private final SimpleFlowspecIpv4NlriParser fsParser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
 
     @Before
     public void setUp() {
-        MockitoAnnotations.initMocks(this);
-        doReturn(Optional.of(this.muliPathSupport)).when(this.constraint).getPeerConstraint(any());
-        doReturn(true).when(this.muliPathSupport).isTableTypeSupported(any());
+        doReturn(Optional.of(muliPathSupport)).when(constraint).getPeerConstraint(any());
+        doReturn(true).when(muliPathSupport).isTableTypeSupported(any());
     }
 
     @Test
@@ -207,13 +201,11 @@ public class SimpleFlowspecIpv4NlriParserTest {
             .setDestinationFlowspecIpv4(new DestinationFlowspecIpv4Builder().setFlowspec(fs).build())
             .build()).build());
 
-        final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
-            flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
-                SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
+        final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
 
-        final MpReachNlriBuilder result = new MpReachNlriBuilder();
-        result.setAfi(Ipv4AddressFamily.class);
-        result.setSafi(FlowspecSubsequentAddressFamily.class);
+        final MpReachNlriBuilder result = new MpReachNlriBuilder()
+            .setAfi(Ipv4AddressFamily.VALUE)
+            .setSafi(FlowspecSubsequentAddressFamily.VALUE);
         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI), result, null);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
@@ -224,16 +216,18 @@ public class SimpleFlowspecIpv4NlriParserTest {
 
         final ByteBuf buffer = Unpooled.buffer();
         parser.serializeAttribute(new AttributesBuilder()
-            .addAugmentation(new Attributes1Builder()
-                .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build())
+            .addAugmentation(new AttributesReachBuilder()
+                .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.VALUE).build())
                 .build())
             .build(), buffer);
         assertArrayEquals(REACHED_NLRI, ByteArray.readAllBytes(buffer));
 
-        assertEquals("all packets to 10.0.1.0/32 AND from 1.2.3.4/32 AND where IP protocol equals to 6 AND where port "
-                + "is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where "
-                + "destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ",
-                this.fsParser.stringNlri(flows));
+        assertEquals("""
+            all packets to 10.0.1.0/32 AND from 1.2.3.4/32 AND where IP protocol equals to 6 AND where port \
+            is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where \
+            destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 \
+            """,
+            fsParser.stringNlri(flows));
     }
 
     private static void testFlows(final List<Flowspec> flows, final DestinationPrefixCase destinationPrefix,
@@ -249,19 +243,19 @@ public class SimpleFlowspecIpv4NlriParserTest {
     }
 
     private static FlowspecType createSps() {
-        final List<SourcePorts> sports = Lists.newArrayList(new SourcePortsBuilder().setOp(
+        final List<SourcePorts> sports = List.of(new SourcePortsBuilder().setOp(
             new NumericOperand(false, true, true, false, false)).setValue(Uint16.valueOf(8080)).build());
         return new SourcePortCaseBuilder().setSourcePorts(sports).build();
     }
 
     private static FlowspecType createProts() {
-        final List<ProtocolIps> protocols = Lists.newArrayList(new ProtocolIpsBuilder().setOp(
+        final List<ProtocolIps> protocols = List.of(new ProtocolIpsBuilder().setOp(
             new NumericOperand(false, true, true, false, false)).setValue(Uint8.valueOf(6)).build());
         return new ProtocolIpCaseBuilder().setProtocolIps(protocols).build();
     }
 
     private static FlowspecType createDps() {
-        final List<DestinationPorts> destports = Lists.newArrayList(new DestinationPortsBuilder().setOp(
+        final List<DestinationPorts> destports = List.of(new DestinationPortsBuilder().setOp(
             new NumericOperand(false, false, false, true, false)).setValue(Uint16.valueOf(4089)).build(),
             new DestinationPortsBuilder().setOp(new NumericOperand(false, true, true, false, false))
                 .setValue(Uint16.valueOf(179)).build());
@@ -311,14 +305,12 @@ public class SimpleFlowspecIpv4NlriParserTest {
             ).build()
         );
 
-        final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
-            flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
-                SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
+        final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
 
-        final MpReachNlriBuilder result = new MpReachNlriBuilder();
-        result.setAfi(Ipv4AddressFamily.class);
-        result.setSafi(FlowspecSubsequentAddressFamily.class);
-        parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, this.constraint);
+        final MpReachNlriBuilder result = new MpReachNlriBuilder()
+            .setAfi(Ipv4AddressFamily.VALUE)
+            .setSafi(FlowspecSubsequentAddressFamily.VALUE);
+        parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_ADD_PATH), result, constraint);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
             .bgp.flowspec.rev200120.update.attributes.mp.reach.nlri.advertized.routes.destination.type
@@ -328,20 +320,22 @@ public class SimpleFlowspecIpv4NlriParserTest {
 
         final ByteBuf buffer = Unpooled.buffer();
         parser.serializeAttribute(new AttributesBuilder()
-            .addAugmentation(new Attributes1Builder()
-                .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.class).build())
+            .addAugmentation(new AttributesReachBuilder()
+                .setMpReachNlri(mp.setAfi(Ipv4AddressFamily.VALUE).build())
                 .build())
             .build(), buffer);
         assertArrayEquals(REACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
 
-        assertEquals("all packets to 10.0.1.0/32 AND from 1.2.3.4/32 AND where IP protocol equals to 6 AND where port "
-                + "is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where "
-                + "destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 ",
-                this.fsParser.stringNlri(flows));
+        assertEquals("""
+            all packets to 10.0.1.0/32 AND from 1.2.3.4/32 AND where IP protocol equals to 6 AND where port \
+            is greater than or equals to 137 and is less than or equals to 139 or equals to 8080 AND where \
+            destination port is greater than 4089 or equals to 179 AND where source port equals to 8080 \
+            """,
+            fsParser.stringNlri(flows));
     }
 
     private static PortCase createPorts() {
-        final List<Ports> ports = Lists.newArrayList(
+        final List<Ports> ports = List.of(
             new PortsBuilder().setOp(new NumericOperand(false, false, true, true, false)).setValue(Uint16.valueOf(137))
                 .build(),
             new PortsBuilder().setOp(new NumericOperand(true, false, true, false, true)).setValue(Uint16.valueOf(139))
@@ -355,7 +349,6 @@ public class SimpleFlowspecIpv4NlriParserTest {
     @Test
     public void testParseMpUnreachNlri() throws BGPParsingException {
         final List<Flowspec> fs = new ArrayList<>();
-        final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder();
 
         final FlowspecBuilder builder = new FlowspecBuilder();
 
@@ -383,24 +376,22 @@ public class SimpleFlowspecIpv4NlriParserTest {
         builder.setFlowspecType(fragment);
         fs.add(builder.build());
 
-        mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
-                .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
-                .setDestinationFlowspecIpv4(
-                    new DestinationFlowspecIpv4Builder()
+        final MpUnreachNlriBuilder mp = new MpUnreachNlriBuilder()
+            .setAfi(Ipv4AddressFamily.VALUE)
+            .setWithdrawnRoutes(new WithdrawnRoutesBuilder()
+                .setDestinationType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec
+                    .rev200120.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
+                    .DestinationFlowspecCaseBuilder().setDestinationFlowspecIpv4(new DestinationFlowspecIpv4Builder()
                         .setFlowspec(fs)
-                        .build()
-                ).build()
-            ).build()
-        );
+                        .build())
+                    .build())
+                .build());
 
-        final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
-            this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
-                SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
+        final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
 
-        final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
-        result.setAfi(Ipv4AddressFamily.class);
-        result.setSafi(FlowspecSubsequentAddressFamily.class);
+        final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder()
+            .setAfi(Ipv4AddressFamily.VALUE)
+            .setSafi(FlowspecSubsequentAddressFamily.VALUE);
         parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI), result, null);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
@@ -410,44 +401,45 @@ public class SimpleFlowspecIpv4NlriParserTest {
         checkUnreachFlows(flows, icmpType, icmpCode, tcp, packet, dscp, fragment);
 
         final ByteBuf buffer = Unpooled.buffer();
-        parser.serializeNlri(new Object[] {flows}, null, buffer);
+        parser.serializeNlri(flows, null, buffer);
         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
 
         parser.serializeAttribute(new AttributesBuilder()
-            .addAugmentation(new Attributes2Builder().setMpUnreachNlri(mp.build()).build())
+            .addAugmentation(new AttributesUnreachBuilder().setMpUnreachNlri(mp.build()).build())
             .build(), buffer);
         assertArrayEquals(UNREACHED_NLRI, ByteArray.readAllBytes(buffer));
 
-        assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 "
-                + "or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 "
-                + "AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ",
-                this.fsParser.stringNlri(flows));
-
+        assertEquals("""
+            all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 \
+            or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 \
+            AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' \
+            """,
+            fsParser.stringNlri(flows));
     }
 
     private static FlowspecType createFragment() {
-        final List<Fragments> fragments = Lists.newArrayList(new FragmentsBuilder()
+        final List<Fragments> fragments = List.of(new FragmentsBuilder()
             .setOp(new BitmaskOperand(false, true, true, false))
             .setValue(new Fragment(false, true, true, true)).build());
         return new FragmentCaseBuilder().setFragments(fragments).build();
     }
 
     private static FlowspecType createDscp() {
-        final List<Dscps> dscps = Lists.newArrayList(new DscpsBuilder()
+        final List<Dscps> dscps = List.of(new DscpsBuilder()
             .setOp(new NumericOperand(false, true, false, true, false))
             .setValue(new Dscp(Uint8.valueOf(42))).build());
         return new DscpCaseBuilder().setDscps(dscps).build();
     }
 
     private static PacketLengthCase createPackets() {
-        final List<PacketLengths> packets = Lists.newArrayList(new PacketLengthsBuilder()
+        final List<PacketLengths> packets = List.of(new PacketLengthsBuilder()
             .setOp(new NumericOperand(false, true, false, false, true))
             .setValue(Uint16.valueOf(57005)).build());
         return new PacketLengthCaseBuilder().setPacketLengths(packets).build();
     }
 
     private static TcpFlagsCase createTcp() {
-        final List<TcpFlags> flags = Lists.newArrayList(new TcpFlagsBuilder()
+        final List<TcpFlags> flags = List.of(new TcpFlagsBuilder()
             .setOp(new BitmaskOperand(false, false, false, true)).setValue(Uint16.valueOf(1025))
             .build(), new TcpFlagsBuilder()
             .setOp(new BitmaskOperand(false, true, true, false))
@@ -456,7 +448,7 @@ public class SimpleFlowspecIpv4NlriParserTest {
     }
 
     private static FlowspecType createIcmpCode() {
-        final List<Codes> codes = Lists.newArrayList(new CodesBuilder()
+        final List<Codes> codes = List.of(new CodesBuilder()
             .setOp(new NumericOperand(false, false, false, false, true))
             .setValue(Uint8.valueOf(4))
             .build(), new CodesBuilder()
@@ -466,7 +458,7 @@ public class SimpleFlowspecIpv4NlriParserTest {
     }
 
     private static FlowspecType createIcmpType() {
-        final List<Types> types = Lists.newArrayList(
+        final List<Types> types = List.of(
             new TypesBuilder().setOp(new NumericOperand(false, false, false, false, true)).setValue(Uint8.TWO)
                 .build(),
             new TypesBuilder().setOp(new NumericOperand(false, true, false, false, true)).setValue(Uint8.valueOf(3))
@@ -517,7 +509,7 @@ public class SimpleFlowspecIpv4NlriParserTest {
         builder.setFlowspecType(fragment);
         fs.add(builder.build());
 
-        mp.setAfi(Ipv4AddressFamily.class).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
+        mp.setAfi(Ipv4AddressFamily.VALUE).setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
             new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev200120.update
                 .attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecCaseBuilder()
                 .setDestinationFlowspecIpv4(
@@ -529,14 +521,12 @@ public class SimpleFlowspecIpv4NlriParserTest {
             ).build()
         );
 
-        final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
-            this.flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
-                SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
+        final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
 
-        final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder();
-        result.setAfi(Ipv4AddressFamily.class);
-        result.setSafi(FlowspecSubsequentAddressFamily.class);
-        parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, this.constraint);
+        final MpUnreachNlriBuilder result = new MpUnreachNlriBuilder()
+            .setAfi(Ipv4AddressFamily.VALUE)
+            .setSafi(FlowspecSubsequentAddressFamily.VALUE);
+        parser.parseNlri(Unpooled.wrappedBuffer(UNREACHED_NLRI_ADD_PATH), result, constraint);
 
         final List<Flowspec> flows = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang
             .bgp.flowspec.rev200120.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type
@@ -546,416 +536,380 @@ public class SimpleFlowspecIpv4NlriParserTest {
 
 
         final ByteBuf buffer = Unpooled.buffer();
-        parser.serializeNlri(new Object[] {flows}, PATH_ID, buffer);
+        parser.serializeNlri(flows, PATH_ID, buffer);
         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
 
         parser.serializeAttribute(new AttributesBuilder()
-            .addAugmentation(new Attributes2Builder().setMpUnreachNlri(mp.build()).build())
+            .addAugmentation(new AttributesUnreachBuilder().setMpUnreachNlri(mp.build()).build())
             .build(), buffer);
         assertArrayEquals(UNREACHED_NLRI_ADD_PATH, ByteArray.readAllBytes(buffer));
 
-        assertEquals("all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 "
-                + "or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 "
-                + "AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' ",
-                this.fsParser.stringNlri(flows));
-
+        assertEquals("""
+            all packets where ICMP type is less than 2 or is less than 3 AND where ICMP code is less than 4 \
+            or 5 AND where TCP flags is not 1025 or does match 22193 AND where packet length is less than 57005 \
+            AND where DSCP is greater than 42 AND where fragment does match 'IS FIRST' 'IS LAST' 'IS A' \
+            """,
+            fsParser.stringNlri(flows));
     }
 
     @Test
     public void testExtractFlowspecDestPrefix() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PREFIX_NID)
-                        .withValue("127.0.0.5/32").build()).build()).build()).build());
+                    .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.DEST_PREFIX_NID, "127.0.0.5/32"))
+                    .build()).build()).build());
 
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(
             new Ipv4Prefix("127.0.0.5/32")).build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecSourcePrefix() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID)
-                        .withValue("127.0.0.6/32").build()).build()).build()).build());
+                    .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.SOURCE_PREFIX_NID, "127.0.0.6/32"))
+                    .build()).build()).build());
 
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("127.0.0.6/32"))
             .build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecProtocolIps() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
-                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
-                                    AbstractOperandParser.AND_BIT_VALUE)).build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint8.valueOf(100)).build()).build())
-                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE)).build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint8.valueOf(200)).build()).build())
-                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
-                                    AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.EQUALS_VALUE))
-                                .build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint8.valueOf(240)).build()).build())
+                    .withChild(ImmutableNodes.newUnkeyedListBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE)))
+                            .withChild(
+                                ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(100)))
+                            .build())
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.AND_BIT_VALUE)))
+                            .withChild(
+                                ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(200)))
+                            .build())
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE,
+                                AbstractNumericOperandParser.EQUALS_VALUE)))
+                            .withChild(
+                                ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(240)))
+                            .build())
                         .build()).build()).build()).build());
 
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(
-            Lists.newArrayList(
+            List.of(
                 new ProtocolIpsBuilder().setValue(Uint8.valueOf(100)).setOp(
                     new NumericOperand(true, true, false, false, false)).build(),
                 new ProtocolIpsBuilder().setValue(Uint8.valueOf(200)).setOp(
                     new NumericOperand(true, false, false, false, false)).build(),
                 new ProtocolIpsBuilder().setValue(Uint8.valueOf(240)).setOp(
                     new NumericOperand(true, true, true, false, false)).build())).build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecPorts() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.PORTS_NID)
-                        .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
-                                    AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.LESS_THAN_VALUE))
-                                .build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint16.valueOf(100)).build()).build())
+                    .withChild(ImmutableNodes.newUnkeyedListBuilder()
+                        .withNodeIdentifier(AbstractFlowspecNlriParser.PORTS_NID)
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder().withNodeIdentifier(PROTOCOL_IP_NID)
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.END_OF_LIST_VALUE, AbstractOperandParser.AND_BIT_VALUE,
+                                AbstractNumericOperandParser.LESS_THAN_VALUE)))
+                            .withChild(
+                                ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint16.valueOf(100)))
+                            .build())
                         .build()).build()).build()).build());
 
         final FlowspecBuilder expectedFS = new FlowspecBuilder()
                 .setFlowspecType(new PortCaseBuilder()
-                    .setPorts(Lists.newArrayList(new PortsBuilder()
+                    .setPorts(List.of(new PortsBuilder()
                         .setValue(Uint16.valueOf(100))
                         .setOp(new NumericOperand(true, true, false, false, true))
                         .build()))
                     .build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecDestinationPorts() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.unkeyedListBuilder()
+                    .withChild(ImmutableNodes.newUnkeyedListBuilder()
                         .withNodeIdentifier(AbstractFlowspecNlriParser.DEST_PORT_NID)
-                        .withChild(Builders.unkeyedListEntryBuilder()
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.END_OF_LIST_VALUE,
-                                    AbstractNumericOperandParser.EQUALS_VALUE)).build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint16.valueOf(1024)).build()).build())
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE)))
+                            .withChild(
+                                ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint16.valueOf(1024)))
+                            .build())
                         .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new DestinationPortCaseBuilder()
-            .setDestinationPorts(Lists.newArrayList(new DestinationPortsBuilder()
+            .setDestinationPorts(List.of(new DestinationPortsBuilder()
                 .setValue(Uint16.valueOf(1024))
                 .setOp(new NumericOperand(false, true, true, false, false))
                 .build()))
             .build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecSourcePorts() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.unkeyedListBuilder()
+                    .withChild(ImmutableNodes.newUnkeyedListBuilder()
                         .withNodeIdentifier(AbstractFlowspecNlriParser.SOURCE_PORT_NID)
-                        .withChild(Builders.unkeyedListEntryBuilder()
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
-                                    AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE,
-                                    AbstractNumericOperandParser.GREATER_THAN_VALUE,
-                                    AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint16.valueOf(8080)).build()).build())
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE,
+                                AbstractNumericOperandParser.EQUALS_VALUE,
+                                AbstractNumericOperandParser.GREATER_THAN_VALUE,
+                                AbstractNumericOperandParser.LESS_THAN_VALUE)))
+                            .withChild(
+                                ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint16.valueOf(8080)))
+                            .build())
                         .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new SourcePortCaseBuilder()
-            .setSourcePorts(Lists.newArrayList(new SourcePortsBuilder()
+            .setSourcePorts(List.of(new SourcePortsBuilder()
                 .setValue(Uint16.valueOf(8080))
                 .setOp(new NumericOperand(true, true, true, true, true))
                 .build()))
             .build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecSourceTypes() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.unkeyedListBuilder()
+                    .withChild(ImmutableNodes.newUnkeyedListBuilder()
                         .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_TYPE_NID)
-                        .withChild(Builders.unkeyedListEntryBuilder()
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
-                                    AbstractOperandParser.END_OF_LIST_VALUE, AbstractNumericOperandParser.EQUALS_VALUE,
-                                    AbstractNumericOperandParser.GREATER_THAN_VALUE,
-                                    AbstractNumericOperandParser.LESS_THAN_VALUE)).build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint8.valueOf(22)).build()).build())
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE,
+                                AbstractNumericOperandParser.EQUALS_VALUE,
+                                AbstractNumericOperandParser.GREATER_THAN_VALUE,
+                                AbstractNumericOperandParser.LESS_THAN_VALUE)))
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(22)))
+                            .build())
                         .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
-        expectedFS.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(Lists.newArrayList(new TypesBuilder()
+        expectedFS.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(List.of(new TypesBuilder()
             .setValue(Uint8.valueOf(22)).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecSourceCodes() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.unkeyedListBuilder()
+                    .withChild(ImmutableNodes.newUnkeyedListBuilder()
                         .withNodeIdentifier(AbstractFlowspecNlriParser.ICMP_CODE_NID)
-                        .withChild(Builders.unkeyedListEntryBuilder()
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Collections.emptySet()).build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint8.valueOf(23)).build()).build())
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of()))
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(23)))
+                            .build())
                         .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
-        expectedFS.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(Lists.newArrayList(new CodesBuilder()
+        expectedFS.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(List.of(new CodesBuilder()
             .setValue(Uint8.valueOf(23)).setOp(new NumericOperand(false, false, false, false, false)).build()))
             .build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecSourceTcpFlags() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.unkeyedListBuilder()
+                    .withChild(ImmutableNodes.newUnkeyedListBuilder()
                         .withNodeIdentifier(AbstractFlowspecNlriParser.TCP_FLAGS_NID)
-                        .withChild(Builders.unkeyedListEntryBuilder()
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
-                                    AbstractOperandParser.END_OF_LIST_VALUE)).build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint16.valueOf(99)).build()).build())
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE)))
+                            .withChild(
+                                ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint16.valueOf(99)))
+                            .build())
                         .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new TcpFlagsCaseBuilder()
-            .setTcpFlags(Lists.newArrayList(new TcpFlagsBuilder()
+            .setTcpFlags(List.of(new TcpFlagsBuilder()
                 .setValue(Uint16.valueOf(99))
                 .setOp(new BitmaskOperand(true, true, false, false))
                 .build()))
             .build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecPacketLengths() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.unkeyedListBuilder()
+                    .withChild(ImmutableNodes.newUnkeyedListBuilder()
                         .withNodeIdentifier(AbstractFlowspecNlriParser.PACKET_LENGTHS_NID)
-                        .withChild(Builders.unkeyedListEntryBuilder()
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
-                                    AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint16.valueOf(101)).build()).build())
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.AND_BIT_VALUE, AbstractNumericOperandParser.GREATER_THAN_VALUE)))
+                            .withChild(
+                                ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint16.valueOf(101)))
+                            .build())
                         .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
         expectedFS.setFlowspecType(new PacketLengthCaseBuilder()
-            .setPacketLengths(Lists.newArrayList(new PacketLengthsBuilder()
+            .setPacketLengths(List.of(new PacketLengthsBuilder()
                 .setValue(Uint16.valueOf(101))
                 .setOp(new NumericOperand(true, false, false, true, false))
                 .build()))
             .build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecDscps() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.DSCP_NID)
-                        .withChild(Builders.unkeyedListEntryBuilder()
+                    .withChild(ImmutableNodes.newUnkeyedListBuilder()
+                        .withNodeIdentifier(AbstractFlowspecNlriParser.DSCP_NID)
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
-                                    AbstractOperandParser.END_OF_LIST_VALUE,
-                                    AbstractNumericOperandParser.GREATER_THAN_VALUE)).build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Uint8.valueOf(15)).build()).build())
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE,
+                                AbstractNumericOperandParser.GREATER_THAN_VALUE)))
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Uint8.valueOf(15)))
+                            .build())
                         .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
-        expectedFS.setFlowspecType(new DscpCaseBuilder().setDscps(Lists.newArrayList(new DscpsBuilder()
+        expectedFS.setFlowspecType(new DscpCaseBuilder().setDscps(List.of(new DscpsBuilder()
             .setValue(new Dscp(Uint8.valueOf(15))).setOp(new NumericOperand(true, true, false, true, false)).build()))
             .build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testExtractFlowspecFragments() {
-        final DataContainerNodeBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry =
-                Builders.mapEntryBuilder();
+        final var entry = ImmutableNodes.newMapEntryBuilder();
         entry.withNodeIdentifier(NodeIdentifierWithPredicates.of(FlowspecRoute.QNAME, FlowspecRoute.QNAME, entry));
-        entry.withChild(Builders.unkeyedListBuilder()
+        entry.withChild(ImmutableNodes.newUnkeyedListBuilder()
             .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-            .withChild(Builders.unkeyedListEntryBuilder()
+            .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                 .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_NID)
-                .withChild(Builders.choiceBuilder()
+                .withChild(ImmutableNodes.newChoiceBuilder()
                     .withNodeIdentifier(AbstractFlowspecNlriParser.FLOWSPEC_TYPE_NID)
-                    .withChild(Builders.unkeyedListBuilder()
+                    .withChild(ImmutableNodes.newUnkeyedListBuilder()
                         .withNodeIdentifier(AbstractFlowspecNlriParser.FRAGMENT_NID)
-                        .withChild(Builders.unkeyedListEntryBuilder()
+                        .withChild(ImmutableNodes.newUnkeyedListEntryBuilder()
                             .withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.OP_NID)
-                                .withValue(Sets.newHashSet(AbstractOperandParser.AND_BIT_VALUE,
-                                    AbstractOperandParser.END_OF_LIST_VALUE, BitmaskOperandParser.MATCH_VALUE,
-                                    BitmaskOperandParser.NOT_VALUE)).build())
-                            .withChild(Builders.leafBuilder().withNodeIdentifier(AbstractFlowspecNlriParser.VALUE_NID)
-                                .withValue(Sets.newHashSet(AbstractFlowspecNlriParser.DO_NOT_VALUE,
-                                    AbstractFlowspecNlriParser.FIRST_VALUE, AbstractFlowspecNlriParser.IS_A_VALUE,
-                                    AbstractFlowspecNlriParser.LAST_VALUE)).build()).build())
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.OP_NID, Set.of(
+                                AbstractOperandParser.AND_BIT_VALUE, AbstractOperandParser.END_OF_LIST_VALUE,
+                                BitmaskOperandParser.MATCH_VALUE, BitmaskOperandParser.NOT_VALUE)))
+                            .withChild(ImmutableNodes.leafNode(AbstractFlowspecNlriParser.VALUE_NID, Set.of(
+                                AbstractFlowspecNlriParser.DO_NOT_VALUE, AbstractFlowspecNlriParser.FIRST_VALUE,
+                                AbstractFlowspecNlriParser.IS_A_VALUE, AbstractFlowspecNlriParser.LAST_VALUE)))
+                            .build())
                         .build()).build()).build()).build());
         final FlowspecBuilder expectedFS = new FlowspecBuilder();
-        expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.newArrayList(new FragmentsBuilder()
+        expectedFS.setFlowspecType(new FragmentCaseBuilder().setFragments(List.of(new FragmentsBuilder()
             .setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build()))
             .build());
-        final List<Flowspec> expected = new ArrayList<>();
-        expected.add(expectedFS.build());
-        assertEquals(expected, this.fsParser.extractFlowspec(entry.build()));
+        assertEquals(List.of(expectedFS.build()), fsParser.extractFlowspec(entry.build()));
     }
 
     @Test
     public void testBatchedFlowspecNlri() throws Exception {
-        final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(
-            flowspecContext.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4,
-                SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC));
+        final SimpleFlowspecIpv4NlriParser parser = new SimpleFlowspecIpv4NlriParser(SAFI.FLOWSPEC);
 
-        final MpReachNlriBuilder result = new MpReachNlriBuilder();
-        result.setAfi(Ipv4AddressFamily.class);
-        result.setSafi(FlowspecSubsequentAddressFamily.class);
+        final MpReachNlriBuilder result = new MpReachNlriBuilder()
+            .setAfi(Ipv4AddressFamily.VALUE)
+            .setSafi(FlowspecSubsequentAddressFamily.VALUE);
 
         parser.parseNlri(Unpooled.wrappedBuffer(REACHED_NLRI_BATCHED), result, null);
         final MpReachNlri nlri = result.build();
 
         final List<Flowspec> flowspecList = ((DestinationFlowspecCase) nlri.getAdvertizedRoutes().getDestinationType())
-                .getDestinationFlowspecIpv4().getFlowspec();
+                .getDestinationFlowspecIpv4().nonnullFlowspec();
         assertEquals(3, flowspecList.size());
         assertEquals("216.58.245.101/32", ((DestinationPrefixCase) flowspecList.get(0).getFlowspecType())
             .getDestinationPrefix().getValue());