BUG-6409: Fix L3vpn flowspec routes model 89/44789/1
authorClaudio D. Gasparini <cgaspari@cisco.com>
Sat, 13 Aug 2016 13:34:27 +0000 (15:34 +0200)
committerMilos Fabian <milfabia@cisco.com>
Mon, 29 Aug 2016 13:55:41 +0000 (13:55 +0000)
Fix L3vpn flowspec routes model to fit with
corresponding destination route model.

Change-Id: I4c60d4550b423b42848912da6acde787ebe17661
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
(cherry picked from commit 7ff8942ba27c9c9da54d0520439287146ce5e7b7)

bgp/concepts/pom.xml
bgp/concepts/src/main/java/org/opendaylight/bgp/concepts/RouteDistinguisherUtil.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/AbstractFlowspecL3vpnNlriParser.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/AbstractFlowspecL3vpnRIBSupport.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv4/FlowspecL3vpnIpv4RIBSupport.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/l3vpn/ipv6/FlowspecL3vpnIpv6RIBSupport.java
bgp/flowspec/src/main/yang/bgp-flowspec.yang
bgp/flowspec/src/test/java/org/opendaylight/protocol/bgp/flowspec/FlowspecL3vpnIpv4NlriParserTest.java
features/bgp/src/main/features/features.xml

index a6714532cdc6e708e1dfc66f0f2b5ef8e3c4c872..fcd38bee4e5c28930f96e4a66a60ff296ca708e4 100644 (file)
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>yang-common</artifactId>
         </dependency>
+        <dependency>
+            <groupId>org.opendaylight.yangtools</groupId>
+            <artifactId>yang-data-api</artifactId>
+        </dependency>
         <dependency>
             <groupId>org.opendaylight.yangtools</groupId>
             <artifactId>concepts</artifactId>
index 8069e9ce57add88cce4011862aea83a3f45a1f87..c42ecd1a68843151307faeaff48d52d8755f4095 100644 (file)
@@ -17,6 +17,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.type
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RdTwoOctetAs;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisher;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.RouteDistinguisherBuilder;
+import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.PathArgument;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
+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.NormalizedNode;
+import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -141,4 +147,12 @@ public final class RouteDistinguisherUtil {
             return null;
         }
     }
+
+    public static RouteDistinguisher extractRouteDistinguisher(final DataContainerNode<?> route, final NodeIdentifier rdNid) {
+        final NormalizedNode<?, ?> rdNode = NormalizedNodes.findNode(route, rdNid).orNull();
+        if (rdNode != null) {
+            return parseRouteDistinguisher(rdNode.getValue());
+        }
+        return null;
+    }
 }
index 2a754fd943e59603507d9e8814696a3dc193ad80..7627d30cbe6be25bc85ab41180e5d20f85034f5c 100644 (file)
@@ -7,7 +7,8 @@
  */
 package org.opendaylight.protocol.bgp.flowspec.l3vpn;
 
-import com.google.common.base.Optional;
+import static org.opendaylight.bgp.concepts.RouteDistinguisherUtil.extractRouteDistinguisher;
+
 import com.google.common.base.Preconditions;
 import io.netty.buffer.ByteBuf;
 import java.util.List;
@@ -20,28 +21,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.types.rev130919.RouteDistinguisher;
 import org.opendaylight.yangtools.yang.common.QName;
 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.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-/**
- * @author Kevin Wang
- */
 public abstract class AbstractFlowspecL3vpnNlriParser extends AbstractFlowspecNlriParser {
     private static final Logger LOG = LoggerFactory.getLogger(AbstractFlowspecL3vpnNlriParser.class);
+    public static final NodeIdentifier RD_NID = new NodeIdentifier(QName.create(Flowspec.QNAME.getNamespace(), Flowspec.QNAME.getRevision(), "route-distinguisher"));
 
-    private static final NodeIdentifier RD_NID = new NodeIdentifier(QName.create(Flowspec.QNAME.getNamespace(), Flowspec.QNAME.getRevision(), "route-distinguisher"));
-
-    protected AbstractFlowspecL3vpnNlriParser(SimpleFlowspecTypeRegistry flowspecTypeRegistry) {
+    protected AbstractFlowspecL3vpnNlriParser(final SimpleFlowspecTypeRegistry flowspecTypeRegistry) {
         super(flowspecTypeRegistry);
     }
 
     @Override
     public String stringNlri(final DataContainerNode<?> flowspec) {
         final StringBuilder buffer = new StringBuilder();
-        final RouteDistinguisher rd = extractRouteDistinguisher(flowspec);
+        final RouteDistinguisher rd = extractRouteDistinguisher(flowspec, RD_NID);
         if (rd != null) {
             buffer.append("[l3vpn with route-distinguisher ").append(rd.getValue()).append("] ");
         }
@@ -49,21 +44,13 @@ public abstract class AbstractFlowspecL3vpnNlriParser extends AbstractFlowspecNl
         return buffer.toString();
     }
 
-    public static final RouteDistinguisher extractRouteDistinguisher(final DataContainerNode<?> route) {
-        final Optional<DataContainerChild<? extends PathArgument, ?>> rdNode = route.getChild(RD_NID);
-        if (rdNode.isPresent()) {
-            return RouteDistinguisherUtil.parseRouteDistinguisher(rdNode.get().getValue());
-        }
-        return null;
-    }
-
     /**
      * For flowspec-l3vpn, there is a route distinguisher field at the beginning of NLRI (8 bytes)
      *
      * @param nlri
      * @return
      */
-    private static final RouteDistinguisher readRouteDistinguisher(final ByteBuf nlri) {
+    private static RouteDistinguisher readRouteDistinguisher(final ByteBuf nlri) {
         final RouteDistinguisher rd = RouteDistinguisherUtil.parseRouteDistinguisher(nlri);
         LOG.trace("Route Distinguisher read from NLRI: {}", rd);
         return rd;
index c5c70d00aced8ce8f8d10b808a7a79cd5d19cdec..d1fc2f724fe99736a38dee50acf1e69aaa107cc2 100644 (file)
@@ -7,11 +7,12 @@
  */
 package org.opendaylight.protocol.bgp.flowspec.l3vpn;
 
+import static org.opendaylight.bgp.concepts.RouteDistinguisherUtil.extractRouteDistinguisher;
+
 import com.google.common.collect.Iterables;
 import java.util.Collection;
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
-import org.opendaylight.bgp.concepts.RouteDistinguisherUtil;
+
 import org.opendaylight.protocol.bgp.flowspec.AbstractFlowspecRIBSupport;
 import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.FlowspecL3vpnSubsequentAddressFamily;
@@ -24,15 +25,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.type
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.common.QName;
 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.DataContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 
-/**
- * @author Kevin Wang
- */
 public abstract class AbstractFlowspecL3vpnRIBSupport<T extends AbstractFlowspecL3vpnNlriParser> extends AbstractFlowspecRIBSupport<T> {
     private final NodeIdentifier routeDistinguisherNID;
 
@@ -45,18 +39,7 @@ public abstract class AbstractFlowspecL3vpnRIBSupport<T extends AbstractFlowspec
         final T flowspecNlriParser
     ) {
         super(cazeClass, containerClass, listClass, afiClass, FlowspecL3vpnSubsequentAddressFamily.class, dstContainerClassQName, flowspecNlriParser);
-        final QName routeDistinguisherQName = QName.create(routeQName(), "route-distinguisher").intern();
-        routeDistinguisherNID = new NodeIdentifier(routeDistinguisherQName);
-    }
-
-    @Nullable
-    private RouteDistinguisher buildRouteDistinguisher(final DataContainerNode<? extends PathArgument> data) {
-        final NormalizedNode<?, ?> rdNode = NormalizedNodes.findNode(data, routeDistinguisherNID).orNull();
-        RouteDistinguisher rd = null;
-        if (rdNode != null) {
-            rd = RouteDistinguisherUtil.parseRouteDistinguisher(rdNode.getValue());
-        }
-        return rd;
+        this.routeDistinguisherNID = new NodeIdentifier(QName.create(routeQName(), "route-distinguisher").intern());
     }
 
     @Nonnull
@@ -64,7 +47,7 @@ public abstract class AbstractFlowspecL3vpnRIBSupport<T extends AbstractFlowspec
     protected DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes) {
         final MapEntryNode routesCont = Iterables.getOnlyElement(routes);
         final PathId pathId = PathIdUtil.buildPathId(routesCont, routePathIdNid());
-        final RouteDistinguisher rd = buildRouteDistinguisher(routesCont);
+        final RouteDistinguisher rd = extractRouteDistinguisher(routesCont, this.routeDistinguisherNID);
         return this.nlriParser.createAdvertizedRoutesDestinationType(
             new Object[] {rd, this.nlriParser.extractFlowspec(routesCont)},
             pathId
@@ -76,7 +59,7 @@ public abstract class AbstractFlowspecL3vpnRIBSupport<T extends AbstractFlowspec
     protected DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes) {
         final MapEntryNode routesCont = Iterables.getOnlyElement(routes);
         final PathId pathId = PathIdUtil.buildPathId(routesCont, routePathIdNid());
-        final RouteDistinguisher rd = buildRouteDistinguisher(routesCont);
+            final RouteDistinguisher rd = extractRouteDistinguisher(routesCont, this.routeDistinguisherNID);
         return this.nlriParser.createWithdrawnDestinationType(
             new Object[] {rd, nlriParser.extractFlowspec(Iterables.getOnlyElement(routes))},
             pathId
index a21afe505969e9a3aaeea3c2b2eacd322956aa4f..0338cabc177e74a2de6accaa2209c74561efed43 100644 (file)
@@ -10,28 +10,25 @@ package org.opendaylight.protocol.bgp.flowspec.l3vpn.ipv4;
 import org.opendaylight.protocol.bgp.flowspec.SimpleFlowspecExtensionProviderContext;
 import org.opendaylight.protocol.bgp.flowspec.l3vpn.AbstractFlowspecL3vpnRIBSupport;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.bgp.rib.rib.loc.rib.tables.routes.FlowspecL3vpnIpv4RoutesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.ipv4.route.FlowspecRoute;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv4.DestinationFlowspecL3vpnIpv4;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.ipv4.routes.FlowspecL3vpnIpv4Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.ipv4.route.FlowspecL3vpnRoute;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
 
-/**
- * @author Kevin Wang
- */
 public final class FlowspecL3vpnIpv4RIBSupport extends AbstractFlowspecL3vpnRIBSupport<FlowspecL3vpnIpv4NlriParser> {
 
-    public FlowspecL3vpnIpv4RIBSupport(SimpleFlowspecExtensionProviderContext context) {
+    public FlowspecL3vpnIpv4RIBSupport(final SimpleFlowspecExtensionProviderContext context) {
         super(
             FlowspecL3vpnIpv4RoutesCase.class,
             FlowspecL3vpnIpv4Routes.class,
-            FlowspecRoute.class,
+            FlowspecL3vpnRoute.class,
             DestinationFlowspecL3vpnIpv4.QNAME,
             Ipv4AddressFamily.class,
             new FlowspecL3vpnIpv4NlriParser(context.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV4, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN))
         );
     }
 
-    public static final FlowspecL3vpnIpv4RIBSupport getInstance(SimpleFlowspecExtensionProviderContext context) {
+    public static FlowspecL3vpnIpv4RIBSupport getInstance(final SimpleFlowspecExtensionProviderContext context) {
         return new FlowspecL3vpnIpv4RIBSupport(context);
     }
 }
index fe6a22da6910dcd4b9ecdfddae7273f25e5b2293..0c48539608e239b78da16a3a46ec22ce2fc72080 100644 (file)
@@ -10,28 +10,24 @@ package org.opendaylight.protocol.bgp.flowspec.l3vpn.ipv6;
 import org.opendaylight.protocol.bgp.flowspec.SimpleFlowspecExtensionProviderContext;
 import org.opendaylight.protocol.bgp.flowspec.l3vpn.AbstractFlowspecL3vpnRIBSupport;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.bgp.rib.rib.loc.rib.tables.routes.FlowspecL3vpnIpv6RoutesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.ipv6.route.FlowspecRoute;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.destination.ipv6.DestinationFlowspecL3vpnIpv6;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.ipv6.route.FlowspecL3vpnRoute;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.l3vpn.ipv6.routes.FlowspecL3vpnIpv6Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
 
-/**
- * @author Kevin Wang
- */
 public final class FlowspecL3vpnIpv6RIBSupport extends AbstractFlowspecL3vpnRIBSupport<FlowspecL3vpnIpv6NlriParser> {
-
-    public FlowspecL3vpnIpv6RIBSupport(SimpleFlowspecExtensionProviderContext context) {
+    private FlowspecL3vpnIpv6RIBSupport(SimpleFlowspecExtensionProviderContext context) {
         super(
             FlowspecL3vpnIpv6RoutesCase.class,
             FlowspecL3vpnIpv6Routes.class,
-            FlowspecRoute.class,
+            FlowspecL3vpnRoute.class,
             DestinationFlowspecL3vpnIpv6.QNAME,
             Ipv6AddressFamily.class,
             new FlowspecL3vpnIpv6NlriParser(context.getFlowspecTypeRegistry(SimpleFlowspecExtensionProviderContext.AFI.IPV6, SimpleFlowspecExtensionProviderContext.SAFI.FLOWSPEC_VPN))
         );
     }
 
-    public static final FlowspecL3vpnIpv6RIBSupport getInstance(SimpleFlowspecExtensionProviderContext context) {
+    public static FlowspecL3vpnIpv6RIBSupport getInstance(final SimpleFlowspecExtensionProviderContext context) {
         return new FlowspecL3vpnIpv6RIBSupport(context);
     }
 }
index 4347f9bba605b9817082f41a25232cfd96bd92ee..2013376ff32c37f09935539cd43cba45a5f49942 100644 (file)
@@ -461,39 +461,59 @@ module bgp-flowspec {
         }
     }
 
+    grouping flowspec-ipv4-route-list {
+        leaf route-key {
+            description
+                "The sole function of this leaf
+                to act as the key in the list.
+                Its format does not form the
+                API contract of this model.";
+            type string;
+        }
+        uses flowspec-destination-group-ipv4;
+        uses bgp-rib-route;
+    }
+
     grouping flowspec-ipv4-route {
         list flowspec-route {
-            leaf route-key {
-                description
-                    "The sole function of this leaf
-                    to act as the key in the list.
-                    Its format does not form the
-                    API contract of this model.";
-                type string;
-            }
             key "route-key path-id";
+            uses flowspec-ipv4-route-list;
+        }
+    }
 
-            uses flowspec-destination-group-ipv4;
+    grouping flowspec-l3vpn-ipv4-route {
+        list flowspec-l3vpn-route {
+            key "route-key path-id";
+            uses flowspec-ipv4-route-list;
+            uses flowspec-l3vpn-rd;
+        }
+    }
 
-            uses bgp-rib-route;
+    grouping flowspec-ipv6-route-list {
+        uses flowspec-destination-group-ipv6;
+        uses bgp-rib-route;
+        leaf route-key {
+            description
+                "The sole function of this leaf
+                to act as the key in the list.
+                Its format does not form the
+                API contract of this model.";
+            type string;
         }
     }
 
     grouping flowspec-ipv6-route {
         list flowspec-route {
-            leaf route-key {
-                description
-                    "The sole function of this leaf
-                    to act as the key in the list.
-                    Its format does not form the
-                    API contract of this model.";
-                type string;
-            }
             key "route-key path-id";
+            uses flowspec-ipv6-route-list;
+        }
+    }
 
-            uses flowspec-destination-group-ipv6;
-
-            uses bgp-rib-route;
+    grouping flowspec-l3vpn-ipv6-route {
+        list flowspec-l3vpn-route {
+            key "route-key path-id";
+            uses flowspec-ipv6-route-list;
+            uses flowspec-l3vpn-rd;
         }
     }
 
@@ -511,21 +531,13 @@ module bgp-flowspec {
 
     grouping flowspec-l3vpn-ipv4-routes {
         container flowspec-l3vpn-ipv4-routes {
-            uses flowspec-ipv4-route {
-                augment "flowspec-route" {
-                    uses flowspec-l3vpn-rd;
-                }
-            }
+            uses flowspec-l3vpn-ipv4-route;
         }
     }
 
     grouping flowspec-l3vpn-ipv6-routes {
         container flowspec-l3vpn-ipv6-routes {
-            uses flowspec-ipv6-route {
-                augment "flowspec-route" {
-                    uses flowspec-l3vpn-rd;
-                }
-            }
+            uses flowspec-l3vpn-ipv6-route;
         }
     }
 
index f4ca87037795551da6d96e65cc005c704e638d94..3a4c1f1a26d1db94be5c8143ccc4f73888a4bee1 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.protocol.bgp.flowspec;
 
 import static org.junit.Assert.assertArrayEquals;
 import static org.junit.Assert.assertEquals;
+import static org.opendaylight.bgp.concepts.RouteDistinguisherUtil.extractRouteDistinguisher;
 
 import com.google.common.collect.Lists;
 import com.google.common.collect.Sets;
@@ -801,7 +802,7 @@ public class FlowspecL3vpnIpv4NlriParserTest {
         );
 
         RouteDistinguisher rd = RouteDistinguisherBuilder.getDefaultInstance(ROUTE_DISTINGUISHER);
-        assertEquals(rd, FS_PARSER.extractRouteDistinguisher(entry.build()));
+        assertEquals(rd, extractRouteDistinguisher(entry.build(), FS_PARSER.RD_NID));
     }
 }
 
index e5a1905960a7b2013b783ee527bea9a21bf23fc5..e8b3dac1a360310fa359aca7a5e74dc9a8bfb947 100644 (file)
@@ -58,6 +58,7 @@
         <!--  concepts -->
         <bundle>mvn:com.google.guava/guava/{{VERSION}}</bundle>
         <feature version='${mdsal.model.version}'>odl-mdsal-models</feature>
+        <feature version='${yangtools.version}'>odl-yangtools-yang-data</feature>
         <bundle>mvn:org.opendaylight.bgpcep/concepts/{{VERSION}}</bundle>
         <!-- util -->
         <feature version='[4.0.30,4.1.0)'>odl-netty</feature>