Rib support refactoring II 26/39226/10
authorClaudio D. Gasparini <cgaspari@cisco.com>
Sat, 21 May 2016 18:51:37 +0000 (20:51 +0200)
committerClaudio D. Gasparini <cgaspari@cisco.com>
Fri, 27 May 2016 11:30:45 +0000 (13:30 +0200)
-Implement new abstract class for MP Advertisement
-Fix route Key creation for Mp Advetsiment on extension
Flowspec, Labeled.
-Apply naming convention to variables names on L3vpn
-Remove duplicated code

Change-Id: I833e3da81782574eea5e1bbd424126a98cfbd550
Signed-off-by: Claudio D. Gasparini <cgaspari@cisco.com>
19 files changed:
bgp/evpn/src/main/java/org/opendaylight/protocol/bgp/evpn/impl/EvpnRibSupport.java
bgp/evpn/src/test/java/org/opendaylight/protocol/bgp/evpn/impl/EvpnRibSupportTest.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/AbstractFlowspecRIBSupport.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/FlowspecIpv4RIBSupport.java
bgp/flowspec/src/main/java/org/opendaylight/protocol/bgp/flowspec/FlowspecIpv6RIBSupport.java
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/AbstractVpnRIBSupport.java
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv4/VpnIpv4RIBSupport.java
bgp/l3vpn/src/main/java/org/opendaylight/protocol/bgp/l3vpn/ipv6/VpnIpv6RIBSupport.java
bgp/labeled-unicast/src/main/java/org/opendaylight/protocol/bgp/labeled/unicast/LabeledUnicastRIBSupport.java
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/LinkstateRIBSupport.java
bgp/linkstate/src/test/java/org/opendaylight/protocol/bgp/linkstate/LinkstateRIBSupportTest.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AbstractIPRIBSupport.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/IPv4RIBSupport.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/IPv6RIBSupport.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AbstractRIBSupport.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AddPathRibSupport.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/MultiPathAbstractRIBSupport.java [new file with mode: 0644]
bgp/rib-spi/src/test/java/org/opendaylight/protocol/bgp/rib/spi/AbstractRIBSupportTest.java
features/bgp/src/main/features/features.xml

index 3377b4ab2758f16a4ca4c568a93a0f491535e26d..7db5692a4950c8e06438da6b6c47c94c9e4b7b34 100644 (file)
@@ -12,7 +12,6 @@ import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableSet;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -31,27 +30,18 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.evpn._case.DestinationEvpn;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationEvpnCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.evpn._case.DestinationEvpnBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 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.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 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.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -59,28 +49,16 @@ final class EvpnRibSupport extends AbstractRIBSupport {
     private static final EvpnRibSupport SINGLETON = new EvpnRibSupport();
     private static final Logger LOG = LoggerFactory.getLogger(EvpnRibSupport.class);
     private static final QName ROUTE_KEY = QName.create(EvpnRoute.QNAME, "route-key").intern();
-    private static final NodeIdentifier DESTINATION = NodeIdentifier.create(DestinationEvpn.QNAME);
     private static final NodeIdentifier NLRI_ROUTES_LIST = NodeIdentifier.create(EvpnDestination.QNAME);
-    private static final NodeIdentifier ROUTE = NodeIdentifier.create(EvpnRoute.QNAME);
-
-    private static final ChoiceNode EMPTY_ROUTES = Builders.choiceBuilder().withNodeIdentifier(NodeIdentifier.create(Routes.QNAME))
-        .addChild(Builders.containerBuilder().withNodeIdentifier(NodeIdentifier.create(EvpnRoutes.QNAME))
-            .addChild(ImmutableNodes.mapNodeBuilder(EvpnRoute.QNAME).build()).build()).build();
 
     private EvpnRibSupport() {
-        super(EvpnRoutesCase.class, EvpnRoutes.class, EvpnRoute.class);
+        super(EvpnRoutesCase.class, EvpnRoutes.class, EvpnRoute.class, L2vpnAddressFamily.class, EvpnSubsequentAddressFamily.class, DestinationEvpn.QNAME);
     }
 
     static EvpnRibSupport getInstance() {
         return SINGLETON;
     }
 
-    @Nonnull
-    @Override
-    public ChoiceNode emptyRoutes() {
-        return EMPTY_ROUTES;
-    }
-
     @Nonnull
     @Override
     public ImmutableCollection<Class<? extends DataObject>> cacheableAttributeObjects() {
@@ -100,61 +78,32 @@ final class EvpnRibSupport extends AbstractRIBSupport {
 
     @Nonnull
     @Override
-    protected NodeIdentifier destinationContainerIdentifier() {
-        return DESTINATION;
-    }
-
-    @Override
-    protected void deleteDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath, final ContainerNode destination,
-        final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, null, DELETE_ROUTE);
-    }
-
-    @Override
-    protected void putDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath, final ContainerNode destination,
-        final ContainerNode attributes, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, attributes, putRoute);
+    protected DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes) {
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.reach.nlri.advertized
+            .routes.destination.type.DestinationEvpnCaseBuilder().setDestinationEvpn(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.
+            ns.yang.bgp.evpn.rev160321.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.evpn._case.
+            DestinationEvpnBuilder().setEvpnDestination(extractRoutes(routes)).build()).build();
     }
 
     @Nonnull
     @Override
-    protected MpReachNlri buildReach(final Collection<MapEntryNode> routes, final CNextHop hop) {
-        final MpReachNlriBuilder mb = new MpReachNlriBuilder();
-        mb.setAfi(L2vpnAddressFamily.class);
-        mb.setSafi(EvpnSubsequentAddressFamily.class);
-        mb.setCNextHop(hop);
-
-        final List<EvpnDestination> dests = new ArrayList<>(routes.size());
-        dests.addAll(routes.stream().map(EvpnNlriParser::extractEvpnDestination).collect(Collectors.toList()));
-        mb.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationEvpnCaseBuilder()
-            .setDestinationEvpn(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.update
-                .attributes.mp.reach.nlri.advertized.routes.destination.type.destination.evpn._case.DestinationEvpnBuilder().setEvpnDestination(dests).build()).build()).build());
-        return mb.build();
+    protected DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes) {
+        return new DestinationEvpnCaseBuilder().setDestinationEvpn(new DestinationEvpnBuilder().setEvpnDestination(extractRoutes(routes)).build()).build();
     }
 
-    @Nonnull
-    @Override
-    protected MpUnreachNlri buildUnreach(final Collection<MapEntryNode> routes) {
-        final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder();
-        mb.setAfi(L2vpnAddressFamily.class);
-        mb.setSafi(EvpnSubsequentAddressFamily.class);
-
-        final List<EvpnDestination> dests = new ArrayList<>(routes.size());
-        dests.addAll(routes.stream().map(EvpnNlriParser::extractEvpnDestination).collect(Collectors.toList()));
-        mb.setWithdrawnRoutes(new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp
-            .unreach.nlri.WithdrawnRoutesBuilder().setDestinationType(new DestinationEvpnCaseBuilder().setDestinationEvpn(
-            new DestinationEvpnBuilder().setEvpnDestination(dests).build()).build()).build()).build();
-        return mb.build();
+    private List<EvpnDestination> extractRoutes(final Collection<MapEntryNode> routes) {
+        return routes.stream().map(EvpnNlriParser::extractEvpnDestination).collect(Collectors.toList());
     }
 
-    private void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
+    @Override
+    protected void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
         final ContainerNode destination, final ContainerNode attributes, final ApplyRoute function) {
         if (destination != null) {
             final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = destination.getChild(NLRI_ROUTES_LIST);
             if (maybeRoutes.isPresent()) {
                 final DataContainerChild<? extends PathArgument, ?> routes = maybeRoutes.get();
                 if (routes instanceof UnkeyedListNode) {
-                    final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(ROUTE);
+                    final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(routeNid());
                     for (final UnkeyedListEntryNode e : ((UnkeyedListNode) routes).getValue()) {
                         final NodeIdentifierWithPredicates routeKey = createRouteKey(e);
                         function.apply(tx, base, routeKey, e, attributes);
@@ -170,7 +119,7 @@ final class EvpnRibSupport extends AbstractRIBSupport {
         final ByteBuf buffer = Unpooled.buffer();
         final EvpnDestination dest = EvpnNlriParser.extractRouteKeyDestination(evpn);
         EvpnNlriParser.serializeNlri(Collections.singletonList(dest), buffer);
-        return new NodeIdentifierWithPredicates(EvpnRoute.QNAME, ROUTE_KEY, ByteArray.readAllBytes(buffer));
+        return new NodeIdentifierWithPredicates(routeQName(), ROUTE_KEY, ByteArray.readAllBytes(buffer));
     }
 
 }
index ec12f7f3ebd9b989d9bc697a89db038306742af4..e0d0f6bfbb8fa950c753f51d8ea6f6719e46299a 100644 (file)
@@ -7,55 +7,11 @@
  */
 package org.opendaylight.protocol.bgp.evpn.impl;
 
-import static org.junit.Assert.assertEquals;
-import static org.opendaylight.protocol.bgp.evpn.impl.EvpnTestUtil.RD_MODEL;
-import static org.opendaylight.protocol.bgp.evpn.impl.EvpnTestUtil.createValueBuilder;
-import static org.opendaylight.protocol.bgp.evpn.impl.nlri.EvpnNlriParserTest.createMACIpAdvChoice;
-import static org.opendaylight.protocol.bgp.evpn.spi.pojo.SimpleEvpnNlriRegistryTest.EVPN_NID;
-
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.protocol.bgp.evpn.impl.esi.types.ESIActivator;
-import org.opendaylight.protocol.bgp.evpn.impl.nlri.EthADRParserTest;
-import org.opendaylight.protocol.bgp.evpn.impl.nlri.NlriActivator;
-import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.EvpnSubsequentAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.L2vpnAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.EvpnChoice;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.evpn.rev160321.evpn.destination.EvpnDestination;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-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.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListNodeBuilder;
-
+/**
+ * TODO: Remove, instead use Common Rib Support test
+ */
 public class EvpnRibSupportTest {
-
+/*
     private static final NodeIdentifier RD_NID = NodeIdentifier.create(QName.create(EvpnChoice.QNAME, "route-distinguisher").intern());
     private static final NodeIdentifier ROUTES_NODE_ID = new NodeIdentifier(Routes.QNAME);
     private static final Ipv4Address ipv4 = new Ipv4Address("42.42.42.42");
@@ -148,5 +104,5 @@ public class EvpnRibSupportTest {
 
         evpnRibSupport.deleteDestinationRoutes(tx, yangIdentifier, destination, ROUTES_NODE_ID);
         Assert.assertEquals(0, this.routes.size());
-    }
+    }*/
 }
\ No newline at end of file
index be2e21672601d5fce11b7845ef18ca8425f9e23f..1dd63ef3fd66efabb73f000eb8df798b627e96c1 100644 (file)
@@ -7,54 +7,38 @@
  */
 package org.opendaylight.protocol.bgp.flowspec;
 
+import com.google.common.base.Optional;
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import java.util.Collection;
-import javax.annotation.Nullable;
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
-import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupport;
+import org.opendaylight.protocol.bgp.rib.spi.MultiPathAbstractRIBSupport;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.FlowspecSubsequentAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.ipv6.routes.flowspec.ipv6.routes.FlowspecRoute;
 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.update.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+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.rib.rev130925.Route;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-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.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
-
-public abstract class AbstractFlowspecRIBSupport extends AbstractRIBSupport {
-    private static final QName PATHID_QNAME = QName.create(FlowspecRoute.QNAME, "path-id").intern();
-    private static final NodeIdentifier PATH_ID_NII = new NodeIdentifier(PATHID_QNAME);
-
-    private static final QName ROUTE_KEY = QName.create(FlowspecRoute.QNAME, "route-key").intern();
 
+public abstract class AbstractFlowspecRIBSupport extends MultiPathAbstractRIBSupport {
     protected AbstractFlowspecRIBSupport(final Class<? extends Routes> cazeClass, final Class<? extends DataObject> containerClass,
-        final Class<? extends Route> listClass) {
-        super(cazeClass, containerClass, listClass);
+        final Class<? extends Route> listClass, final Class<? extends AddressFamily> afiClass, final QName destinationQname) {
+        super(cazeClass, containerClass, listClass, afiClass, FlowspecSubsequentAddressFamily.class, "route-key", destinationQname);
     }
 
-    protected abstract NodeIdentifier routeIdentifier();
-
     protected abstract AbstractFlowspecNlriParser getParser();
 
-    protected abstract Class<? extends AddressFamily> getAfiClass();
-
     @Override
     public final ImmutableCollection<Class<? extends DataObject>> cacheableAttributeObjects() {
         return ImmutableSet.of();
@@ -70,64 +54,31 @@ public abstract class AbstractFlowspecRIBSupport extends AbstractRIBSupport {
         return true;
     }
 
+    @Nonnull
     @Override
-    protected final void putDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
-        final ContainerNode destination, final ContainerNode attributes, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, attributes, this.putRoute);
-    }
-
-    @Override
-    protected final void deleteDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
-        final ContainerNode destination, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, null, DELETE_ROUTE);
-    }
-
-    private void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
-        final ContainerNode destination, final ContainerNode attributes, final ApplyRoute function) {
-        if (destination != null) {
-            final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(routeIdentifier());
-            final NodeIdentifierWithPredicates routeKey = new NodeIdentifierWithPredicates(FlowspecRoute.QNAME, ROUTE_KEY, getParser().stringNlri(destination));
-            function.apply(tx, base, routeKey,  destination, attributes);
-        }
-    }
-
-    @Override
-    protected final MpReachNlri buildReach(final Collection<MapEntryNode> routes, final CNextHop hop) {
-        final MpReachNlriBuilder mb = new MpReachNlriBuilder();
-        mb.setAfi(getAfiClass());
-        mb.setSafi(FlowspecSubsequentAddressFamily.class);
-        mb.setCNextHop(hop);
-
+    protected DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes) {
         final MapEntryNode routesCont = Iterables.getOnlyElement(routes);
-        final PathId pathId = PathIdUtil.buildPathId(routesCont, PATH_ID_NII);
-
-        mb.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(getParser().createAdvertizedRoutesDestinationType(
-            getParser().extractFlowspec(routesCont), pathId)).build());
-        return mb.build();
+        final PathId pathId = PathIdUtil.buildPathId(routesCont, routePathIdNid());
+        return getParser().createAdvertizedRoutesDestinationType(getParser().extractFlowspec(routesCont), pathId);
     }
 
+    @Nonnull
     @Override
-    protected final MpUnreachNlri buildUnreach(final Collection<MapEntryNode> routes) {
-        final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder();
-        mb.setAfi(getAfiClass());
-        mb.setSafi(FlowspecSubsequentAddressFamily.class);
-
+    protected DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes) {
         final MapEntryNode routesCont = Iterables.getOnlyElement(routes);
-        final PathId pathId = PathIdUtil.buildPathId(routesCont, PATH_ID_NII);
-
-        mb.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(getParser().createWithdrawnDestinationType(
-            getParser().extractFlowspec(Iterables.getOnlyElement(routes)), pathId)).build());
-        return mb.build();
+        final PathId pathId = PathIdUtil.buildPathId(routesCont, routePathIdNid());
+        return getParser().createWithdrawnDestinationType(getParser().extractFlowspec(Iterables.getOnlyElement(routes)), pathId);
     }
 
-    @Nullable
     @Override
-    public PathArgument getRouteIdAddPath(final long pathId, final PathArgument routeId) {
-        return PathIdUtil.createNidKey(pathId, routeId, FlowspecRoute.QNAME, PATHID_QNAME, ROUTE_KEY);
-    }
-
-    @Override
-    public Long extractPathId(final NormalizedNode<?, ?> data) {
-        return PathIdUtil.extractPathId(data, PATH_ID_NII);
+    protected final void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
+        final ContainerNode destination, final ContainerNode attributes, final ApplyRoute function) {
+        if (destination != null) {
+            final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(routeQName());
+            final Optional<DataContainerChild<? extends PathArgument, ?>> maybePathIdLeaf = destination.getChild(routePathIdNid());
+            final String routeKeyValue = getParser().stringNlri(destination);
+            final NodeIdentifierWithPredicates routeKey = PathIdUtil.createNidKey(routeQName(), routeKeyQName(), pathIdQName(), routeKeyValue, maybePathIdLeaf);
+            function.apply(tx, base, routeKey, destination, attributes);
+        }
     }
 }
index 6505de904a95165d9957f0bef5bad8f033688cbd..4909ca889113cf77df998249b0af3bb798e0c938 100644 (file)
@@ -11,28 +11,14 @@ 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.rev150807.flowspec.routes.FlowspecRoutes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.routes.flowspec.routes.FlowspecRoute;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.flowspec._case.DestinationFlowspec;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 
 final class FlowspecIpv4RIBSupport extends AbstractFlowspecRIBSupport {
 
     private SimpleFlowspecIpv4NlriParser FS_PARSER;
 
-    private final NodeIdentifier destinationNid = new NodeIdentifier(DestinationFlowspec.QNAME);
-    private final NodeIdentifier routeNid = new NodeIdentifier(FlowspecRoute.QNAME);
-    private final ChoiceNode emptyRoutes = Builders.choiceBuilder()
-        .withNodeIdentifier(new NodeIdentifier(Routes.QNAME))
-        .addChild(Builders.containerBuilder()
-            .withNodeIdentifier(new NodeIdentifier(FlowspecRoutes.QNAME))
-            .addChild(ImmutableNodes.mapNodeBuilder(FlowspecRoute.QNAME).build()).build()).build();
-
     public FlowspecIpv4RIBSupport(SimpleFlowspecExtensionProviderContext context) {
-        super(FlowspecRoutesCase.class, FlowspecRoutes.class, FlowspecRoute.class);
+        super(FlowspecRoutesCase.class, FlowspecRoutes.class, FlowspecRoute.class, Ipv4AddressFamily.class, DestinationFlowspec.QNAME);
         FS_PARSER = new SimpleFlowspecIpv4NlriParser(context.getFlowspecIpv4TypeRegistry());
     }
 
@@ -40,29 +26,8 @@ final class FlowspecIpv4RIBSupport extends AbstractFlowspecRIBSupport {
         return new FlowspecIpv4RIBSupport(context);
     }
 
-    @Override
-    public ChoiceNode emptyRoutes() {
-        return this.emptyRoutes;
-    }
-
-    @Override
-    protected NodeIdentifier destinationContainerIdentifier() {
-        return this.destinationNid;
-    }
-
-    @Override
-    protected NodeIdentifier routeIdentifier() {
-        return this.routeNid;
-    }
-
     @Override
     protected AbstractFlowspecNlriParser getParser() {
         return FS_PARSER;
     }
-
-    @Override
-    protected Class<? extends AddressFamily> getAfiClass() {
-        return Ipv4AddressFamily.class;
-    }
-
 }
index c5dfa7adac049de5b0dbace25ad5d97e1dc53e31..6ceacaaf85e9f3a022fcc024bbec1558484ad7d6 100644 (file)
@@ -11,28 +11,14 @@ 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.rev150807.flowspec.ipv6.routes.FlowspecIpv6Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.flowspec.ipv6.routes.flowspec.ipv6.routes.FlowspecRoute;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.flowspec.rev150807.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.flowspec.ipv6._case.DestinationFlowspec;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 
 public final class FlowspecIpv6RIBSupport extends AbstractFlowspecRIBSupport {
 
     private SimpleFlowspecIpv6NlriParser FS_PARSER;
 
-    private final NodeIdentifier destinationNid = new NodeIdentifier(DestinationFlowspec.QNAME);
-    private final NodeIdentifier routeNid = new NodeIdentifier(FlowspecRoute.QNAME);
-    private final ChoiceNode emptyRoutes = Builders.choiceBuilder()
-        .withNodeIdentifier(new NodeIdentifier(Routes.QNAME))
-        .addChild(Builders.containerBuilder()
-            .withNodeIdentifier(new NodeIdentifier(FlowspecIpv6Routes.QNAME))
-            .addChild(ImmutableNodes.mapNodeBuilder(FlowspecRoute.QNAME).build()).build()).build();
-
     public FlowspecIpv6RIBSupport(SimpleFlowspecExtensionProviderContext context) {
-        super(FlowspecIpv6RoutesCase.class, FlowspecIpv6Routes.class, FlowspecRoute.class);
+        super(FlowspecIpv6RoutesCase.class, FlowspecIpv6Routes.class, FlowspecRoute.class, Ipv6AddressFamily.class, DestinationFlowspec.QNAME);
         FS_PARSER = new SimpleFlowspecIpv6NlriParser(context.getFlowspecIpv6TypeRegistry());
     }
 
@@ -40,29 +26,8 @@ public final class FlowspecIpv6RIBSupport extends AbstractFlowspecRIBSupport {
         return new FlowspecIpv6RIBSupport(context);
     }
 
-    @Override
-    public ChoiceNode emptyRoutes() {
-        return this.emptyRoutes;
-    }
-
-    @Override
-    protected NodeIdentifier destinationContainerIdentifier() {
-        return this.destinationNid;
-    }
-
-    @Override
-    protected NodeIdentifier routeIdentifier() {
-        return this.routeNid;
-    }
-
     @Override
     protected AbstractFlowspecNlriParser getParser() {
         return FS_PARSER;
     }
-
-    @Override
-    protected Class<? extends AddressFamily> getAfiClass() {
-        return Ipv6AddressFamily.class;
-    }
-
 }
index 7b72c90775d1d647c384ab2846ca7a52e294cb9a..f0613238d24486d35bf254fb0fa5e9f60cdaa024 100644 (file)
@@ -12,7 +12,6 @@ import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableSet;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
@@ -23,19 +22,12 @@ import org.opendaylight.protocol.bgp.labeled.unicast.LabeledUnicastRIBSupport;
 import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupport;
 import org.opendaylight.protocol.util.ByteArray;
 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.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.MplsLabeledVpnSubsequentAddressFamily;
 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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestination;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.rev160413.l3vpn.ip.destination.type.VpnDestinationBuilder;
 import org.opendaylight.yangtools.yang.binding.DataObject;
@@ -45,15 +37,12 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 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.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 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.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -62,18 +51,12 @@ import org.slf4j.LoggerFactory;
  */
 public abstract class AbstractVpnRIBSupport extends AbstractRIBSupport {
     private static final Logger LOG = LoggerFactory.getLogger(AbstractVpnRIBSupport.class);
-    private final NodeIdentifier NLRI_ROUTES_LIST;
-    private final NodeIdentifier PREFIX_TYPE_NID;
-    private final NodeIdentifier LABEL_STACK_NID;
-    private final NodeIdentifier LV_NID;
-    private final NodeIdentifier RD_NID;
-    private final NodeIdentifier DESTINATION;
-    private final QName ROUTE_KEY;
-    private final NodeIdentifier ROUTE;
-    private final Class<? extends AddressFamily> ADDRESS_FAMILY_CLAZZ;
-    private final QName CONTAINER_CLASS_QNAME;
-    private final QName LIST_CLASS_QNAME;
-    private final ChoiceNode EMPTY_ROUTES;
+    private final NodeIdentifier nlriRoutesListNid;
+    private final NodeIdentifier prefixTypeNid;
+    private final NodeIdentifier labelStackNid;
+    private final NodeIdentifier lvNid;
+    private final NodeIdentifier rdNid;
+    private final QName routeKey;
 
     /**
      * Default constructor. Requires the QName of the container augmented under the routes choice
@@ -85,121 +68,53 @@ public abstract class AbstractVpnRIBSupport extends AbstractRIBSupport {
      * @param containerClass Binding class of the container in routes choice, must not be null.
      * @param listClass      Binding class of the route list, nust not be null;
      */
-    protected AbstractVpnRIBSupport(
-        Class<? extends Routes> cazeClass,
-        Class<? extends DataObject> containerClass,
-        Class<? extends Route> listClass,
-        Class<? extends AddressFamily> addressFamilyClass,
-        final QName VPN_DST_CONTAINER_CLASS_QNAME
-    ) {
-        super(cazeClass, containerClass, listClass);
-        CONTAINER_CLASS_QNAME = BindingReflections.findQName(containerClass).intern();
-        LIST_CLASS_QNAME =
-            QName.create(
-                CONTAINER_CLASS_QNAME.getNamespace(), CONTAINER_CLASS_QNAME.getRevision(), BindingReflections.findQName(listClass).intern().getLocalName()
-            );
-        ROUTE = NodeIdentifier.create(LIST_CLASS_QNAME);
-        ROUTE_KEY = QName.create(LIST_CLASS_QNAME, "route-key").intern();
-        EMPTY_ROUTES = Builders.choiceBuilder()
-            .withNodeIdentifier(YangInstanceIdentifier.NodeIdentifier.create(Routes.QNAME))
-            .addChild(
-                Builders.containerBuilder()
-                    .withNodeIdentifier(YangInstanceIdentifier.NodeIdentifier.create(CONTAINER_CLASS_QNAME))
-                    .addChild(
-                        ImmutableNodes.mapNodeBuilder(
-                            LIST_CLASS_QNAME
-                        ).build()
-                    ).build()
-            ).build();
-        final QName VPN_DST_CLASS_QNAME =
-            QName.create(
-                CONTAINER_CLASS_QNAME.getNamespace(), CONTAINER_CLASS_QNAME.getRevision(), VpnDestination.QNAME.getLocalName()
-            );
-        NLRI_ROUTES_LIST = NodeIdentifier.create(VPN_DST_CLASS_QNAME);
-        PREFIX_TYPE_NID = NodeIdentifier.create(QName.create(VPN_DST_CLASS_QNAME, "prefix").intern());
-        LABEL_STACK_NID = NodeIdentifier.create(QName.create(VPN_DST_CLASS_QNAME, "label-stack").intern());
-        LV_NID = NodeIdentifier.create(QName.create(VPN_DST_CLASS_QNAME, "label-value").intern());
-        RD_NID = NodeIdentifier.create(QName.create(VPN_DST_CLASS_QNAME, "route-distinguisher").intern());
-        DESTINATION = NodeIdentifier.create(VPN_DST_CONTAINER_CLASS_QNAME);
-        ADDRESS_FAMILY_CLAZZ = addressFamilyClass;
+    protected AbstractVpnRIBSupport(Class<? extends Routes> cazeClass, Class<? extends DataObject> containerClass, Class<? extends Route> listClass,
+        Class<? extends AddressFamily> afiClass, final QName vpnDstContainerClassQname) {
+        super(cazeClass, containerClass, listClass, afiClass, MplsLabeledVpnSubsequentAddressFamily.class, vpnDstContainerClassQname);
+        final QName classQname = BindingReflections.findQName(containerClass).intern();
+        routeKey = QName.create(routeQName(), "route-key").intern();
+        final QName vpnDstClassQname = QName.create(classQname, VpnDestination.QNAME.getLocalName());
+        nlriRoutesListNid = NodeIdentifier.create(vpnDstClassQname);
+        prefixTypeNid = NodeIdentifier.create(QName.create(vpnDstClassQname, "prefix").intern());
+        labelStackNid = NodeIdentifier.create(QName.create(vpnDstClassQname, "label-stack").intern());
+        lvNid = NodeIdentifier.create(QName.create(vpnDstClassQname, "label-value").intern());
+        rdNid = NodeIdentifier.create(QName.create(vpnDstClassQname, "route-distinguisher").intern());
     }
 
     private VpnDestination extractVpnDestination(DataContainerNode<? extends PathArgument> route) {
         final VpnDestination dst = new VpnDestinationBuilder()
-            .setPrefix(LabeledUnicastRIBSupport.extractPrefix(route, PREFIX_TYPE_NID))
-            .setLabelStack(LabeledUnicastRIBSupport.extractLabel(route, LABEL_STACK_NID, LV_NID))
+            .setPrefix(LabeledUnicastRIBSupport.extractPrefix(route, prefixTypeNid))
+            .setLabelStack(LabeledUnicastRIBSupport.extractLabel(route, labelStackNid, lvNid))
             .setRouteDistinguisher(extractRouteDistinguisher(route))
             .build();
         return dst;
     }
 
     private RouteDistinguisher extractRouteDistinguisher(final DataContainerNode<? extends YangInstanceIdentifier.PathArgument> route) {
-        if (route.getChild(RD_NID).isPresent()) {
-            return RouteDistinguisherBuilder.getDefaultInstance((String) route.getChild(RD_NID).get().getValue());
+        if (route.getChild(rdNid).isPresent()) {
+            return RouteDistinguisherBuilder.getDefaultInstance((String) route.getChild(rdNid).get().getValue());
         }
         return null;
     }
 
-    @Nonnull
-    @Override
-    public ChoiceNode emptyRoutes() {
-        return EMPTY_ROUTES;
-    }
-
-    @Nonnull
-    @Override
-    protected NodeIdentifier destinationContainerIdentifier() {
-        return DESTINATION;
-    }
-
-    @Override
-    protected void deleteDestinationRoutes(DOMDataWriteTransaction tx, YangInstanceIdentifier tablePath, ContainerNode destination, YangInstanceIdentifier.NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, null, DELETE_ROUTE);
-    }
-
-    @Override
-    protected void putDestinationRoutes(DOMDataWriteTransaction tx, YangInstanceIdentifier tablePath, ContainerNode destination, ContainerNode attributes, YangInstanceIdentifier.NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, attributes, putRoute);
-    }
-
-    protected abstract DestinationType getAdvertizedDestinationType(List<VpnDestination> dests);
+    protected abstract DestinationType getAdvertisedDestinationType(List<VpnDestination> dests);
 
     protected abstract DestinationType getWithdrawnDestinationType(List<VpnDestination> dests);
 
     @Nonnull
     @Override
-    protected MpReachNlri buildReach(Collection<MapEntryNode> routes, CNextHop hop) {
-        final MpReachNlriBuilder mb = new MpReachNlriBuilder()
-            .setAfi(ADDRESS_FAMILY_CLAZZ)
-            .setSafi(MplsLabeledVpnSubsequentAddressFamily.class)
-            .setCNextHop(hop);
-
-        final List<VpnDestination> dests = new ArrayList<>(routes.size());
-        dests.addAll(routes.stream().map(this::extractVpnDestination).collect(Collectors.toList()));
-
-        mb.setAdvertizedRoutes(
-            new AdvertizedRoutesBuilder().setDestinationType(
-                getAdvertizedDestinationType(dests)
-            ).build()
-        ).build();
-        return mb.build();
+    protected DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes) {
+        return getAdvertisedDestinationType(extractRoutes(routes));
     }
 
     @Nonnull
     @Override
-    protected MpUnreachNlri buildUnreach(Collection<MapEntryNode> routes) {
-        final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder()
-            .setAfi(ADDRESS_FAMILY_CLAZZ)
-            .setSafi(MplsLabeledVpnSubsequentAddressFamily.class);
-
-        final List<VpnDestination> dests = new ArrayList<>(routes.size());
-        dests.addAll(routes.stream().map(this::extractVpnDestination).collect(Collectors.toList()));
-
-        mb.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-            getWithdrawnDestinationType(dests)
-            ).build()
-        ).build();
-        return mb.build();
+    protected DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes) {
+        return getWithdrawnDestinationType(extractRoutes(routes));
+    }
+
+    private List<VpnDestination> extractRoutes(final Collection<MapEntryNode> routes) {
+        return routes.stream().map(this::extractVpnDestination).collect(Collectors.toList());
     }
 
     @Nonnull
@@ -219,16 +134,17 @@ public abstract class AbstractVpnRIBSupport extends AbstractRIBSupport {
         return true;
     }
 
-    private void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
+    @Override
+    protected void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
                                     final ContainerNode destination, final ContainerNode attributes, final ApplyRoute function) {
         if (destination != null) {
-            final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = destination.getChild(NLRI_ROUTES_LIST);
+            final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = destination.getChild(this.nlriRoutesListNid);
             if (maybeRoutes.isPresent()) {
                 final DataContainerChild<? extends PathArgument, ?> routes = maybeRoutes.get();
                 if (routes instanceof UnkeyedListNode) {
                     UnkeyedListNode routeListNode = (UnkeyedListNode) routes;
                     LOG.debug("{} routes are found", routeListNode.getSize());
-                    final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(ROUTE);
+                    final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(routeNid());
                     for (final UnkeyedListEntryNode e : routeListNode.getValue()) {
                         final NodeIdentifierWithPredicates routeKey = createRouteKey(e);
                         LOG.debug("Route {} is processed.", routeKey);
@@ -248,6 +164,6 @@ public abstract class AbstractVpnRIBSupport extends AbstractRIBSupport {
 
         final VpnDestination dest = extractVpnDestination(l3vpn);
         AbstractVpnNlriParser.serializeNlri(Collections.singletonList(dest), buffer);
-        return new NodeIdentifierWithPredicates(LIST_CLASS_QNAME, ROUTE_KEY, ByteArray.readAllBytes(buffer));
+        return new NodeIdentifierWithPredicates(routeQName(), this.routeKey, ByteArray.readAllBytes(buffer));
     }
 }
index c647f35dda4fc09275a9c3fe21a5e28e6e53ca89..a24134cefdc7bfef8da6cdc2673f6d1a16b8f6aa 100644 (file)
@@ -30,7 +30,7 @@ final class VpnIpv4RIBSupport extends AbstractVpnRIBSupport {
     }
 
     @Override
-    protected DestinationType getAdvertizedDestinationType(List<VpnDestination> dests) {
+    protected DestinationType getAdvertisedDestinationType(List<VpnDestination> dests) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv4.rev160210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv4CaseBuilder().setVpnIpv4Destination(
             new VpnIpv4DestinationBuilder().setVpnDestination(dests).build()
         ).build();
index 316ac54271174e65a62dd203819315e7bf719ef8..dc3df08fd1518013d50b02f752f5f59b5318aa32 100644 (file)
@@ -34,16 +34,14 @@ final class VpnIpv6RIBSupport extends AbstractVpnRIBSupport {
     }
 
     @Override
-    protected DestinationType getAdvertizedDestinationType(List<VpnDestination> dests) {
+    protected DestinationType getAdvertisedDestinationType(List<VpnDestination> dests) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationVpnIpv6CaseBuilder().setVpnIpv6Destination(
-            new VpnIpv6DestinationBuilder().setVpnDestination(dests).build()
-        ).build();
+            new VpnIpv6DestinationBuilder().setVpnDestination(dests).build()).build();
     }
 
     @Override
     protected DestinationType getWithdrawnDestinationType(List<VpnDestination> dests) {
         return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.vpn.ipv6.rev160331.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationVpnIpv6CaseBuilder().setVpnIpv6Destination(
-            new VpnIpv6DestinationBuilder().setVpnDestination(dests).build()
-        ).build();
+            new VpnIpv6DestinationBuilder().setVpnDestination(dests).build()).build();
     }
 }
index 7a2bd0adb367ba8c565b86dfcf1cfdf173ec68f9..f059cec2d3818d42d983c366986dd64149c0b6fb 100644 (file)
@@ -16,10 +16,11 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
+import java.util.stream.Collectors;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
-import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupport;
+import org.opendaylight.protocol.bgp.rib.spi.MultiPathAbstractRIBSupport;
 import org.opendaylight.protocol.util.ByteArray;
 import org.opendaylight.protocol.util.Ipv4Util;
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;
@@ -36,15 +37,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labe
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLabeledUnicastCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.labeled.unicast._case.DestinationLabeledUnicast;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.labeled.unicast._case.DestinationLabeledUnicastBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
+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.types.rev130919.AddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -52,49 +46,26 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 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.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 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.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-public final class LabeledUnicastRIBSupport extends AbstractRIBSupport {
+public final class LabeledUnicastRIBSupport extends MultiPathAbstractRIBSupport {
 
-    private static final QName PATHID_QNAME = QName.create(LabeledUnicastRoute.QNAME, "path-id").intern();
     private static final Logger LOG = LoggerFactory.getLogger(LabeledUnicastRIBSupport.class);
     private static final NodeIdentifier PREFIX_TYPE_NID = NodeIdentifier.create(QName.create(CLabeledUnicastDestination.QNAME, "prefix").intern());
-    private static final NodeIdentifier PATH_ID_LEAF = new NodeIdentifier(PATHID_QNAME);
     private static final NodeIdentifier LABEL_STACK_NID = NodeIdentifier.create(QName.create(CLabeledUnicastDestination.QNAME, "label-stack").intern());
     private static final NodeIdentifier LV_NID = NodeIdentifier.create(QName.create(CLabeledUnicastDestination.QNAME, "label-value").intern());
-
-    private static final QName ROUTE_KEY = QName.create(LabeledUnicastRoute.QNAME, "route-key").intern();
-
-    private static final ChoiceNode EMPTY_ROUTES = Builders.choiceBuilder()
-        .withNodeIdentifier(NodeIdentifier.create(Routes.QNAME))
-        .addChild(Builders.containerBuilder()
-            .withNodeIdentifier(NodeIdentifier.create(LabeledUnicastRoutes.QNAME))
-            .addChild(ImmutableNodes.mapNodeBuilder(LabeledUnicastRoute.QNAME).build()).build()).build();
-    private static final NodeIdentifier DESTINATION = NodeIdentifier.create(DestinationLabeledUnicast.QNAME);
-    private static final NodeIdentifier ROUTE = NodeIdentifier.create(LabeledUnicastRoute.QNAME);
     private static final NodeIdentifier NLRI_ROUTES_LIST = NodeIdentifier.create(CLabeledUnicastDestination.QNAME);
 
-    private final Class<? extends AddressFamily> afiType;
-
     public LabeledUnicastRIBSupport(final Class<? extends AddressFamily> afiType) {
-        super(LabeledUnicastRoutesCase.class, LabeledUnicastRoutes.class, LabeledUnicastRoute.class);
-        this.afiType = afiType;
-    }
-
-    @Override
-    public ChoiceNode emptyRoutes() {
-        return EMPTY_ROUTES;
+        super(LabeledUnicastRoutesCase.class, LabeledUnicastRoutes.class, LabeledUnicastRoute.class, afiType, LabeledUnicastSubsequentAddressFamily
+            .class, "route-key", DestinationLabeledUnicast.QNAME);
     }
 
     @Override
@@ -113,18 +84,14 @@ public final class LabeledUnicastRIBSupport extends AbstractRIBSupport {
     }
 
     @Override
-    protected NodeIdentifier destinationContainerIdentifier() {
-        return DESTINATION;
-    }
-
-    private void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
+    protected void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
         final ContainerNode destination, final ContainerNode attributes, final ApplyRoute function) {
         if (destination != null) {
             final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = destination.getChild(NLRI_ROUTES_LIST);
             if (maybeRoutes.isPresent()) {
                 final DataContainerChild<? extends PathArgument, ?> routes = maybeRoutes.get();
                 if (routes instanceof UnkeyedListNode) {
-                    final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(ROUTE);
+                    final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(routeNid());
                     for (final UnkeyedListEntryNode e : ((UnkeyedListNode)routes).getValue()) {
                         final NodeIdentifierWithPredicates routeKey = createRouteKey(e);
                         function.apply(tx, base, routeKey, e, attributes);
@@ -141,63 +108,42 @@ public final class LabeledUnicastRIBSupport extends AbstractRIBSupport {
 
         final CLabeledUnicastDestination dest = extractCLabeledUnicastDestination(labeledUnicast);
         LUNlriParser.serializeNlri(Collections.singletonList(dest), buffer);
-        return new NodeIdentifierWithPredicates(LabeledUnicastRoute.QNAME, ROUTE_KEY, ByteArray.readAllBytes(buffer));
-    }
-
-    @Override
-    protected void deleteDestinationRoutes(final DOMDataWriteTransaction tx,
-        final YangInstanceIdentifier tablePath, final ContainerNode destination, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, null, DELETE_ROUTE);
+        final byte[] routeKeyValue = ByteArray.readAllBytes(buffer);
+        final Optional<DataContainerChild<? extends PathArgument, ?>> maybePathIdLeaf = labeledUnicast.getChild(routePathIdNid());
+        final NodeIdentifierWithPredicates routeKey = PathIdUtil.createNidKey(routeQName(), routeKeyQName(), pathIdQName(), routeKeyValue, maybePathIdLeaf);
+        return routeKey;
     }
 
+    @Nonnull
     @Override
-    protected void putDestinationRoutes(final DOMDataWriteTransaction tx,
-        final YangInstanceIdentifier tablePath, final ContainerNode destination,
-        final ContainerNode attributes, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, attributes, this.putRoute);
+    protected DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes) {
+        return new DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
+            new DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(extractRoutes(routes)).build()).build();
     }
 
+    @Nonnull
     @Override
-    protected MpReachNlri buildReach(final Collection<MapEntryNode> routes,
-        final CNextHop hop) {
-        final MpReachNlriBuilder mb = new MpReachNlriBuilder();
-        mb.setAfi(this.afiType);
-        mb.setSafi(LabeledUnicastSubsequentAddressFamily.class);
-        mb.setCNextHop(hop);
-
-        final List<CLabeledUnicastDestination> dests = new ArrayList<>(routes.size());
-        for (final MapEntryNode route : routes) {
-            dests.add(extractCLabeledUnicastDestination(route));
-        }
-        mb.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
-            new DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
-                new DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(dests).build()).build()).build());
-        return mb.build();
+    protected DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes) {
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.labeled.unicast._case.DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(
+                extractRoutes(routes)).build()).build();
     }
 
-    @Override
-    protected MpUnreachNlri buildUnreach(final Collection<MapEntryNode> routes) {
-        final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder();
-        mb.setAfi(this.afiType);
-        mb.setSafi(LabeledUnicastSubsequentAddressFamily.class);
-
-        final List<CLabeledUnicastDestination> dests = new ArrayList<>(routes.size());
-        for (final MapEntryNode route : routes) {
-            dests.add(extractCLabeledUnicastDestination(route));
-        }
-        mb.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLabeledUnicastCaseBuilder().setDestinationLabeledUnicast(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev150525.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.labeled.unicast._case.DestinationLabeledUnicastBuilder().setCLabeledUnicastDestination(
-                    dests).build()).build()).build());
-        return mb.build();
+    private List<CLabeledUnicastDestination> extractRoutes(final Collection<MapEntryNode> routes) {
+        return routes.stream().map(this::extractCLabeledUnicastDestination).collect(Collectors.toList());
     }
 
-    // Conversion from DataContainer to LabeledUnicastDestination Object
-    private static CLabeledUnicastDestination extractCLabeledUnicastDestination(final DataContainerNode<? extends PathArgument> route) {
+    /**
+     * Conversion from DataContainer to LabeledUnicastDestination Object
+     *
+     * @param route DataContainer
+     * @return LabeledUnicastDestination Object
+     */
+    private CLabeledUnicastDestination extractCLabeledUnicastDestination(final DataContainerNode<? extends PathArgument> route) {
         final CLabeledUnicastDestinationBuilder builder = new CLabeledUnicastDestinationBuilder();
         builder.setPrefix(extractPrefix(route, PREFIX_TYPE_NID));
         builder.setLabelStack(extractLabel(route, LABEL_STACK_NID, LV_NID));
-        builder.setPathId(PathIdUtil.buildPathId(route, PATH_ID_LEAF));
+        builder.setPathId(PathIdUtil.buildPathId(route, routePathIdNid()));
         return builder.build();
     }
 
@@ -230,15 +176,4 @@ public final class LabeledUnicastRIBSupport extends AbstractRIBSupport {
         }
         return labels;
     }
-
-    @Nonnull
-    @Override
-    public PathArgument getRouteIdAddPath(final long pathId, final PathArgument routeId) {
-        return PathIdUtil.createNidKey(pathId, routeId, LabeledUnicastRoute.QNAME, PATHID_QNAME, ROUTE_KEY);
-    }
-
-    @Override
-    public Long extractPathId(final NormalizedNode<?, ?> data) {
-        return PathIdUtil.extractPathId(data, PATH_ID_LEAF);
-    }
 }
index afa5b17a9b0a99e128e497822642ddfb9ec474f5..634ed91f4e05508c240d26995ed5360e890aa4b6 100644 (file)
@@ -12,9 +12,10 @@ import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableSet;
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
-import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
+import java.util.stream.Collectors;
+import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.protocol.bgp.linkstate.nlri.LinkstateNlriParser;
 import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupport;
@@ -28,58 +29,37 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationLinkstateCaseBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.linkstate._case.DestinationLinkstate;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.reach.nlri.advertized.routes.destination.type.destination.linkstate._case.DestinationLinkstateBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.destination.DestinationType;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 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.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
 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.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 final class LinkstateRIBSupport extends AbstractRIBSupport {
     private static final Logger LOG = LoggerFactory.getLogger(LinkstateRIBSupport.class);
-
     private static final QName ROUTE_KEY = QName.create(LinkstateRoute.QNAME, "route-key").intern();
     private static final LinkstateRIBSupport SINGLETON = new LinkstateRIBSupport();
-    private final ChoiceNode emptyRoutes = Builders.choiceBuilder()
-        .withNodeIdentifier(new NodeIdentifier(Routes.QNAME))
-        .addChild(Builders.containerBuilder()
-            .withNodeIdentifier(new NodeIdentifier(LinkstateRoutes.QNAME))
-            .addChild(ImmutableNodes.mapNodeBuilder(LinkstateRoute.QNAME).build()).build()).build();
-    private final NodeIdentifier destination = new NodeIdentifier(DestinationLinkstate.QNAME);
     private final NodeIdentifier route = new NodeIdentifier(LinkstateRoute.QNAME);
     private final NodeIdentifier nlriRoutesList = new NodeIdentifier(CLinkstateDestination.QNAME);
 
     private LinkstateRIBSupport() {
-       super(LinkstateRoutesCase.class, LinkstateRoutes.class, LinkstateRoute.class);
+        super(LinkstateRoutesCase.class, LinkstateRoutes.class, LinkstateRoute.class, LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class,
+            DestinationLinkstate.QNAME);
     }
 
     static LinkstateRIBSupport getInstance() {
         return SINGLETON;
     }
 
-    @Override
-    public ChoiceNode emptyRoutes() {
-        return this.emptyRoutes;
-    }
-
     @Override
     public ImmutableCollection<Class<? extends DataObject>> cacheableAttributeObjects() {
         return ImmutableSet.of();
@@ -91,12 +71,12 @@ final class LinkstateRIBSupport extends AbstractRIBSupport {
     }
 
     @Override
-    protected void deleteDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
-        final ContainerNode destination, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, null, DELETE_ROUTE);
+    public boolean isComplexRoute() {
+        return true;
     }
 
-    private void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
+    @Override
+    protected void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
         final ContainerNode destination, final ContainerNode attributes, final ApplyRoute function) {
         if (destination != null) {
             final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = destination.getChild(this.nlriRoutesList);
@@ -104,9 +84,9 @@ final class LinkstateRIBSupport extends AbstractRIBSupport {
                 final DataContainerChild<? extends PathArgument, ?> routes = maybeRoutes.get();
                 if (routes instanceof UnkeyedListNode) {
                     final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(this.route);
-                    for (final UnkeyedListEntryNode e : ((UnkeyedListNode)routes).getValue()) {
+                    for (final UnkeyedListEntryNode e : ((UnkeyedListNode) routes).getValue()) {
                         final NodeIdentifierWithPredicates routeKey = createRouteKey(e);
-                        function.apply(tx, base, routeKey,  e, attributes);
+                        function.apply(tx, base, routeKey, e, attributes);
                     }
                 } else {
                     LOG.warn("Routes {} are not a map", routes);
@@ -115,12 +95,6 @@ final class LinkstateRIBSupport extends AbstractRIBSupport {
         }
     }
 
-    @Override
-    protected void putDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
-        final ContainerNode destination, final ContainerNode attributes, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, attributes, this.putRoute);
-    }
-
     private NodeIdentifierWithPredicates createRouteKey(final UnkeyedListEntryNode linkstate) {
         final ByteBuf buffer = Unpooled.buffer();
         final CLinkstateDestination cLinkstateDestination = LinkstateNlriParser.extractLinkstateDestination(linkstate);
@@ -129,46 +103,22 @@ final class LinkstateRIBSupport extends AbstractRIBSupport {
         return new NodeIdentifierWithPredicates(LinkstateRoute.QNAME, ROUTE_KEY, ByteArray.readAllBytes(buffer));
     }
 
+    @Nonnull
     @Override
-    protected NodeIdentifier destinationContainerIdentifier() {
-        return this.destination;
+    protected DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes) {
+        return new DestinationLinkstateCaseBuilder().setDestinationLinkstate(
+            new DestinationLinkstateBuilder().setCLinkstateDestination(extractRoutes(routes)).build()).build();
     }
 
+    @Nonnull
     @Override
-    public boolean isComplexRoute() {
-        return true;
-    }
-
-    @Override
-    protected MpReachNlri buildReach(final Collection<MapEntryNode> routes, final CNextHop hop) {
-        final MpReachNlriBuilder mb = new MpReachNlriBuilder();
-        mb.setAfi(LinkstateAddressFamily.class);
-        mb.setSafi(LinkstateSubsequentAddressFamily.class);
-        mb.setCNextHop(hop);
-
-        final List<CLinkstateDestination> dests = new ArrayList<>(routes.size());
-        for (final MapEntryNode reachRoute : routes) {
-            dests.add(LinkstateNlriParser.extractLinkstateDestination(reachRoute));
-        }
-        mb.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(
-            new DestinationLinkstateCaseBuilder().setDestinationLinkstate(
-                new DestinationLinkstateBuilder().setCLinkstateDestination(dests).build()).build()).build());
-        return mb.build();
+    protected DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes) {
+        return new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCaseBuilder().setDestinationLinkstate(
+            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.linkstate._case.DestinationLinkstateBuilder().
+                setCLinkstateDestination(extractRoutes(routes)).build()).build();
     }
 
-    @Override
-    protected MpUnreachNlri buildUnreach(final Collection<MapEntryNode> routes) {
-        final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder();
-        mb.setAfi(LinkstateAddressFamily.class);
-        mb.setSafi(LinkstateSubsequentAddressFamily.class);
-
-        final List<CLinkstateDestination> dests = new ArrayList<>(routes.size());
-        for (final MapEntryNode unreachRoute : routes) {
-            dests.add(LinkstateNlriParser.extractLinkstateDestination(unreachRoute));
-        }
-        mb.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(
-            new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationLinkstateCaseBuilder().setDestinationLinkstate(
-                new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.update.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.destination.linkstate._case.DestinationLinkstateBuilder().setCLinkstateDestination(dests).build()).build()).build());
-        return mb.build();
+    private List<CLinkstateDestination> extractRoutes(final Collection<MapEntryNode> routes) {
+        return routes.stream().map(LinkstateNlriParser::extractLinkstateDestination).collect(Collectors.toList());
     }
 }
index 5f3a7d21cf9e21284333f5df47e4a2d396aa1bed..993d44d0ded53fcbcf943b0be4312372a0410de4 100644 (file)
@@ -7,56 +7,11 @@
  */
 package org.opendaylight.protocol.bgp.linkstate;
 
-import static org.junit.Assert.assertEquals;
-
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.Mockito;
-import org.mockito.MockitoAnnotations;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.protocol.bgp.linkstate.nlri.LinkstateNlriParser;
-import org.opendaylight.protocol.bgp.linkstate.nlri.NodeNlriParser;
-import org.opendaylight.protocol.bgp.linkstate.nlri.SimpleNlriTypeRegistry;
-import org.opendaylight.protocol.bgp.parser.BGPParsingException;
-import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.LinkstateSubsequentAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.destination.CLinkstateDestination;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.object.type.NodeCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.node.identifier.CRouterIdentifier;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.Ipv4NextHopCaseBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.c.next.hop.ipv4.next.hop._case.Ipv4NextHopBuilder;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
-import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
-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.UnkeyedListEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeAttrBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.api.DataContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableUnkeyedListNodeBuilder;
-
+/**
+ * TODO: Remove, instead use Common Rib Support test
+ */
 public class LinkstateRIBSupportTest {
-
+/*
     private static final Ipv4Address ipv4 = new Ipv4Address("42.42.42.42");
     private static final NodeIdentifier ROUTES_NODE_ID = new NodeIdentifier(Routes.QNAME);
     final LinkstateRIBSupport link = LinkstateRIBSupport.getInstance();
@@ -190,5 +145,5 @@ public class LinkstateRIBSupportTest {
 
         Assert.assertEquals(0, this.routes.size());
     }
-
+*/
 }
\ No newline at end of file
index c15dcfc9d0cd19ff0ad8912ee4c0c42f5ced25db..a7cb472a5d6cc5eeb798271a2602df5ceedc62b5 100644 (file)
@@ -11,150 +11,49 @@ import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.collect.ImmutableCollection;
 import com.google.common.collect.ImmutableSet;
-import java.util.Collection;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
-import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupport;
-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.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.protocol.bgp.rib.spi.MultiPathAbstractRIBSupport;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
 import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
 import org.opendaylight.yangtools.yang.common.QName;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 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.YangInstanceIdentifier.PathArgument;
-import org.opendaylight.yangtools.yang.data.api.schema.ChoiceNode;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
-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.UnkeyedListEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
-import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
-import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
  * Common {@link org.opendaylight.protocol.bgp.rib.spi.RIBSupport} class for IPv4 and IPv6 addresses.
  */
-abstract class AbstractIPRIBSupport extends AbstractRIBSupport {
+abstract class AbstractIPRIBSupport extends MultiPathAbstractRIBSupport {
     private static final Logger LOG = LoggerFactory.getLogger(AbstractIPRIBSupport.class);
-    private final QName prefixQname;
-    private final QName pathIdQname;
-    private final NodeIdentifier pathIdNid;
     private final NodeIdentifier prefixNid;
-    private final QName routeQname;
-    private final ChoiceNode emptyRoutes;
-    private final NodeIdentifier destination;
     private final NodeIdentifier nlriRoutesList;
     private final ImmutableCollection<Class<? extends DataObject>> cacheableNlriObjects;
-    private final Class<? extends AddressFamily> addressFamilyClass;
 
     protected AbstractIPRIBSupport(final Class<? extends DataObject> prefixClass, final Class<? extends AddressFamily> addressFamilyClass,
         final Class<? extends Routes> cazeClass, final Class<? extends DataObject> containerClass, final Class<? extends Route> listClass,
-        final QName destination, final QName prefixesQname) {
-        super(cazeClass, containerClass, listClass);
-        this.routeQname = BindingReflections.findQName(listClass).intern();
-        this.addressFamilyClass = addressFamilyClass;
-        this.prefixQname = QName.create(this.routeQname, "prefix").intern();
-        this.pathIdQname = QName.create(this.routeQname, "path-id").intern();
-        this.pathIdNid = new NodeIdentifier(this.pathIdQname);
-        this.prefixNid = new NodeIdentifier(this.prefixQname);
-        this.emptyRoutes = Builders.choiceBuilder().withNodeIdentifier(ROUTES).addChild(Builders.containerBuilder()
-            .withNodeIdentifier(routesContainerIdentifier()).withChild(ImmutableNodes.mapNodeBuilder(this.routeQname).build()).build()).build();
-        this.destination = new NodeIdentifier(destination);
+        final QName destinationQname, final QName prefixesQname) {
+        super(cazeClass, containerClass, listClass, addressFamilyClass, UnicastSubsequentAddressFamily.class, "prefix", destinationQname);
+        this.prefixNid = new NodeIdentifier(routeKeyQName());
         this.nlriRoutesList = new NodeIdentifier(prefixesQname);
         this.cacheableNlriObjects = ImmutableSet.of(prefixClass);
     }
 
-    private QName prefixQName() {
-        return this.prefixQname;
-    }
-
-    private QName pathIdQName() {
-        return this.pathIdQname;
-    }
-
-    private QName routeQName() {
-        return this.routeQname;
-    }
-
     protected final NodeIdentifier routePrefixIdentifier() {
         return this.prefixNid;
     }
 
-    protected final NodeIdentifier routePathIdIdentifier() {
-        return this.pathIdNid;
-    }
-
-    @Nonnull
-    @Override
-    protected final NodeIdentifier destinationContainerIdentifier() {
-        return this.destination;
-    }
-
-    @Override
-    protected final void deleteDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
-        final ContainerNode destination, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, null, DELETE_ROUTE);
-    }
-
-    @Override
-    protected final void putDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath, final ContainerNode destination,
-        final ContainerNode attributes, final NodeIdentifier routesNodeId) {
-        processDestination(tx, tablePath.node(routesNodeId), destination, attributes, this.putRoute);
-    }
-
-    @Override
-    protected final MpReachNlri buildReach(final Collection<MapEntryNode> routes, final CNextHop hop) {
-        final MpReachNlriBuilder mb = new MpReachNlriBuilder();
-        mb.setAfi(this.addressFamilyClass);
-        mb.setSafi(UnicastSubsequentAddressFamily.class);
-        mb.setCNextHop(hop);
-        mb.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(buildDestination(routes)).build());
-        return mb.build();
-    }
-
-    @Nonnull
-    @Override
-    protected final MpUnreachNlri buildUnreach(final Collection<MapEntryNode> routes) {
-        final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder();
-        mb.setAfi(this.addressFamilyClass);
-        mb.setSafi(UnicastSubsequentAddressFamily.class);
-        mb.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(buildWithdrawnDestination(routes)).build());
-        return mb.build();
-    }
-
-    @Nonnull
-    @Override
-    public final PathArgument getRouteIdAddPath(final long pathId, final PathArgument routeId) {
-        return PathIdUtil.createNidKey(pathId, routeId, routeQName(), pathIdQName(), prefixQName());
-    }
-
-    @Override
-    public final Long extractPathId(final NormalizedNode<?, ?> data) {
-        return PathIdUtil.extractPathId(data, this.routePathIdIdentifier());
-    }
-
-    @Nonnull
-    @Override
-    public final ChoiceNode emptyRoutes() {
-        return this.emptyRoutes;
-    }
-
     @Nonnull
     @Override
     public final ImmutableCollection<Class<? extends DataObject>> cacheableAttributeObjects() {
@@ -172,7 +71,8 @@ abstract class AbstractIPRIBSupport extends AbstractRIBSupport {
         return false;
     }
 
-    private void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
+    @Override
+    protected void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath,
         final ContainerNode destination, final ContainerNode attributes, final ApplyRoute function) {
         if (destination != null) {
             final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = destination.getChild(this.nlriRoutesList);
@@ -181,7 +81,7 @@ abstract class AbstractIPRIBSupport extends AbstractRIBSupport {
                 if (routes instanceof UnkeyedListNode) {
                     // Instance identifier to table/(choice routes)/(map of route)
                     // FIXME: cache on per-table basis (in TableContext, for example)
-                    final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(this.routesListIdentifier);
+                    final YangInstanceIdentifier base = routesPath.node(routesContainerIdentifier()).node(routeNid());
                     for (final UnkeyedListEntryNode e : ((UnkeyedListNode) routes).getValue()) {
                         final NodeIdentifierWithPredicates routeKey = createRouteKey(e);
                         function.apply(tx, base, routeKey, e, attributes);
@@ -201,15 +101,9 @@ abstract class AbstractIPRIBSupport extends AbstractRIBSupport {
      */
     private NodeIdentifierWithPredicates createRouteKey(final UnkeyedListEntryNode prefixes) {
         final Optional<DataContainerChild<? extends PathArgument, ?>> maybePrefixLeaf = prefixes.getChild(routePrefixIdentifier());
-        final Optional<DataContainerChild<? extends PathArgument, ?>> maybePathIdLeaf = prefixes.getChild(routePathIdIdentifier());
+        final Optional<DataContainerChild<? extends PathArgument, ?>> maybePathIdLeaf = prefixes.getChild(routePathIdNid());
         Preconditions.checkState(maybePrefixLeaf.isPresent());
         final Object prefixValue = (maybePrefixLeaf.get()).getValue();
-        return PathIdUtil.createNidKey(routeQName(), prefixQName(), pathIdQName(), prefixValue, maybePathIdLeaf);
+        return PathIdUtil.createNidKey(routeQName(), routeKeyQName(), pathIdQName(), prefixValue, maybePathIdLeaf);
     }
-
-    @Nonnull
-    protected abstract DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes);
-
-    @Nonnull
-    protected abstract DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes);
 }
index aecddfaa4eb118dfafe0a7d6e032c331d6ad994c..00ce32a162310d081f5a283f650f7396228bca9f 100644 (file)
@@ -46,7 +46,7 @@ final class IPv4RIBSupport extends AbstractIPRIBSupport {
         for (final MapEntryNode route : routes) {
             final String prefix = (String) route.getChild(this.routePrefixIdentifier()).get().getValue();
             final Ipv4PrefixesBuilder prefixBuilder = new Ipv4PrefixesBuilder().setPrefix(new Ipv4Prefix(prefix));
-            prefixBuilder.setPathId(PathIdUtil.buildPathId(route, this.routePathIdIdentifier()));
+            prefixBuilder.setPathId(PathIdUtil.buildPathId(route, this.routePathIdNid()));
             prefs.add(prefixBuilder.build());
         }
         return prefs;
index 434731cabfc93b4192ba3e500cf44db43920cb87..4c5d516c904342d66991988fe330ac5d610c57a1 100644 (file)
@@ -59,7 +59,7 @@ final class IPv6RIBSupport extends AbstractIPRIBSupport {
         final List<Ipv6Prefixes> prefs = new ArrayList<>(routes.size());
         for (final MapEntryNode ipv6Route : routes) {
             final String prefix = (String) ipv6Route.getChild(this.routePrefixIdentifier()).get().getValue();
-            prefs.add(new Ipv6PrefixesBuilder().setPathId(PathIdUtil.buildPathId(ipv6Route, this.routePathIdIdentifier())).setPrefix(new Ipv6Prefix(prefix)).build());
+            prefs.add(new Ipv6PrefixesBuilder().setPathId(PathIdUtil.buildPathId(ipv6Route, this.routePathIdNid())).setPrefix(new Ipv6Prefix(prefix)).build());
         }
         return prefs;
     }
index 25a3d42ac029942f4342e05a191431a53119d806..3618db5e4f9e09b3ee137486e45d9c53743d516c 100644 (file)
@@ -7,15 +7,12 @@
  */
 package org.opendaylight.protocol.bgp.rib.spi;
 
-import static org.opendaylight.protocol.bgp.parser.spi.PathIdUtil.NON_PATH_ID;
-
 import com.google.common.annotations.Beta;
 import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import java.util.Collection;
 import java.util.Collections;
 import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
@@ -28,11 +25,17 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.Attributes2Builder;
 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.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpReachNlriBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder;
 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.reach.nlri.AdvertizedRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
@@ -46,7 +49,6 @@ import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
 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.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
@@ -58,59 +60,122 @@ import org.slf4j.LoggerFactory;
 @Beta
 public abstract class AbstractRIBSupport implements RIBSupport {
     private static final Logger LOG = LoggerFactory.getLogger(AbstractRIBSupport.class);
-    private static final NodeIdentifier ADVERTIZED_ROUTES = new NodeIdentifier(AdvertizedRoutes.QNAME);
+    private static final NodeIdentifier ADVERTISED_ROUTES = new NodeIdentifier(AdvertizedRoutes.QNAME);
     private static final NodeIdentifier WITHDRAWN_ROUTES = new NodeIdentifier(WithdrawnRoutes.QNAME);
     private static final NodeIdentifier DESTINATION_TYPE = new NodeIdentifier(DestinationType.QNAME);
-    protected static final NodeIdentifier ROUTES = new NodeIdentifier(Routes.QNAME);
-    protected static final ApplyRoute DELETE_ROUTE = new DeleteRoute();
+    private static final NodeIdentifier ROUTES = new NodeIdentifier(Routes.QNAME);
+    private static final ApplyRoute DELETE_ROUTE = new DeleteRoute();
 
     private final NodeIdentifier routesContainerIdentifier;
-    protected final NodeIdentifier routesListIdentifier;
+    private final NodeIdentifier routesListIdentifier;
     private final NodeIdentifier routeAttributesIdentifier;
     private final Class<? extends Routes> cazeClass;
     private final Class<? extends DataObject> containerClass;
     private final Class<? extends Route> listClass;
-    protected final ApplyRoute putRoute = new PutRoute();
+    private final ApplyRoute putRoute = new PutRoute();
+    private final ChoiceNode emptyRoutes;
+    private final QName routeQname;
+    private final Class<? extends AddressFamily> afiClass;
+    private final Class<? extends SubsequentAddressFamily> safiClass;
+    private final NodeIdentifier destinationNid;
 
     /**
      * Default constructor. Requires the QName of the container augmented under the routes choice
      * node in instantiations of the rib grouping. It is assumed that this container is defined by
      * the same model which populates it with route grouping instantiation, and by extension with
      * the route attributes container.
-     *
      * @param cazeClass Binding class of the AFI/SAFI-specific case statement, must not be null
      * @param containerClass Binding class of the container in routes choice, must not be null.
      * @param listClass Binding class of the route list, nust not be null;
+     * @param afiClass address Family Class
+     * @param safiClass SubsequentAddressFamily
+     * @param destinationQname destination Qname
      */
-    protected AbstractRIBSupport(final Class<? extends Routes> cazeClass, final Class<? extends DataObject> containerClass, final Class<? extends Route> listClass) {
+    protected AbstractRIBSupport(final Class<? extends Routes> cazeClass, final Class<? extends DataObject> containerClass,
+        final Class<? extends Route> listClass, final Class<? extends AddressFamily> afiClass, final Class<? extends SubsequentAddressFamily> safiClass,
+        final QName destinationQname) {
         final QName qname = BindingReflections.findQName(containerClass).intern();
         this.routesContainerIdentifier = new NodeIdentifier(qname);
         this.routeAttributesIdentifier = new NodeIdentifier(QName.create(qname, Attributes.QNAME.getLocalName().intern()));
         this.cazeClass = Preconditions.checkNotNull(cazeClass);
         this.containerClass = Preconditions.checkNotNull(containerClass);
         this.listClass = Preconditions.checkNotNull(listClass);
-        this.routesListIdentifier = new NodeIdentifier(
-            QName.create(
-                qname.getNamespace(), qname.getRevision(), BindingReflections.findQName(listClass).intern().getLocalName()
-            )
-        );
+        this.routeQname = QName.create(qname, BindingReflections.findQName(listClass).intern().getLocalName());
+        this.routesListIdentifier = new NodeIdentifier(this.routeQname);
+        this.emptyRoutes = Builders.choiceBuilder().withNodeIdentifier(ROUTES).addChild(Builders.containerBuilder()
+            .withNodeIdentifier(routesContainerIdentifier()).withChild(ImmutableNodes.mapNodeBuilder(this.routeQname).build()).build()).build();
+        this.afiClass = afiClass;
+        this.safiClass = safiClass;
+        this.destinationNid = new NodeIdentifier(destinationQname);
     }
 
+    @Nonnull
     @Override
     public final Class<? extends Routes> routesCaseClass() {
         return this.cazeClass;
     }
 
+    @Nonnull
     @Override
     public final Class<? extends DataObject> routesContainerClass() {
         return this.containerClass;
     }
 
+    @Nonnull
     @Override
     public final Class<? extends Route> routesListClass() {
         return this.listClass;
     }
 
+    @Nonnull
+    @Override
+    public final ChoiceNode emptyRoutes() {
+        return this.emptyRoutes;
+    }
+
+    protected final QName routeQName() {
+        return this.routeQname;
+    }
+
+    protected final NodeIdentifier routeNid() {
+        return this.routesListIdentifier;
+    }
+
+    /**
+     * Build MpReachNlri object from DOM representation.
+     *
+     * @param routes Collection of MapEntryNode DOM representation of routes
+     * @param hop CNextHop as it was parsed from Attributes, to be included in MpReach object
+     * @return MpReachNlri
+     */
+    private MpReachNlri buildReach(final Collection<MapEntryNode> routes, final CNextHop hop) {
+        final MpReachNlriBuilder mb = new MpReachNlriBuilder();
+        mb.setAfi(this.afiClass);
+        mb.setSafi(this.safiClass);
+        mb.setCNextHop(hop);
+        mb.setAdvertizedRoutes(new AdvertizedRoutesBuilder().setDestinationType(buildDestination(routes)).build());
+        return mb.build();
+    }
+
+    /**
+     * Build MpUnReachNlri object from DOM representation.
+     *
+     * @param routes Collection of MapEntryNode DOM representation of routes
+     * @return MpUnreachNlri
+     */
+    private MpUnreachNlri buildUnreach(final Collection<MapEntryNode> routes) {
+        final MpUnreachNlriBuilder mb = new MpUnreachNlriBuilder();
+        mb.setAfi(this.afiClass);
+        mb.setSafi(this.safiClass);
+        mb.setWithdrawnRoutes(new WithdrawnRoutesBuilder().setDestinationType(buildWithdrawnDestination(routes)).build());
+        return mb.build();
+    }
+
+    @Nonnull
+    protected abstract DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes);
+    @Nonnull
+    protected abstract DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes);
+
     /**
      * Return the {@link NodeIdentifier} of the AFI/SAFI-specific container under
      * the RIB routes.
@@ -127,7 +192,9 @@ public abstract class AbstractRIBSupport implements RIBSupport {
      *
      * @return Container identifier, may not be null.
      */
-    @Nonnull protected abstract NodeIdentifier destinationContainerIdentifier();
+    private NodeIdentifier destinationContainerIdentifier() {
+        return this.destinationNid;
+    }
 
     /**
      * Given the destination as ContainerNode, implementation needs to parse the DOM model
@@ -142,7 +209,10 @@ public abstract class AbstractRIBSupport implements RIBSupport {
      * @param destination ContainerNode DOM representation of NLRI in Update message
      * @param routesNodeId NodeIdentifier
      */
-    protected abstract void deleteDestinationRoutes(DOMDataWriteTransaction tx, YangInstanceIdentifier tablePath, ContainerNode destination, NodeIdentifier routesNodeId);
+    private void deleteDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
+        final ContainerNode destination, final NodeIdentifier routesNodeId) {
+        processDestination(tx, tablePath.node(routesNodeId), destination, null, DELETE_ROUTE);
+    }
 
     /**
      * Given the destination as ContainerNode, implementation needs to parse the DOM model
@@ -158,8 +228,13 @@ public abstract class AbstractRIBSupport implements RIBSupport {
      * @param attributes ContainerNode to be passed into implementation
      * @param routesNodeId NodeIdentifier
      */
-    protected abstract void putDestinationRoutes(DOMDataWriteTransaction tx, YangInstanceIdentifier tablePath, ContainerNode destination, ContainerNode attributes,
-            NodeIdentifier routesNodeId);
+    private void putDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
+        final ContainerNode destination, final ContainerNode attributes, final NodeIdentifier routesNodeId) {
+        processDestination(tx, tablePath.node(routesNodeId), destination, attributes, this.putRoute);
+    }
+
+    protected abstract void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath, final ContainerNode destination,
+        final ContainerNode attributes, final ApplyRoute applyFunction);
 
     private static ContainerNode getDestination(final DataContainerChild<? extends PathArgument, ?> routes, final NodeIdentifier destinationId) {
         if (routes instanceof ContainerNode) {
@@ -202,7 +277,7 @@ public abstract class AbstractRIBSupport implements RIBSupport {
         if (myRoutes == null) {
             return Collections.emptySet();
         }
-        final DataTreeCandidateNode routesMap = myRoutes.getModifiedChild(this.routesListIdentifier);
+        final DataTreeCandidateNode routesMap = myRoutes.getModifiedChild(routeNid());
         if (routesMap == null) {
             return Collections.emptySet();
         }
@@ -213,7 +288,7 @@ public abstract class AbstractRIBSupport implements RIBSupport {
 
     @Override
     public final YangInstanceIdentifier routePath(final YangInstanceIdentifier routesPath, final PathArgument routeId) {
-        return routesPath.node(this.routesContainerIdentifier).node(this.routesListIdentifier).node(routeId);
+        return routesPath.node(this.routesContainerIdentifier).node(routeNid()).node(routeId);
     }
 
     @Override
@@ -226,25 +301,9 @@ public abstract class AbstractRIBSupport implements RIBSupport {
         putRoutes(tx, tablePath, nlri, attributes, ROUTES);
     }
 
-    /**
-     * Build MpReachNlri object from DOM representation.
-     *
-     * @param routes Collection of MapEntryNode DOM representation of routes
-     * @param hop CNextHop as it was parsed from Attributes, to be included in MpReach object
-     * @return MpReachNlri
-     */
-    @Nonnull protected abstract MpReachNlri buildReach(Collection<MapEntryNode> routes, CNextHop hop);
-
-    /**
-     * Build MpUnReachNlri object from DOM representation.
-     *
-     * @param routes Collection of MapEntryNode DOM representation of routes
-     * @return MpUnreachNlri
-     */
-    @Nonnull protected abstract MpUnreachNlri buildUnreach(Collection<MapEntryNode> routes);
-
+    @Nonnull
     @Override
-    public Update buildUpdate(final Collection<MapEntryNode> advertised, final Collection<MapEntryNode> withdrawn, final Attributes attr) {
+    public final Update buildUpdate(final Collection<MapEntryNode> advertised, final Collection<MapEntryNode> withdrawn, final Attributes attr) {
         final UpdateBuilder ub = new UpdateBuilder();
         final AttributesBuilder ab = new AttributesBuilder(attr);
         final CNextHop hop = ab.getCNextHop();
@@ -282,7 +341,7 @@ public abstract class AbstractRIBSupport implements RIBSupport {
     @Override
     public final void putRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath, final ContainerNode nlri,
             final ContainerNode attributes, final NodeIdentifier routesNodeId) {
-        final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = nlri.getChild(ADVERTIZED_ROUTES);
+        final Optional<DataContainerChild<? extends PathArgument, ?>> maybeRoutes = nlri.getChild(ADVERTISED_ROUTES);
         if (maybeRoutes.isPresent()) {
             final ContainerNode destination = getDestination(maybeRoutes.get(), destinationContainerIdentifier());
             if (destination != null) {
@@ -293,21 +352,6 @@ public abstract class AbstractRIBSupport implements RIBSupport {
         }
     }
 
-    @Nullable
-    @Override
-    /**
-     * Return null for non supporting Add path models
-     */
-    public PathArgument getRouteIdAddPath(final long pathId, final PathArgument routeId) {
-        return null;
-    }
-
-    @Override
-    public Long extractPathId(final NormalizedNode<?, ?> data) {
-        return NON_PATH_ID;
-    }
-
-
     private static class DeleteRoute implements ApplyRoute {
         @Override
         public void apply(final DOMDataWriteTransaction tx, final YangInstanceIdentifier base, final NodeIdentifierWithPredicates routeKey,
index 83196d57008946fce4e8ced963564ec455678382..46867bcc7057c98922aa8ef7af711a37e7e3330d 100644 (file)
@@ -8,6 +8,8 @@
 
 package org.opendaylight.protocol.bgp.rib.spi;
 
+import static org.opendaylight.protocol.bgp.parser.spi.PathIdUtil.NON_PATH_ID;
+
 import javax.annotation.Nullable;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
@@ -15,15 +17,19 @@ import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 /**
  * Interface implemented to be extended by RibSupport.
  * This interface exposes methods to access to Add Path information
+ * By default we implement non supported Multiple Path therefore
+ * 0 Path Id is returned and null PathArgument
  */
-public interface AddPathRibSupport {
+interface AddPathRibSupport {
     /**
      * Extract PathId from route change received
      *
-     * @param normalizedNode
-     * @return pathId  The path identifier from data change, in case its not provided or supported return 0 by default
+     * @param normalizedNode Path Id Container
+     * @return pathId  The path identifier value
      */
-    Long extractPathId(NormalizedNode<?, ?> normalizedNode);
+    default Long extractPathId(NormalizedNode<?, ?> normalizedNode) {
+        return NON_PATH_ID;
+    }
 
     /**
      * Construct a PathArgument to an AddPathRoute
@@ -32,5 +38,7 @@ public interface AddPathRibSupport {
      * @param routeId PathArgument leaf path
      * @return routeId PathArgument + pathId or Null in case Add-path is not supported
      */
-    @Nullable PathArgument getRouteIdAddPath(long pathId, PathArgument routeId);
+    @Nullable default PathArgument getRouteIdAddPath(long pathId, PathArgument routeId) {
+        return null;
+    }
 }
diff --git a/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/MultiPathAbstractRIBSupport.java b/bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/MultiPathAbstractRIBSupport.java
new file mode 100644 (file)
index 0000000..d2e9256
--- /dev/null
@@ -0,0 +1,75 @@
+/*
+ * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v1.0 which accompanies this distribution,
+ * and is available at http://www.eclipse.org/legal/epl-v10.html
+ */
+
+package org.opendaylight.protocol.bgp.rib.spi;
+
+import javax.annotation.Nonnull;
+import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily;
+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.NormalizedNode;
+
+/**
+ * Implements common methods for Advertisement of Multiple Paths on ribSupport
+ */
+public abstract class MultiPathAbstractRIBSupport extends AbstractRIBSupport {
+    private final QName routeKeyQname;
+    private final QName pathIdQname;
+    private final NodeIdentifier pathIdNid;
+
+    /**
+     * Default constructor. Requires the QName of the container augmented under the routes choice
+     * node in instantiations of the rib grouping. It is assumed that this container is defined by
+     * the same model which populates it with route grouping instantiation, and by extension with
+     * the route attributes container.
+     * @param cazeClass Binding class of the AFI/SAFI-specific case statement, must not be null
+     * @param containerClass Binding class of the container in routes choice, must not be null.
+     * @param listClass Binding class of the route list, nust not be null;
+     * @param addressFamilyClass  address Family Class
+     * @param safiClass  SubsequentAddressFamily
+     * @param routeKeyNaming Route Key name (prefix/ route-key / etc..)
+     * @param destinationQname destination Qname
+     */
+    protected MultiPathAbstractRIBSupport(final Class<? extends Routes> cazeClass, final Class<? extends DataObject> containerClass,
+        final Class<? extends Route> listClass, final Class<? extends AddressFamily> addressFamilyClass,
+        final Class<? extends SubsequentAddressFamily> safiClass, final String routeKeyNaming, final QName destinationQname) {
+        super(cazeClass, containerClass, listClass, addressFamilyClass, safiClass, destinationQname);
+        this.routeKeyQname = QName.create(routeQName(), routeKeyNaming).intern();
+        this.pathIdQname = QName.create(routeQName(), "path-id").intern();
+        this.pathIdNid = new NodeIdentifier(this.pathIdQname);
+    }
+
+    protected final NodeIdentifier routePathIdNid() {
+        return this.pathIdNid;
+    }
+
+    protected QName pathIdQName() {
+        return this.pathIdQname;
+    }
+
+    protected QName routeKeyQName() {
+        return this.routeKeyQname;
+    }
+
+    @Nonnull
+    @Override
+    public final PathArgument getRouteIdAddPath(final long pathId, final PathArgument routeId) {
+        return PathIdUtil.createNidKey(pathId, routeId, routeQName(), pathIdQName(), routeKeyQName());
+    }
+
+    @Override
+    public final Long extractPathId(final NormalizedNode<?, ?> data) {
+        return PathIdUtil.extractPathId(data, this.routePathIdNid());
+    }
+}
index 64302300300f8235a234d1ff7955b861ef8c6158..db73b21989dfd68a91736149681334a7893a9943 100644 (file)
@@ -7,60 +7,17 @@
  */
 package org.opendaylight.protocol.bgp.rib.spi;
 
-import static org.junit.Assert.assertEquals;
-
-import com.google.common.collect.ImmutableCollection;
-import java.util.Collection;
-import org.junit.Assert;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv4RoutesCase;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.DestinationIpv4;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.destination.ipv4.Ipv4Prefixes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.Ipv4Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.routes.ipv4.routes.Ipv4Route;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.path.attributes.Attributes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.message.Nlri;
-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.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlri;
-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.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.tables.Routes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.next.hop.CNextHop;
-import org.opendaylight.yangtools.yang.binding.DataObject;
-import org.opendaylight.yangtools.yang.common.QName;
-import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
-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.ContainerNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetEntryNode;
-import org.opendaylight.yangtools.yang.data.api.schema.LeafSetNode;
-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.tree.DataTreeCandidate;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
-import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidates;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableChoiceNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetEntryNodeBuilder;
-import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableLeafSetNodeBuilder;
-
+/**
+ * TODO: Remove, instead use Common Rib Support test
+ */
 public class AbstractRIBSupportTest {
-    private final ContainerNode ipv4p = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(Ipv4Prefixes.QNAME)).build();
+   /* private final ContainerNode ipv4p = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(Ipv4Prefixes.QNAME)).build();
     private final ContainerNode destination = ImmutableContainerNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(DestinationIpv4.QNAME)).addChild(this.ipv4p).build();
     private final ChoiceNode choiceNode = ImmutableChoiceNodeBuilder.create().withNodeIdentifier(new NodeIdentifier(DestinationType.QNAME)).addChild(this.destination).build();
     static ContainerNode dest;
 
-    private final RIBSupport testSupport = new AbstractRIBSupport(Ipv4RoutesCase.class, Ipv4Routes.class, Ipv4Route.class) {
-
-        @Override
-        public ChoiceNode emptyRoutes() {
-            return null;
-        }
-
+    private final RIBSupport testSupport = new AbstractRIBSupport(Ipv4RoutesCase.class, Ipv4Routes.class, Ipv4Route.class,
+        Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, DestinationIpv4.QNAME) {
         @Override
         public ImmutableCollection<Class<? extends DataObject>> cacheableAttributeObjects() {
             return null;
@@ -71,47 +28,27 @@ public class AbstractRIBSupportTest {
             return null;
         }
 
+        @Nonnull
         @Override
-        public PathArgument getRouteIdAddPath(final long pathId, final PathArgument routeId) {
-            throw new UnsupportedOperationException();
+        protected DestinationType buildDestination(@Nonnull final Collection<MapEntryNode> routes) {
+            return null;
         }
 
+        @Nonnull
         @Override
-        protected NodeIdentifier destinationContainerIdentifier() {
-            return new NodeIdentifier(DestinationIpv4.QNAME);
+        protected DestinationType buildWithdrawnDestination(@Nonnull final Collection<MapEntryNode> routes) {
+            return null;
         }
 
         @Override
-        protected void deleteDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
-            final ContainerNode destination, final NodeIdentifier routesNodeId) {
-            AbstractRIBSupportTest.dest = destination;
-        }
+        protected void processDestination(final DOMDataWriteTransaction tx, final YangInstanceIdentifier routesPath, final ContainerNode destination, final ContainerNode attributes, final ApplyRoute applyFunction) {
 
-        @Override
-        protected void putDestinationRoutes(final DOMDataWriteTransaction tx, final YangInstanceIdentifier tablePath,
-            final ContainerNode destination, final ContainerNode attributes, final NodeIdentifier routesNodeId) {
-            AbstractRIBSupportTest.dest = destination;
         }
 
         @Override
         public boolean isComplexRoute() {
             return false;
         }
-
-        @Override
-        public Long extractPathId(final NormalizedNode<?, ?> normalizedNode) {
-            throw new UnsupportedOperationException();
-        }
-
-        @Override
-        protected MpReachNlri buildReach(final Collection<MapEntryNode> routes, final CNextHop hop) {
-            return null;
-        }
-
-        @Override
-        protected MpUnreachNlri buildUnreach(final Collection<MapEntryNode> routes) {
-            return null;
-        }
     };
 
     @Mock
@@ -165,5 +102,5 @@ public class AbstractRIBSupportTest {
         final ContainerNode nlri = ImmutableContainerNodeBuilder.create().addChild(advertised).withNodeIdentifier(new NodeIdentifier(Nlri.QNAME)).build();
         this.testSupport.putRoutes(null, null, nlri, null);
         assertEquals(dest, this.destination);
-    }
+    }*/
 }
index c8d651933886e7221d2dac0e5029a674e44e6aba..ec90ac9432d5bfe3ccdd7d5e3f3ee66e5ba658fe 100644 (file)
@@ -91,6 +91,7 @@
     <feature name='odl-bgpcep-bgp-rib-api' version='${project.version}'>
         <feature version='${project.version}'>odl-bgpcep-bgp-dependencies</feature>
         <bundle>mvn:org.opendaylight.bgpcep/bgp-parser-api/{{VERSION}}</bundle>
+        <bundle>mvn:org.opendaylight.bgpcep/bgp-parser-spi/{{VERSION}}</bundle>
         <feature version='${config.version}'>odl-config-netty-config-api</feature>
         <feature version='${mdsal.version}'>odl-mdsal-broker</feature>
         <bundle>mvn:org.opendaylight.bgpcep/bgp-rib-api/{{VERSION}}</bundle>