2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
8 package org.opendaylight.protocol.bgp.labeled.unicast;
10 import io.netty.buffer.ByteBuf;
11 import io.netty.buffer.Unpooled;
12 import java.util.ArrayList;
13 import java.util.Collection;
14 import java.util.Collections;
15 import java.util.List;
16 import java.util.stream.Collectors;
17 import org.eclipse.jdt.annotation.NonNull;
18 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
19 import org.opendaylight.mdsal.dom.api.DOMDataTreeWriteTransaction;
20 import org.opendaylight.protocol.bgp.parser.spi.PathIdUtil;
21 import org.opendaylight.protocol.bgp.rib.spi.AbstractRIBSupport;
22 import org.opendaylight.protocol.util.ByteArray;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev180329.LabeledUnicastRoutesList;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev180329.LabeledUnicastSubsequentAddressFamily;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev180329.labeled.unicast.LabelStack;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev180329.labeled.unicast.LabelStackBuilder;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev180329.labeled.unicast.destination.CLabeledUnicastDestination;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev180329.labeled.unicast.destination.CLabeledUnicastDestinationBuilder;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.labeled.unicast.rev180329.labeled.unicast.routes.list.LabeledUnicastRoute;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev200120.AddressFamily;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.network.concepts.rev131125.MplsLabel;
34 import org.opendaylight.yangtools.yang.binding.ChildOf;
35 import org.opendaylight.yangtools.yang.binding.DataObject;
36 import org.opendaylight.yangtools.yang.common.QName;
37 import org.opendaylight.yangtools.yang.common.Uint32;
38 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
39 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
40 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
41 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
42 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerChild;
43 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
44 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
45 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListEntryNode;
46 import org.opendaylight.yangtools.yang.data.api.schema.UnkeyedListNode;
47 import org.slf4j.Logger;
48 import org.slf4j.LoggerFactory;
50 abstract class AbstractLabeledUnicastRIBSupport<
51 C extends Routes & DataObject,
52 S extends ChildOf<? super C> & LabeledUnicastRoutesList>
53 extends AbstractRIBSupport<C, S, LabeledUnicastRoute> {
54 private static final NodeIdentifier LABEL_STACK_NID
55 = NodeIdentifier.create(QName.create(CLabeledUnicastDestination.QNAME, "label-stack").intern());
56 private static final NodeIdentifier LV_NID
57 = NodeIdentifier.create(QName.create(CLabeledUnicastDestination.QNAME, "label-value").intern());
58 private static final NodeIdentifier NLRI_ROUTES_LIST = NodeIdentifier.create(CLabeledUnicastDestination.QNAME);
59 private static final Logger LOG = LoggerFactory.getLogger(AbstractLabeledUnicastRIBSupport.class);
62 * Default constructor. Requires the QName of the container augmented under the routes choice
63 * node in instantiations of the rib grouping. It is assumed that this container is defined by
64 * the same model which populates it with route grouping instantiation, and by extension with
65 * the route attributes container.
66 * @param mappingService Binding Normalized Node Serializer
67 * @param cazeClass Binding class of the AFI/SAFI-specific case statement, must not be null
68 * @param containerClass Binding class of the container in routes choice, must not be null.
69 * @param addressFamilyClass address Family Class
70 * @param destinationQname destination Qname
72 AbstractLabeledUnicastRIBSupport(
73 final BindingNormalizedNodeSerializer mappingService,
74 final Class<C> cazeClass,
75 final Class<S> containerClass,
76 final AddressFamily addressFamilyClass,
77 final QName destinationQname) {
81 LabeledUnicastRoute.class,
83 LabeledUnicastSubsequentAddressFamily.VALUE,
88 protected Collection<NodeIdentifierWithPredicates> processDestination(final DOMDataTreeWriteTransaction tx,
89 final YangInstanceIdentifier routesPath,
90 final ContainerNode destination,
91 final ContainerNode attributes,
92 final ApplyRoute function) {
93 if (destination != null) {
94 final DataContainerChild routes = destination.childByArg(NLRI_ROUTES_LIST);
96 if (routes instanceof UnkeyedListNode) {
97 final YangInstanceIdentifier base = routesYangInstanceIdentifier(routesPath);
98 final Collection<UnkeyedListEntryNode> routesList = ((UnkeyedListNode) routes).body();
99 final List<NodeIdentifierWithPredicates> keys = new ArrayList<>(routesList.size());
100 for (final UnkeyedListEntryNode labeledUcastDest : routesList) {
101 final NodeIdentifierWithPredicates routeKey = createRouteKey(labeledUcastDest);
102 function.apply(tx, base, routeKey, labeledUcastDest, attributes);
107 LOG.warn("Routes {} are not a map", routes);
110 return Collections.emptyList();
114 protected List<CLabeledUnicastDestination> extractRoutes(final Collection<MapEntryNode> routes) {
115 return routes.stream().map(this::extractCLabeledUnicastDestination).collect(Collectors.toList());
118 private NodeIdentifierWithPredicates createRouteKey(final UnkeyedListEntryNode labeledUnicast) {
119 final ByteBuf buffer = Unpooled.buffer();
121 final CLabeledUnicastDestination dest = extractCLabeledUnicastDestination(labeledUnicast);
122 LUNlriParser.serializeNlri(Collections.singletonList(dest), false, buffer);
123 final String routeKeyValue = ByteArray.encodeBase64(buffer);
124 return PathIdUtil.createNidKey(routeQName(), routeKeyTemplate(), routeKeyValue,
125 labeledUnicast.findChildByArg(routePathIdNid()));
129 * Conversion from DataContainer to LabeledUnicastDestination Object.
131 * @param route DataContainer
132 * @return LabeledUnicastDestination Object
134 private CLabeledUnicastDestination extractCLabeledUnicastDestination(final DataContainerNode route) {
135 final DataContainerChild child = route.childByArg(prefixNid());
137 return new CLabeledUnicastDestinationBuilder()
138 .setPrefix(child == null ? null : createIpPrefix((String) child.body()))
139 .setLabelStack(extractLabel(route, LABEL_STACK_NID, LV_NID))
140 .setPathId(PathIdUtil.buildPathId(route, routePathIdNid()))
144 protected abstract @NonNull IpPrefix createIpPrefix(@NonNull String prefixString);
146 public static List<LabelStack> extractLabel(final DataContainerNode route, final NodeIdentifier labelStackNid,
147 final NodeIdentifier labelValueNid) {
148 final List<LabelStack> labels = new ArrayList<>();
149 final DataContainerChild labelStacks = route.childByArg(labelStackNid);
150 if (labelStacks != null) {
151 for (final UnkeyedListEntryNode label : ((UnkeyedListNode) labelStacks).body()) {
152 final DataContainerChild labelStack = label.childByArg(labelValueNid);
153 if (labelStack != null) {
154 labels.add(new LabelStackBuilder()
155 .setLabelValue(new MplsLabel((Uint32) labelStack.body()))