Bug 3044 - Conversion from Flowspec BI -> BA 22/22622/5
authorLadislav Borak <lborak@cisco.com>
Mon, 15 Jun 2015 15:26:21 +0000 (17:26 +0200)
committerGerrit Code Review <gerrit@opendaylight.org>
Tue, 16 Jun 2015 14:26:49 +0000 (14:26 +0000)
Added support to convert flowspec type in BI to the BA.

Change-Id: I780cab9e3a2fb6c8acc4fdab6572057d76f63432
Signed-off-by: Ladislav Borak <lborak@cisco.com>
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/FSNlriParser.java
bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FSNlriParserTest.java

index 3bb9743d75bfd0b589befff5d1c2e9ef400c5f01..33d2d34af964c9f65f96b9877c78e37b6d6716ad 100644 (file)
@@ -16,6 +16,7 @@ import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.Set;
 import org.opendaylight.protocol.bgp.parser.BGPParsingException;
 import org.opendaylight.protocol.bgp.parser.spi.NlriParser;
 import org.opendaylight.protocol.bgp.parser.spi.NlriSerializer;
@@ -27,6 +28,8 @@ import org.opendaylight.protocol.util.Values;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.BitmaskOperand;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.ComponentType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.Dscp;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.Fragment;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.NumericOneByteValue;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.NumericOperand;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150114.NumericTwoByteValue;
@@ -97,6 +100,8 @@ import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
+import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -108,20 +113,59 @@ public class FSNlriParser implements NlriParser, NlriSerializer {
     static final NodeIdentifier COMPONENT_TYPE_NID = new NodeIdentifier(QName.cachedReference(QName.create(Flowspec.QNAME, "component-type")));
     @VisibleForTesting
     static final NodeIdentifier DEST_PREFIX_NID = new NodeIdentifier(QName.cachedReference(QName.create(DestinationPrefixCase.QNAME, "destination-prefix")));
-    private static final NodeIdentifier SOURCE_PREFIX_NID = new NodeIdentifier(QName.cachedReference(QName.create(SourcePrefixCase.QNAME, "source-prefix")));
-    private static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
-    private static final NodeIdentifier PORTS_NID = new NodeIdentifier(Ports.QNAME);
-    private static final NodeIdentifier DEST_PORT_NID = new NodeIdentifier(DestinationPorts.QNAME);
-    private static final NodeIdentifier SOURCE_PORT_NID = new NodeIdentifier(SourcePorts.QNAME);
-    private static final NodeIdentifier ICMP_TYPE_NID = new NodeIdentifier(Types.QNAME);
-    private static final NodeIdentifier ICMP_CODE_NID = new NodeIdentifier(Codes.QNAME);
-    private static final NodeIdentifier TCP_FLAGS_NID = new NodeIdentifier(TcpFlags.QNAME);
-    private static final NodeIdentifier PACKET_LENGTHS_NID = new NodeIdentifier(PacketLengths.QNAME);
-    private static final NodeIdentifier DSCP_NID = new NodeIdentifier(Dscps.QNAME);
-    private static final NodeIdentifier FRAGMENT_NID = new NodeIdentifier(Fragments.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier SOURCE_PREFIX_NID = new NodeIdentifier(QName.cachedReference(QName.create(SourcePrefixCase.QNAME, "source-prefix")));
+    @VisibleForTesting
+    static final NodeIdentifier PROTOCOL_IP_NID = new NodeIdentifier(ProtocolIps.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier PORTS_NID = new NodeIdentifier(Ports.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier DEST_PORT_NID = new NodeIdentifier(DestinationPorts.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier SOURCE_PORT_NID = new NodeIdentifier(SourcePorts.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier ICMP_TYPE_NID = new NodeIdentifier(Types.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier ICMP_CODE_NID = new NodeIdentifier(Codes.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier TCP_FLAGS_NID = new NodeIdentifier(TcpFlags.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier PACKET_LENGTHS_NID = new NodeIdentifier(PacketLengths.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier DSCP_NID = new NodeIdentifier(Dscps.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier FRAGMENT_NID = new NodeIdentifier(Fragments.QNAME);
+    @VisibleForTesting
+    static final NodeIdentifier OP_NID = new NodeIdentifier(QName.create("urn:opendaylight:params:xml:ns:yang:bgp-flowspec","2015-01-14","op"));
+    @VisibleForTesting
+    static final NodeIdentifier VALUE_NID = new NodeIdentifier(QName.create("urn:opendaylight:params:xml:ns:yang:bgp-flowspec","2015-01-14","value"));
 
     private static final int NLRI_LENGTH = 1;
     private static final int NLRI_LENGTH_EXTENDED = 2;
+
+    @VisibleForTesting
+    static final String AND_BIT_VALUE = "and-bit";
+    @VisibleForTesting
+    static final String END_OF_LIST_VALUE = "end-of-list";
+    @VisibleForTesting
+    static final String EQUALS_VALUE = "equals";
+    @VisibleForTesting
+    static final String GREATER_THAN_VALUE = "greater-than";
+    @VisibleForTesting
+    static final String LESS_THAN_VALUE = "less-than";
+    @VisibleForTesting
+    static final String MATCH_VALUE = "match";
+    @VisibleForTesting
+    static final String NOT_VALUE = "not";
+    @VisibleForTesting
+    static final String DO_NOT_VALUE = "do-not";
+    @VisibleForTesting
+    static final String FIRST_VALUE = "first";
+    @VisibleForTesting
+    static final String LAST_VALUE = "last";
+    @VisibleForTesting
+    static final String IS_A_VALUE = "is-a";
+
     /**
      * Add this constant to length value to achieve all ones in the leftmost nibble.
      */
@@ -622,39 +666,233 @@ public class FSNlriParser implements NlriParser, NlriSerializer {
             fs.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix((String) fsType.getChild(SOURCE_PREFIX_NID).get().getValue()))
                     .build());
         } else if (fsType.getChild(PROTOCOL_IP_NID).isPresent()) {
-            // FIXME: BUG-3044
-            fs.setFlowspecType(new ProtocolIpCaseBuilder().build());
+            fs.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(createProtocolsIps((UnkeyedListNode) fsType.getChild(PROTOCOL_IP_NID).get())).build());
         } else if (fsType.getChild(PORTS_NID).isPresent()) {
-            // FIXME: BUG-3044
-            fs.setFlowspecType(new PortCaseBuilder().build());
+            fs.setFlowspecType(new PortCaseBuilder().setPorts(createPorts((UnkeyedListNode) fsType.getChild(PORTS_NID).get())).build());
         } else if (fsType.getChild(DEST_PORT_NID).isPresent()) {
-            // FIXME: BUG-3044
-            fs.setFlowspecType(new DestinationPortCaseBuilder().build());
+            fs.setFlowspecType(new DestinationPortCaseBuilder().setDestinationPorts(createDestinationPorts((UnkeyedListNode) fsType.getChild(DEST_PORT_NID).get())).build());
         } else if (fsType.getChild(SOURCE_PORT_NID).isPresent()) {
-            // FIXME: BUG-3044
-            fs.setFlowspecType(new SourcePortCaseBuilder().build());
+            fs.setFlowspecType(new SourcePortCaseBuilder().setSourcePorts(createSourcePorts((UnkeyedListNode) fsType.getChild(SOURCE_PORT_NID).get())).build());
         } else if (fsType.getChild(ICMP_TYPE_NID).isPresent()) {
-            // FIXME: BUG-3044
-            fs.setFlowspecType(new IcmpTypeCaseBuilder().build());
+            fs.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(createTypes((UnkeyedListNode) fsType.getChild(ICMP_TYPE_NID).get())).build());
         } else if (fsType.getChild(ICMP_CODE_NID).isPresent()) {
-            // FIXME: BUG-3044
-            fs.setFlowspecType(new IcmpCodeCaseBuilder().build());
+            fs.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(createCodes((UnkeyedListNode) fsType.getChild(ICMP_CODE_NID).get())).build());
         } else if (fsType.getChild(TCP_FLAGS_NID).isPresent()) {
-            // FIXME: BUG-3044
-            fs.setFlowspecType(new TcpFlagsCaseBuilder().build());
+            fs.setFlowspecType(new TcpFlagsCaseBuilder().setTcpFlags(createTcpFlags((UnkeyedListNode) fsType.getChild(TCP_FLAGS_NID).get())).build());
         } else if (fsType.getChild(PACKET_LENGTHS_NID).isPresent()) {
-            // FIXME: BUG-3044
-            fs.setFlowspecType(new PacketLengthCaseBuilder().build());
+            fs.setFlowspecType(new PacketLengthCaseBuilder().setPacketLengths(createPacketLengths((UnkeyedListNode) fsType.getChild(PACKET_LENGTHS_NID).get())).build());
         } else if (fsType.getChild(DSCP_NID).isPresent()) {
-            // FIXME: BUG-3044
-            fs.setFlowspecType(new DscpCaseBuilder().build());
+            fs.setFlowspecType(new DscpCaseBuilder().setDscps(createDscpsLengths((UnkeyedListNode) fsType.getChild(DSCP_NID).get())).build());
         } else if (fsType.getChild(FRAGMENT_NID).isPresent()) {
-            // FIXME: BUG-3044
-            fs.setFlowspecType(new FragmentCaseBuilder().build());
+            fs.setFlowspecType(new FragmentCaseBuilder().setFragments(createFragments((UnkeyedListNode) fsType.getChild(FRAGMENT_NID).get())).build());
         }
         return fs.build();
     }
 
+    private static NumericOperand createNumericOperand(final Set<String> opValues) {
+        return new NumericOperand(opValues.contains(AND_BIT_VALUE), opValues.contains(END_OF_LIST_VALUE), opValues.contains(EQUALS_VALUE), opValues.contains(GREATER_THAN_VALUE), opValues.contains(LESS_THAN_VALUE));
+    }
+
+    private static BitmaskOperand createBitmaskOperand(final Set<String> opValues) {
+        return new BitmaskOperand(opValues.contains(AND_BIT_VALUE), opValues.contains(END_OF_LIST_VALUE), opValues.contains(MATCH_VALUE), opValues.contains(NOT_VALUE));
+    }
+
+    private static Fragment createFragment(final Set<String> data) {
+        return new Fragment(data.contains(DO_NOT_VALUE), data.contains(FIRST_VALUE), data.contains(IS_A_VALUE), data.contains(LAST_VALUE));
+    }
+
+    private static List<ProtocolIps> createProtocolsIps(final UnkeyedListNode protocolIpsData) {
+        final List<ProtocolIps> protocolIps = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : protocolIpsData.getValue()) {
+            final ProtocolIpsBuilder ipsBuilder = new ProtocolIpsBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
+            if (opValue.isPresent()) {
+                ipsBuilder.setOp(createNumericOperand((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
+            if (valueNode.isPresent()) {
+                ipsBuilder.setValue((Integer) valueNode.get().getValue());
+            }
+            protocolIps.add(ipsBuilder.build());
+        }
+
+        return protocolIps;
+    }
+
+    private static List<Ports> createPorts(final UnkeyedListNode portsData) {
+        final List<Ports> ports = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : portsData.getValue()) {
+            final PortsBuilder portsBuilder = new PortsBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
+            if (opValue.isPresent()) {
+                portsBuilder.setOp(createNumericOperand((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
+            if (valueNode.isPresent()) {
+                portsBuilder.setValue((Integer) valueNode.get().getValue());
+            }
+            ports.add(portsBuilder.build());
+        }
+
+        return ports;
+    }
+
+    private static List<DestinationPorts> createDestinationPorts(final UnkeyedListNode destinationPortsData) {
+        final List<DestinationPorts> destinationPorts = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : destinationPortsData.getValue()) {
+            final DestinationPortsBuilder destPortsBuilder = new DestinationPortsBuilder();
+            if (node.getNodeType().getLocalName().equals("op")) {
+                final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
+                if (opValue.isPresent()) {
+                    destPortsBuilder.setOp(createNumericOperand((Set<String>) opValue.get().getValue()));
+                }
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
+            if (valueNode.isPresent()) {
+                destPortsBuilder.setValue((Integer) valueNode.get().getValue());
+            }
+            destinationPorts.add(destPortsBuilder.build());
+        }
+
+        return destinationPorts;
+    }
+
+    private static List<SourcePorts> createSourcePorts(final UnkeyedListNode sourcePortsData) {
+        final List<SourcePorts> sourcePorts = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : sourcePortsData.getValue()) {
+            final SourcePortsBuilder sourcePortsBuilder = new SourcePortsBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
+            if (opValue.isPresent()) {
+                sourcePortsBuilder.setOp(createNumericOperand((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
+            if (valueNode.isPresent()) {
+                sourcePortsBuilder.setValue((Integer) valueNode.get().getValue());
+            }
+            sourcePorts.add(sourcePortsBuilder.build());
+        }
+
+        return sourcePorts;
+    }
+
+    private static List<Types> createTypes(final UnkeyedListNode typesData) {
+        final List<Types> types = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : typesData.getValue()) {
+            final TypesBuilder typesBuilder = new TypesBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
+            if (opValue.isPresent()) {
+                typesBuilder.setOp(createNumericOperand((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
+            if (valueNode.isPresent()) {
+                typesBuilder.setValue((Short) valueNode.get().getValue());
+            }
+            types.add(typesBuilder.build());
+        }
+
+        return types;
+    }
+
+    private static List<Codes> createCodes(final UnkeyedListNode codesData) {
+        final List<Codes> codes = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : codesData.getValue()) {
+            final CodesBuilder codesBuilder = new CodesBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
+            if (opValue.isPresent()) {
+                codesBuilder.setOp(createNumericOperand((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
+            if (valueNode.isPresent()) {
+                codesBuilder.setValue((Short) valueNode.get().getValue());
+            }
+            codes.add(codesBuilder.build());
+        }
+
+        return codes;
+    }
+
+    private static List<TcpFlags> createTcpFlags(final UnkeyedListNode tcpFlagsData) {
+        final List<TcpFlags> tcpFlags = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : tcpFlagsData.getValue()) {
+            final TcpFlagsBuilder tcpFlagsBuilder = new TcpFlagsBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
+            if (opValue.isPresent()) {
+                tcpFlagsBuilder.setOp(createBitmaskOperand((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
+            if (valueNode.isPresent()) {
+                tcpFlagsBuilder.setValue((Integer) valueNode.get().getValue());
+            }
+            tcpFlags.add(tcpFlagsBuilder.build());
+        }
+
+        return tcpFlags;
+    }
+
+    private static List<PacketLengths> createPacketLengths(final UnkeyedListNode packetLengthsData) {
+        final List<PacketLengths> packetLengths = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : packetLengthsData.getValue()) {
+            final PacketLengthsBuilder packetLengthsBuilder = new PacketLengthsBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
+            if (opValue.isPresent()) {
+                packetLengthsBuilder.setOp(createNumericOperand((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
+            if (valueNode.isPresent()) {
+                packetLengthsBuilder.setValue((Integer) valueNode.get().getValue());
+            }
+            packetLengths.add(packetLengthsBuilder.build());
+        }
+
+        return packetLengths;
+    }
+
+    private static List<Dscps> createDscpsLengths(final UnkeyedListNode dscpLengthsData) {
+        final List<Dscps> dscpsLengths = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : dscpLengthsData.getValue()) {
+            final DscpsBuilder dscpsLengthsBuilder = new DscpsBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
+            if (opValue.isPresent()) {
+                dscpsLengthsBuilder.setOp(createNumericOperand((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
+            if (valueNode.isPresent()) {
+                dscpsLengthsBuilder.setValue(new Dscp((Short) valueNode.get().getValue()));
+            }
+            dscpsLengths.add(dscpsLengthsBuilder.build());
+        }
+
+        return dscpsLengths;
+    }
+
+    private static List<Fragments> createFragments(final UnkeyedListNode fragmentsData) {
+        final List<Fragments> fragments = new ArrayList<>();
+
+        for (final UnkeyedListEntryNode node : fragmentsData.getValue()) {
+            final FragmentsBuilder fragmentsBuilder = new FragmentsBuilder();
+            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
+            if (opValue.isPresent()) {
+                fragmentsBuilder.setOp(createBitmaskOperand((Set<String>) opValue.get().getValue()));
+            }
+            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
+            if (valueNode.isPresent()) {
+                fragmentsBuilder.setValue(createFragment((Set<String>) valueNode.get().getValue()));
+            }
+            fragments.add(fragmentsBuilder.build());
+        }
+
+        return fragments;
+    }
+
     // FIXME: use codec
     private static ComponentType componentTypeValue(final String compType) {
         switch (compType) {
index 6cfc832ea0d3cee5577696020086f3290d15b045..60fc27ca0e1981a0c22b6fe0825aed286934b0f1 100644 (file)
@@ -11,6 +11,7 @@ import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
 
 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;
@@ -262,7 +263,7 @@ public class FSNlriParserTest {
     }
 
     @Test
-    public void testExtractFlowspec() {
+    public void testExtractFlowspecDestPrefix() {
         final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
         entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
         entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("destination-prefix").build());
@@ -273,4 +274,187 @@ public class FSNlriParserTest {
         expected.setFlowspecType(new DestinationPrefixCaseBuilder().setDestinationPrefix(new Ipv4Prefix("127.0.0.5/32")).build());
         assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
     }
+
+    @Test
+    public void testExtractFlowspecSourcePrefix() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("source-prefix").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.SOURCE_PREFIX_NID).withValue("127.0.0.6/32").build()).build());
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setComponentType(ComponentType.SourcePrefix);
+        expected.setFlowspecType(new SourcePrefixCaseBuilder().setSourcePrefix(new Ipv4Prefix("127.0.0.6/32")).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecProtocolIps() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("protocol-ips").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FSNlriParser.PROTOCOL_IP_NID)
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.PROTOCOL_IP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.END_OF_LIST_VALUE, FSNlriParser.AND_BIT_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue(100).build()).build())
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.PROTOCOL_IP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.AND_BIT_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue(200).build()).build())
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.PROTOCOL_IP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.END_OF_LIST_VALUE, FSNlriParser.AND_BIT_VALUE, FSNlriParser.EQUALS_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue(300).build()).build())
+                .build()).build());
+
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setFlowspecType(new ProtocolIpCaseBuilder().setProtocolIps(Lists.<ProtocolIps>newArrayList(
+                new ProtocolIpsBuilder().setValue(100).setOp(new NumericOperand(true, true, false, false, false)).build(),
+                new ProtocolIpsBuilder().setValue(200).setOp(new NumericOperand(true, false, false, false, false)).build(),
+                new ProtocolIpsBuilder().setValue(300).setOp(new NumericOperand(true, true, true, false, false)).build())).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecPorts() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("ports").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FSNlriParser.PORTS_NID)
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.PROTOCOL_IP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.END_OF_LIST_VALUE, FSNlriParser.AND_BIT_VALUE, FSNlriParser.LESS_THAN_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue(100).build()).build())
+                .build()).build()).build();
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setFlowspecType(new PortCaseBuilder().setPorts(Lists.<Ports>newArrayList(new PortsBuilder().setValue(100).setOp(new NumericOperand(true, true, false, false, true)).build())).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecDestinationPorts() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("destination-ports").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FSNlriParser.DEST_PORT_NID)
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.OP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.END_OF_LIST_VALUE, FSNlriParser.EQUALS_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue(1024).build()).build())
+                .build()).build()).build();
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setFlowspecType(new DestinationPortCaseBuilder().setDestinationPorts(Lists.<DestinationPorts>newArrayList(new DestinationPortsBuilder().setValue(1024).setOp(new NumericOperand(false, true, true, false, false)).build())).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecSourcePorts() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("source-ports").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FSNlriParser.SOURCE_PORT_NID)
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.OP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.AND_BIT_VALUE, FSNlriParser.END_OF_LIST_VALUE, FSNlriParser.EQUALS_VALUE, FSNlriParser.GREATER_THAN_VALUE, FSNlriParser.LESS_THAN_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue(8080).build()).build())
+                .build()).build()).build();
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setFlowspecType(new SourcePortCaseBuilder().setSourcePorts(Lists.<SourcePorts>newArrayList(new SourcePortsBuilder().setValue(8080).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecSourceTypes() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("types").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FSNlriParser.ICMP_TYPE_NID)
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.OP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.AND_BIT_VALUE, FSNlriParser.END_OF_LIST_VALUE, FSNlriParser.EQUALS_VALUE, FSNlriParser.GREATER_THAN_VALUE, FSNlriParser.LESS_THAN_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue((short) 22).build()).build())
+                .build()).build()).build();
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setFlowspecType(new IcmpTypeCaseBuilder().setTypes(Lists.<Types>newArrayList(new TypesBuilder().setValue((short) 22).setOp(new NumericOperand(true, true, true, true, true)).build())).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecSourceCodes() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("codes").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FSNlriParser.ICMP_CODE_NID)
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.OP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet()).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue((short) 23).build()).build())
+                .build()).build()).build();
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setFlowspecType(new IcmpCodeCaseBuilder().setCodes(Lists.<Codes>newArrayList(new CodesBuilder().setValue((short) 23).setOp(new NumericOperand(false, false, false, false, false)).build())).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecSourceTcpFlags() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("tcp-flags").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FSNlriParser.TCP_FLAGS_NID)
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.OP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.AND_BIT_VALUE, FSNlriParser.END_OF_LIST_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue(99).build()).build())
+                .build()).build()).build();
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setComponentType(ComponentType.TcpFlags).setFlowspecType(new TcpFlagsCaseBuilder().setTcpFlags(Lists.<TcpFlags>newArrayList(new TcpFlagsBuilder().setValue(99).setOp(new BitmaskOperand(true, true, false, false)).build())).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecPacketLengths() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("packet-lengths").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FSNlriParser.PACKET_LENGTHS_NID)
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.OP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.AND_BIT_VALUE, FSNlriParser.GREATER_THAN_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue(101).build()).build())
+               .build()).build()).build();
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setFlowspecType(new PacketLengthCaseBuilder().setPacketLengths(Lists.<PacketLengths>newArrayList(new PacketLengthsBuilder().setValue(101).setOp(new NumericOperand(true, false, false, true, false)).build())).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecDscps() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("packet-lengths").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FSNlriParser.DSCP_NID)
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.OP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.AND_BIT_VALUE, FSNlriParser.END_OF_LIST_VALUE, FSNlriParser.GREATER_THAN_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue((short)15).build()).build())
+               .build()).build()).build();
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setFlowspecType(new DscpCaseBuilder().setDscps(Lists.<Dscps>newArrayList(new DscpsBuilder().setValue(new Dscp((short)15)).setOp(new NumericOperand(true, true, false, true, false)).build())).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
+
+    @Test
+    public void testExtractFlowspecFragments() {
+        final DataContainerNodeAttrBuilder<NodeIdentifierWithPredicates, MapEntryNode> entry = Builders.mapEntryBuilder();
+        entry.withNodeIdentifier(new NodeIdentifierWithPredicates(Flowspec.QNAME, Flowspec.QNAME, entry));
+        entry.withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.COMPONENT_TYPE_NID).withValue("packet-lengths").build());
+        entry.withChild(Builders.choiceBuilder().withNodeIdentifier(new NodeIdentifier(FlowspecType.QNAME))
+            .withChild(Builders.unkeyedListBuilder().withNodeIdentifier(FSNlriParser.FRAGMENT_NID)
+                .withChild(Builders.unkeyedListEntryBuilder().withNodeIdentifier(FSNlriParser.OP_NID)
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.OP_NID).withValue(Sets.<String>newHashSet(FSNlriParser.AND_BIT_VALUE, FSNlriParser.END_OF_LIST_VALUE, FSNlriParser.MATCH_VALUE, FSNlriParser.NOT_VALUE)).build())
+                        .withChild(Builders.leafBuilder().withNodeIdentifier(FSNlriParser.VALUE_NID).withValue(Sets.newHashSet(FSNlriParser.DO_NOT_VALUE, FSNlriParser.FIRST_VALUE, FSNlriParser.IS_A_VALUE, FSNlriParser.LAST_VALUE)).build()).build())
+                .build()).build()).build();
+        final FlowspecBuilder expected = new FlowspecBuilder();
+        expected.setFlowspecType(new FragmentCaseBuilder().setFragments(Lists.<Fragments>newArrayList(new FragmentsBuilder().setValue(new Fragment(true, true, true, true)).setOp(new BitmaskOperand(true, true, true, true)).build())).build());
+        assertEquals(expected.build(), FSNlriParser.extractFlowspec(entry.build()));
+    }
 }