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;
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;
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() {
@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);
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));
}
}
*/
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");
evpnRibSupport.deleteDestinationRoutes(tx, yangIdentifier, destination, ROUTES_NODE_ID);
Assert.assertEquals(0, this.routes.size());
- }
+ }*/
}
\ No newline at end of file
*/
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();
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);
+ }
}
}
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());
}
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;
- }
-
}
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());
}
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;
- }
-
}
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;
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;
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;
*/
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
* @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
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);
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));
}
}
}
@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();
}
@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();
}
}
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;
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;
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
}
@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);
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();
}
}
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);
- }
}
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;
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();
}
@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);
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);
}
}
- @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);
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());
}
}
*/
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();
Assert.assertEquals(0, this.routes.size());
}
-
+*/
}
\ No newline at end of file
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() {
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);
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);
*/
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);
}
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;
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;
}
*/
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;
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;
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;
@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.
*
* @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
* @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
* @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) {
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();
}
@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
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();
@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) {
}
}
- @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,
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;
/**
* 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
* @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;
+ }
}
--- /dev/null
+/*
+ * 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());
+ }
+}
*/
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;
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
final ContainerNode nlri = ImmutableContainerNodeBuilder.create().addChild(advertised).withNodeIdentifier(new NodeIdentifier(Nlri.QNAME)).build();
this.testSupport.putRoutes(null, null, nlri, null);
assertEquals(dest, this.destination);
- }
+ }*/
}
<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>