import java.util.Collection;
import java.util.Collections;
import java.util.Optional;
-import javax.annotation.Nonnull;
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.rev171207.Update;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.UpdateBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.Attributes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev171207.path.attributes.AttributesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes1;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes1Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes2;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.Attributes2Builder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.destination.DestinationType;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpReachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpReachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpUnreachNlri;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.MpUnreachNlriBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.reach.nlri.AdvertizedRoutes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev171207.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.Route;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.Tables;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.rib.TablesKey;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev171207.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.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.Update;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.UpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.AttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.Attributes2Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.destination.DestinationType;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpReachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlri;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.MpUnreachNlriBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.BgpRib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.Route;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.Rib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.bgp.rib.rib.LocRib;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.AddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisher;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.RouteDistinguisherBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.SubsequentAddressFamily;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.next.hop.CNextHop;
import org.opendaylight.yangtools.yang.binding.DataObject;
import org.opendaylight.yangtools.yang.binding.Identifier;
import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
import org.opendaylight.yangtools.yang.common.QName;
+import org.opendaylight.yangtools.yang.common.QNameModule;
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.slf4j.LoggerFactory;
@Beta
-public abstract class AbstractRIBSupport<R extends Route, N extends Identifier>
- implements RIBSupport<R, N> {
+public abstract class AbstractRIBSupport<
+ C extends Routes & DataObject,
+ S extends DataObject,
+ R extends Route,
+ I extends Identifier>
+ implements RIBSupport<C, S, R, I> {
public static final String ROUTE_KEY = "route-key";
private static final Logger LOG = LoggerFactory.getLogger(AbstractRIBSupport.class);
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);
+ private static final InstanceIdentifier<Tables> TABLES_II = InstanceIdentifier.create(BgpRib.class)
+ .child(Rib.class).child(LocRib.class).child(Tables.class);
private static final NodeIdentifier ROUTES = new NodeIdentifier(Routes.QNAME);
private static final ApplyRoute DELETE_ROUTE = new DeleteRoute();
private final NodeIdentifier routesContainerIdentifier;
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;
+ private final Class<C> cazeClass;
+ private final Class<S> containerClass;
+ private final Class<R> listClass;
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;
+ private final QName pathIdQname;
+ private final NodeIdentifier pathIdNid;
+ private final QName routeKeyQname;
+ private final NodeIdentifier prefixTypeNid;
+ private final NodeIdentifier rdNid;
+ protected final BindingNormalizedNodeSerializer mappingService;
+ protected final YangInstanceIdentifier routeDefaultYii;
/**
* Default constructor. Requires the QName of the container augmented under the routes choice
* the same model which populates it with route grouping instantiation, and by extension with
* the route attributes container.
*
+ * @param mappingService Serialization service
* @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
+ * @param destContainerQname destination Container Qname
*/
protected AbstractRIBSupport(
- final Class<? extends Routes> cazeClass,
- final Class<? extends DataObject> containerClass,
- final Class<? extends Route> listClass, final Class<? extends AddressFamily> afiClass,
+ final BindingNormalizedNodeSerializer mappingService,
+ final Class<C> cazeClass,
+ final Class<S> containerClass,
+ final Class<R> 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()));
+ final QName destContainerQname) {
+ final QNameModule module = BindingReflections.getQNameModule(cazeClass);
+ this.routesContainerIdentifier
+ = new NodeIdentifier(BindingReflections.findQName(containerClass).withModule(module));
+ this.routeAttributesIdentifier = new NodeIdentifier(Attributes.QNAME.withModule(module));
this.cazeClass = requireNonNull(cazeClass);
+ this.mappingService = requireNonNull(mappingService);
this.containerClass = requireNonNull(containerClass);
this.listClass = requireNonNull(listClass);
- this.routeQname = QName.create(qname, BindingReflections.findQName(listClass).intern().getLocalName());
+ this.routeQname = BindingReflections.findQName(listClass).withModule(module);
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();
+ final TablesKey tk = new TablesKey(afiClass, safiClass);
+ //FIXME Use Route Case IId instead of Tables IId.
+ this.emptyRoutes = (ChoiceNode) ((MapEntryNode) this.mappingService
+ .toNormalizedNode(TABLES_II, new TablesBuilder().setKey(tk)
+ .setRoutes(emptyRoutesCase()).build()).getValue())
+ .getChild(new NodeIdentifier(BindingReflections.findQName(Routes.class))).get();
this.afiClass = afiClass;
this.safiClass = safiClass;
- this.destinationNid = new NodeIdentifier(destinationQname);
+ this.destinationNid = new NodeIdentifier(destContainerQname);
+ this.pathIdQname = QName.create(routeQName(), "path-id").intern();
+ this.pathIdNid = new NodeIdentifier(this.pathIdQname);
+ this.routeKeyQname = QName.create(routeQName(), ROUTE_KEY).intern();
+ this.prefixTypeNid = NodeIdentifier.create(QName.create(destContainerQname, "prefix").intern());
+ this.rdNid = NodeIdentifier.create(QName.create(destContainerQname, "route-distinguisher").intern());
+ this.routeDefaultYii =
+ YangInstanceIdentifier.builder()
+ .node(BgpRib.QNAME)
+ .node(Rib.QNAME)
+ .node(Rib.QNAME)
+ .node(LocRib.QNAME)
+ .node(Tables.QNAME)
+ .node(Tables.QNAME)
+ .node(Routes.QNAME)
+ .node(BindingReflections.findQName(containerClass).withModule(module))
+ .node(this.routeQname)
+ .node(this.routeQname).build();
}
@Override
- public final Class<? extends Routes> routesCaseClass() {
+ public final Class<C> routesCaseClass() {
return this.cazeClass;
}
@Override
- public final Class<? extends DataObject> routesContainerClass() {
+ public final Class<S> routesContainerClass() {
return this.containerClass;
}
@Override
- public final Class<? extends Route> routesListClass() {
+ public final Class<R> routesListClass() {
return this.listClass;
}
return this.routeQname;
}
+ protected final NodeIdentifier prefixNid() {
+ return this.prefixTypeNid;
+ }
+
protected final NodeIdentifier routeNid() {
return this.routesListIdentifier;
}
- @Nonnull
@Override
public final Class<? extends AddressFamily> getAfi() {
return this.afiClass;
}
- @Nonnull
@Override
public final Class<? extends SubsequentAddressFamily> getSafi() {
return this.safiClass;
return mb.build();
}
- @Nonnull
- protected abstract DestinationType buildDestination(@Nonnull Collection<MapEntryNode> routes);
+ protected abstract DestinationType buildDestination(Collection<MapEntryNode> routes);
- @Nonnull
- protected abstract DestinationType buildWithdrawnDestination(@Nonnull Collection<MapEntryNode> routes);
+ protected abstract DestinationType buildWithdrawnDestination(Collection<MapEntryNode> routes);
/**
* Return the {@link NodeIdentifier} of the AFI/SAFI-specific container under
@Override
public final InstanceIdentifier<R> createRouteIdentifier(
- final KeyedInstanceIdentifier<Tables, TablesKey> tableIId, final N key) {
+ final KeyedInstanceIdentifier<Tables, TablesKey> tableIId, final I key) {
return tableIId.child((Class) routesContainerClass()).child(routesListClass(), key);
}
putRoutes(tx, tablePath, nlri, attributes, ROUTES);
}
- @Nonnull
@Override
public final Update buildUpdate(final Collection<MapEntryNode> advertised, final Collection<MapEntryNode> withdrawn,
final Attributes attr) {
tx.put(LogicalDatastoreType.OPERATIONAL, base.node(routeKey), b.build());
}
}
+
+ protected final NodeIdentifier routePathIdNid() {
+ return this.pathIdNid;
+ }
+
+ protected final QName pathIdQName() {
+ return this.pathIdQname;
+ }
+
+ protected final QName routeKeyQName() {
+ return this.routeKeyQname;
+ }
+
+ protected final String extractPrefix(final DataContainerNode<? extends PathArgument> route) {
+ return (String) route.getChild(prefixTypeNid).get().getValue();
+ }
+
+ protected final RouteDistinguisher extractRouteDistinguisher(
+ final DataContainerNode<? extends PathArgument> route) {
+ if (route.getChild(this.rdNid).isPresent()) {
+ return RouteDistinguisherBuilder.getDefaultInstance((String) route.getChild(this.rdNid).get().getValue());
+ }
+ return null;
+ }
}