BUG-5785 Support for dissemination of L3VPN flow spec II
[bgpcep.git] / bgp / flowspec / src / main / java / org / opendaylight / protocol / bgp / flowspec / SimpleFlowspecIpv6NlriParser.java
index a578df8bbd5636bd675829b56b9c831f2bf0e1e0..3acc478e95ab5363bf873934a8254ee597f14eec 100644 (file)
  */
 package org.opendaylight.protocol.bgp.flowspec;
 
-import com.google.common.base.Optional;
 import io.netty.buffer.ByteBuf;
-import java.util.ArrayList;
 import java.util.List;
-import java.util.Set;
+import javax.annotation.Nonnull;
 import javax.annotation.Nullable;
-import org.opendaylight.protocol.bgp.flowspec.handlers.NumericOneByteOperandParser;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv6Prefix;
+import org.opendaylight.protocol.bgp.flowspec.ipv6.FlowspecIpv6NlriParserHelper;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.Flowspec;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.FlowspecBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.flowspec.FlowspecType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.DestinationIpv6PrefixCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.FlowLabelCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.FlowLabelCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.NextHeaderCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.SourceIpv6PrefixCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.flow.label._case.FlowLabel;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.flow.label._case.FlowLabelBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.next.header._case.NextHeaders;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.group.ipv6.flowspec.flowspec.type.next.header._case.NextHeadersBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv6.DestinationFlowspec;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.destination.ipv6.DestinationFlowspecBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathId;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 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.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
 
 public final class SimpleFlowspecIpv6NlriParser extends AbstractFlowspecNlriParser {
 
-    static final NodeIdentifier NEXT_HEADER_NID = new NodeIdentifier(NextHeaders.QNAME);
-    static final NodeIdentifier FLOW_LABEL_NID = new NodeIdentifier(FlowLabel.QNAME);
-
     public SimpleFlowspecIpv6NlriParser(SimpleFlowspecTypeRegistry flowspecTypeRegistry) {
-        this.flowspecTypeRegistry = flowspecTypeRegistry;
+        super(flowspecTypeRegistry);
     }
 
     @Override
-    protected DestinationType createWithdrawnDestinationType(final List<Flowspec> dst, @Nullable final PathId pathId) {
+    protected DestinationType createWithdrawnDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) {
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
-                .setDestinationFlowspec(
-                        new DestinationFlowspecBuilder()
-                                .setFlowspec(dst)
-                                .setPathId(pathId)
-                                .build()
-                ).build();
+            .setDestinationFlowspec(
+                new DestinationFlowspecBuilder()
+                    .setFlowspec(flowspecList)
+                    .setPathId(pathId)
+                    .build()
+            ).build();
     }
 
     @Override
-    protected DestinationType createAdvertizedRoutesDestinationType(final List<Flowspec> dst, @Nullable final PathId pathId) {
+    protected DestinationType createAdvertizedRoutesDestinationType(@Nonnull final Object[] nlriFields, @Nullable final PathId pathId) {
+        final List<Flowspec> flowspecList = (List<Flowspec>) nlriFields[0];
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6CaseBuilder()
-                .setDestinationFlowspec(
-                        new DestinationFlowspecBuilder()
-                                .setFlowspec(dst)
-                                .setPathId(pathId)
-                                .build()
-                ).build();
-    }
-
-    @Override
-    protected void serializeMpReachNlri(final Attributes1 pathAttributes, final ByteBuf byteAggregator) {
-        if (pathAttributes == null) {
-            return;
-        }
-        final AdvertizedRoutes routes = (pathAttributes.getMpReachNlri()).getAdvertizedRoutes();
-        if (routes != null && routes.getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6Case) {
-            final DestinationFlowspec destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6Case) routes.getDestinationType())
-                    .getDestinationFlowspec();
-            serializeNlri(destFlowspec.getFlowspec(), destFlowspec.getPathId(), byteAggregator);
-        }
+            .setDestinationFlowspec(
+                new DestinationFlowspecBuilder()
+                    .setFlowspec(flowspecList)
+                    .setPathId(pathId)
+                    .build()
+            ).build();
     }
 
     @Override
     public void extractSpecificFlowspec(final ChoiceNode fsType, final FlowspecBuilder fsBuilder) {
-        if (fsType.getChild(DEST_PREFIX_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new DestinationIpv6PrefixCaseBuilder()
-                    .setDestinationPrefix(new Ipv6Prefix((String) fsType.getChild(DEST_PREFIX_NID).get().getValue()))
-                    .build());
-        } else if (fsType.getChild(SOURCE_PREFIX_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new SourceIpv6PrefixCaseBuilder()
-                    .setSourcePrefix(new Ipv6Prefix((String) fsType.getChild(SOURCE_PREFIX_NID).get().getValue()))
-                    .build());
-        } else if (fsType.getChild(NEXT_HEADER_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new NextHeaderCaseBuilder().setNextHeaders(createNextHeaders((UnkeyedListNode) fsType.getChild(NEXT_HEADER_NID).get())).build());
-        } else if (fsType.getChild(FLOW_LABEL_NID).isPresent()) {
-            fsBuilder.setFlowspecType(new FlowLabelCaseBuilder().setFlowLabel(createFlowLabels((UnkeyedListNode) fsType.getChild(FLOW_LABEL_NID).get())).build());
-        }
-    }
-
-    private List<NextHeaders> createNextHeaders(final UnkeyedListNode nextHeadersData) {
-        final List<NextHeaders> nextHeaders = new ArrayList<>();
-
-        for (final UnkeyedListEntryNode node : nextHeadersData.getValue()) {
-            final NextHeadersBuilder nextHeadersBuilder = new NextHeadersBuilder();
-            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
-            if (opValue.isPresent()) {
-                nextHeadersBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set<String>) opValue.get().getValue()));
-            }
-            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
-            if (valueNode.isPresent()) {
-                nextHeadersBuilder.setValue((Short) valueNode.get().getValue());
-            }
-            nextHeaders.add(nextHeadersBuilder.build());
-        }
-
-        return nextHeaders;
-    }
-
-    private List<FlowLabel> createFlowLabels(final UnkeyedListNode flowLabelsData) {
-        final List<FlowLabel> flowLabels = new ArrayList<>();
-
-        for (final UnkeyedListEntryNode node : flowLabelsData.getValue()) {
-            final FlowLabelBuilder flowLabelsBuilder = new FlowLabelBuilder();
-            final Optional<DataContainerChild<? extends PathArgument, ?>> opValue = node.getChild(OP_NID);
-            if (opValue.isPresent()) {
-                flowLabelsBuilder.setOp(NumericOneByteOperandParser.INSTANCE.create((Set<String>) opValue.get().getValue()));
-            }
-            final Optional<DataContainerChild<? extends PathArgument, ?>> valueNode = node.getChild(VALUE_NID);
-            if (valueNode.isPresent()) {
-                flowLabelsBuilder.setValue((Long) valueNode.get().getValue());
-            }
-            flowLabels.add(flowLabelsBuilder.build());
-        }
-
-        return flowLabels;
+        FlowspecIpv6NlriParserHelper.extractFlowspec(fsType, fsBuilder);
     }
 
     @Override
     protected void stringSpecificFSNlriType(final FlowspecType value, final StringBuilder buffer) {
-        if (value instanceof DestinationIpv6PrefixCase) {
-            buffer.append("to ");
-            buffer.append(((DestinationIpv6PrefixCase) value).getDestinationPrefix().getValue());
-        } else if (value instanceof SourceIpv6PrefixCase) {
-            buffer.append("from ");
-            buffer.append(((SourceIpv6PrefixCase) value).getSourcePrefix().getValue());
-        } else if (value instanceof NextHeaderCase) {
-            buffer.append("where next header ");
-            buffer.append(NumericOneByteOperandParser.INSTANCE.toString(((NextHeaderCase) value).getNextHeaders()));
-        } else if (value instanceof FlowLabelCase) {
-            buffer.append("where flow label ");
-            buffer.append(stringFlowLabel(((FlowLabelCase) value).getFlowLabel()));
-        }
+        FlowspecIpv6NlriParserHelper.buildFlowspecString(value, buffer);
     }
 
-    private static String stringFlowLabel(final List<FlowLabel> list) {
-        final StringBuilder buffer = new StringBuilder();
-        boolean isFirst = true;
-        for (final FlowLabel item : list) {
-            buffer.append(NumericOneByteOperandParser.INSTANCE.toString(item.getOp(), isFirst));
-            buffer.append(item.getValue());
-            buffer.append(' ');
-            if (isFirst) {
-                isFirst = false;
-            }
+    @Override
+    protected void serializeMpReachNlri(final DestinationType dstType, final ByteBuf byteAggregator) {
+        if (dstType instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6Case) {
+            final DestinationFlowspec destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationFlowspecIpv6Case) dstType)
+                .getDestinationFlowspec();
+            serializeNlri(new Object[] {destFlowspec.getFlowspec()}, destFlowspec.getPathId(), byteAggregator);
         }
-        return buffer.toString();
     }
 
     @Override
-    protected void serializeMpUnreachNlri(final Attributes2 pathAttributes, final ByteBuf byteAggregator) {
-        if (pathAttributes == null) {
-            return;
-        }
-        final WithdrawnRoutes routes = (pathAttributes.getMpUnreachNlri()).getWithdrawnRoutes();
-        if (routes != null && routes.getDestinationType() instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6Case) {
-            final DestinationFlowspec flowspecCase = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6Case) routes.getDestinationType())
-                    .getDestinationFlowspec();
-            serializeNlri(flowspecCase.getFlowspec(), flowspecCase.getPathId(), byteAggregator);
+    protected void serializeMpUnreachNlri(final DestinationType dstType, final ByteBuf byteAggregator) {
+        if (dstType instanceof org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6Case) {
+            final DestinationFlowspec destFlowspec = ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationFlowspecIpv6Case) dstType)
+                .getDestinationFlowspec();
+            serializeNlri(new Object[] {destFlowspec.getFlowspec()}, destFlowspec.getPathId(), byteAggregator);
         }
     }
 }
+