694cfb1ef95f93d87d7d6916d2fefef11cfa02f6
[bgpcep.git] / bgp / rib-spi / src / main / java / org / opendaylight / protocol / bgp / rib / spi / RIBSupport.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8 package org.opendaylight.protocol.bgp.rib.spi;
9
10 import static org.opendaylight.protocol.bgp.parser.spi.PathIdUtil.NON_PATH_ID;
11
12 import com.google.common.collect.ImmutableCollection;
13 import com.google.common.collect.ImmutableSet;
14 import java.util.Collection;
15 import java.util.List;
16 import javax.annotation.Nonnull;
17 import javax.annotation.Nullable;
18 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
19 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.PathId;
20 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.Update;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.path.attributes.Attributes;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.Route;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.tables.Routes;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.AddressFamily;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.SubsequentAddressFamily;
28 import org.opendaylight.yangtools.yang.binding.ChildOf;
29 import org.opendaylight.yangtools.yang.binding.ChoiceIn;
30 import org.opendaylight.yangtools.yang.binding.DataObject;
31 import org.opendaylight.yangtools.yang.binding.Identifiable;
32 import org.opendaylight.yangtools.yang.binding.Identifier;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
35 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
36 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifierWithPredicates;
38 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
39 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
40 import org.opendaylight.yangtools.yang.data.api.schema.DataContainerNode;
41 import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
42 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
43 import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode;
44
45 /**
46  * Interface implemented for AFI/SAFI-specific RIB extensions. The extensions need
47  * to register an implementation of this class and the RIB core then calls into it
48  * to inquire about details specific to that particular model.
49  */
50 public interface RIBSupport<
51         C extends Routes & DataObject & ChoiceIn<Tables>,
52         S extends ChildOf<? super C>,
53         R extends Route & ChildOf<? super S> & Identifiable<I>,
54         I extends Identifier<R>> {
55     /**
56      * Return the table-type-specific empty table with routes empty container, as augmented into the
57      * bgp-rib model under /rib/tables/routes choice node. This needs to include all
58      * the skeleton nodes under which the individual routes will be stored.
59      *
60      * @return Protocol-specific case in the routes choice, may not be null.
61      */
62     @Nonnull
63     MapEntryNode emptyTable();
64
65     /**
66      * Return the localized identifier of the attributes route member, as expanded
67      * from the route grouping in the specific augmentation of the base routes choice.
68      *
69      * @return The attributes identifier, may not be null.
70      */
71     @Nonnull
72     NodeIdentifier routeAttributesIdentifier();
73
74     /**
75      * Return class object of the Routes Case statement.
76      *
77      * @return Class
78      */
79     @Nonnull
80     Class<C> routesCaseClass();
81
82     /**
83      * Return class object of the Routes Container statement.
84      *
85      * @return Class
86      */
87     @Nonnull
88     Class<S> routesContainerClass();
89
90     /**
91      * Return class object of the Routes List statement.
92      *
93      * @return Class
94      */
95     @Nonnull
96     Class<R> routesListClass();
97
98     @Nonnull
99     default ImmutableCollection<Class<? extends DataObject>> cacheableAttributeObjects() {
100         return ImmutableSet.of();
101     }
102
103     @Nonnull
104     default ImmutableCollection<Class<? extends DataObject>> cacheableNlriObjects() {
105         return ImmutableSet.of();
106     }
107
108     /**
109      * Given the NLRI as ContainerNode, this method should extract withdrawn routes
110      * from the DOM model and delete them from RIBs.
111      *
112      * @param tx        DOMDataWriteTransaction
113      * @param tablePath YangInstanceIdentifier
114      * @param nlri      ContainerNode DOM representation of NLRI in Update message
115      */
116     void deleteRoutes(@Nonnull DOMDataWriteTransaction tx, @Nonnull YangInstanceIdentifier tablePath,
117             @Nonnull ContainerNode nlri);
118
119
120     /**
121      * Given the NLRI as ContainerNode, this method should extract withdrawn routes
122      * from the DOM model and delete them from RIBs.
123      * <p>
124      * Use this method when removing routes stored in RIBs out of the "bgp-rib" module.
125      * Provide {@link NodeIdentifier} with customized "routes" QName.
126      * For default "bgp-rib" RIBs use {@link #deleteRoutes}
127      * </p>
128      *
129      * @param tx           DOMDataWriteTransaction
130      * @param tablePath    YangInstanceIdentifier
131      * @param nlri         ContainerNode DOM representation of NLRI in Update message
132      * @param routesNodeId NodeIdentifier of "routes" data node
133      */
134     void deleteRoutes(@Nonnull DOMDataWriteTransaction tx, @Nonnull YangInstanceIdentifier tablePath,
135             @Nonnull ContainerNode nlri, @Nonnull NodeIdentifier routesNodeId);
136
137     /**
138      * Given the NLRI as ContainerNode, this method should extract advertised routes
139      * from the DOM model and put them into RIBs.
140      *
141      * @param tx         DOMDataWriteTransaction
142      * @param tablePath  YangInstanceIdentifier
143      * @param nlri       ContainerNode DOM representation of NLRI in Update message
144      * @param attributes ContainerNode
145      * @return List of processed route Identifiers
146      */
147     Collection<NodeIdentifierWithPredicates> putRoutes(@Nonnull DOMDataWriteTransaction tx,
148             @Nonnull YangInstanceIdentifier tablePath, @Nonnull ContainerNode nlri, @Nonnull ContainerNode attributes);
149
150     /**
151      * Given the NLRI as ContainerNode, this method should extract advertised routes
152      * from the DOM model and put them into RIBs.
153      * <p>
154      * Use this method when putting routes stored in RIBs out of the "bgp-rib" module.
155      * Provide {@link NodeIdentifier} with customized "routes" QName.
156      * For default "bgp-rib" RIBs use {@link #putRoutes}
157      * </p>
158      *
159      * @param tx           DOMDataWriteTransaction
160      * @param tablePath    YangInstanceIdentifier
161      * @param nlri         ContainerNode DOM representation of NLRI in Update message
162      * @param attributes   ContainerNode
163      * @param routesNodeId NodeIdentifier of "routes" data node
164      * @return List of processed routes identifiers
165      */
166     Collection<NodeIdentifierWithPredicates> putRoutes(@Nonnull DOMDataWriteTransaction tx,
167             @Nonnull YangInstanceIdentifier tablePath, @Nonnull ContainerNode nlri, @Nonnull ContainerNode attributes,
168             @Nonnull NodeIdentifier routesNodeId);
169
170     /**
171      * Returns routes that were modified within this RIB support instance.
172      *
173      * @param routes DataTreeCandidateNode
174      * @return collection of modified nodes or empty collection if no node was modified
175      */
176     @Nonnull
177     Collection<DataTreeCandidateNode> changedRoutes(@Nonnull DataTreeCandidateNode routes);
178
179     /**
180      * Constructs an instance identifier path to routeId.
181      *
182      * @param routesPath YangInstanceIdentifier base path
183      * @param routeId    PathArgument leaf path
184      * @return YangInstanceIdentifier with routesPath + specific RIB support routes path + routeId
185      */
186     @Nonnull
187     default YangInstanceIdentifier routePath(@Nonnull final YangInstanceIdentifier routesPath,
188                                              @Nonnull final PathArgument routeId) {
189         return routesPath(routesPath).node(routeId);
190     }
191
192     /**
193      * Constructs an instance identifier path to routes list.
194      *
195      * @param routesPath YangInstanceIdentifier base path
196      * @return YangInstanceIdentifier with routesPath + specific RIB support routes path
197      */
198     @Nonnull
199     YangInstanceIdentifier routesPath(@Nonnull YangInstanceIdentifier routesPath);
200
201     /**
202      * Return the relative path from the generic routes container to the AFI/SAFI specific route list.
203      *
204      * @return Relative path.
205      */
206     @Nonnull
207     List<PathArgument> relativeRoutesPath();
208
209     /**
210      * To send routes out, we'd need to transform the DOM representation of route to
211      * binding-aware format. This needs to be done per each AFI/SAFI.
212      *
213      * @param advertised Collection of advertised routes in DOM format
214      * @param withdrawn  Collection of withdrawn routes in DOM format
215      * @param attr       Attributes MpReach is part of Attributes so we need to pass
216      *                   it as argument, create new AttributesBuilder with existing
217      *                   attributes and add MpReach
218      * @return Update message ready to be sent out
219      */
220     @Nonnull
221     Update buildUpdate(
222             @Nonnull Collection<MapEntryNode> advertised,
223             @Nonnull Collection<MapEntryNode> withdrawn,
224             @Nonnull Attributes attr);
225
226     @Nonnull
227     Class<? extends AddressFamily> getAfi();
228
229     @Nonnull
230     Class<? extends SubsequentAddressFamily> getSafi();
231
232     /**
233      * Creates Route table Peer InstanceIdentifier.
234      *
235      * @param tableKey    table InstanceIdentifier
236      * @param newRouteKey route key
237      * @return InstanceIdentifier
238      */
239     @Nonnull
240     InstanceIdentifier<R> createRouteIdentifier(
241             @Nonnull KeyedInstanceIdentifier<Tables, TablesKey> tableKey,
242             @Nonnull I newRouteKey);
243
244     /**
245      * Creates a route with new path Id and attributes.
246      *
247      * @param route route
248      * @param key route key
249      * @param attributes route attributes
250      * @return Route List key
251      */
252     @Nonnull
253     R createRoute(@Nullable R route, @Nonnull I key, @Nonnull Attributes attributes);
254
255     /**
256      * Returns TablesKey which we are providing support.
257      *
258      * @return TablesKey
259      */
260     TablesKey getTablesKey();
261
262     /**
263      * Translates supplied YANG Instance Identifier and NormalizedNode into Binding Route.
264      *
265      * @param routerId Binding Instance Identifier
266      * @param normalizedNode NormalizedNode representing Route
267      * @return Route
268      */
269     R fromNormalizedNode(YangInstanceIdentifier routerId, NormalizedNode<?, ?> normalizedNode);
270
271     /**
272      * Translates supplied YANG Instance Identifier and NormalizedNode into Binding data Attribute.
273      * @param advertisedAttrs NormalizedNode representing attributes
274      * @return Attribute
275      */
276     Attributes attributeFromContainerNode(ContainerNode advertisedAttrs);
277
278     /**
279      * Translates supplied Binding Instance Identifier and data into NormalizedNode representation.
280      * @param routePath Binding Instance Identifier pointing to data
281      * @param attributes Data object representing Attributes
282      * @return NormalizedNode representation
283      */
284     ContainerNode attributeToContainerNode(YangInstanceIdentifier routePath, Attributes attributes);
285
286     interface ApplyRoute {
287         void apply(@Nonnull DOMDataWriteTransaction tx, @Nonnull YangInstanceIdentifier base,
288                    @Nonnull NodeIdentifierWithPredicates routeKey,
289                    @Nonnull DataContainerNode<?> route, ContainerNode attributes);
290     }
291
292     /**
293      * Return the table-type-specific empty routes container, as augmented into the
294      * bgp-peer model under /peer/effect-rib-in/tables/routes choice node. This needs to include all
295      * the skeleton nodes under which the individual routes will be stored.
296      *
297      * @return Protocol-specific case in the routes choice, may not be null.
298      */
299     @Nonnull
300     @Deprecated
301     C emptyRoutesCase();
302
303     /**
304      * Return the table-type-specific empty routes container, as augmented into the
305      * bgp-peer model under /peer/effect-rib-in/tables/routes choice node/routes container. This needs to include all
306      * the skeleton nodes under which the individual routes will be stored.
307      *
308      * @return Protocol-specific container in the routes, may not be null.
309      */
310     @Nonnull
311     S emptyRoutesContainer();
312
313     /**
314      * Construct a Route List Key using new path Id for Families.
315      *
316      * @param pathId   The path identifier
317      * @param routeKey RouteKey
318      * @return route list Key (RouteKey + pathId)
319      */
320     @Nonnull
321     I createRouteListKey(@Nonnull PathId pathId, @Nonnull String routeKey);
322
323     /**
324      * Construct a Route List Key.
325      *
326      * @param routeKey RouteKey
327      * @return route list Key (RouteKey + empty pathId)
328      */
329     @Nonnull
330     default I createRouteListKey(@Nonnull final String routeKey) {
331         return createRouteListKey(NON_PATH_ID, routeKey);
332     }
333
334     /**
335      * Given a route list key, return the associated path ID.
336      *
337      * @param routeListKey Route list key
338      * @return Path ID
339      */
340     @Nonnull
341     PathId extractPathId(@Nonnull I routeListKey);
342
343     /**
344      * Given a route list key, return the associated path ID.
345      *
346      * @param routeListKey Route list key
347      * @return RouteKey
348      */
349     @Nonnull
350     String extractRouteKey(@Nonnull I routeListKey);
351
352     /**
353      * Extract a route list from the adj-rib-in instantiation of table routes.
354      *
355      * @param routes Table route choice
356      * @return A potentially empty list of routes
357      */
358     @Nonnull
359     List<R> extractAdjRibInRoutes(Routes routes);
360 }