Move EffectiveRibInWriter to Binding independent
[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      * To send routes out, we'd need to transform the DOM representation of route to
203      * binding-aware format. This needs to be done per each AFI/SAFI.
204      *
205      * @param advertised Collection of advertised routes in DOM format
206      * @param withdrawn  Collection of withdrawn routes in DOM format
207      * @param attr       Attributes MpReach is part of Attributes so we need to pass
208      *                   it as argument, create new AttributesBuilder with existing
209      *                   attributes and add MpReach
210      * @return Update message ready to be sent out
211      */
212     @Nonnull
213     Update buildUpdate(
214             @Nonnull Collection<MapEntryNode> advertised,
215             @Nonnull Collection<MapEntryNode> withdrawn,
216             @Nonnull Attributes attr);
217
218     @Nonnull
219     Class<? extends AddressFamily> getAfi();
220
221     @Nonnull
222     Class<? extends SubsequentAddressFamily> getSafi();
223
224     /**
225      * Creates Route table Peer InstanceIdentifier.
226      *
227      * @param tableKey    table InstanceIdentifier
228      * @param newRouteKey route key
229      * @return InstanceIdentifier
230      */
231     @Nonnull
232     InstanceIdentifier<R> createRouteIdentifier(
233             @Nonnull KeyedInstanceIdentifier<Tables, TablesKey> tableKey,
234             @Nonnull I newRouteKey);
235
236     /**
237      * Creates a route with new path Id and attributes.
238      *
239      * @param route route
240      * @param key route key
241      * @param attributes route attributes
242      * @return Route List key
243      */
244     @Nonnull
245     R createRoute(@Nullable R route, @Nonnull I key, @Nonnull Attributes attributes);
246
247     /**
248      * Returns TablesKey which we are providing support.
249      *
250      * @return TablesKey
251      */
252     TablesKey getTablesKey();
253
254     /**
255      * Translates supplied YANG Instance Identifier and NormalizedNode into Binding Route.
256      *
257      * @param routerId Binding Instance Identifier
258      * @param normalizedNode NormalizedNode representing Route
259      * @return Route
260      */
261     R fromNormalizedNode(YangInstanceIdentifier routerId, NormalizedNode<?, ?> normalizedNode);
262
263     /**
264      * Translates supplied YANG Instance Identifier and NormalizedNode into Binding data Attribute.
265      * @param advertisedAttrs NormalizedNode representing attributes
266      * @return Attribute
267      */
268     Attributes attributeFromContainerNode(ContainerNode advertisedAttrs);
269
270     /**
271      * Translates supplied Binding Instance Identifier and data into NormalizedNode representation.
272      * @param routePath Binding Instance Identifier pointing to data
273      * @param attributes Data object representing Attributes
274      * @return NormalizedNode representation
275      */
276     ContainerNode attributeToContainerNode(YangInstanceIdentifier routePath, Attributes attributes);
277
278     interface ApplyRoute {
279         void apply(@Nonnull DOMDataWriteTransaction tx, @Nonnull YangInstanceIdentifier base,
280                    @Nonnull NodeIdentifierWithPredicates routeKey,
281                    @Nonnull DataContainerNode<?> route, ContainerNode attributes);
282     }
283
284     /**
285      * Return the table-type-specific empty routes container, as augmented into the
286      * bgp-peer model under /peer/effect-rib-in/tables/routes choice node. This needs to include all
287      * the skeleton nodes under which the individual routes will be stored.
288      *
289      * @return Protocol-specific case in the routes choice, may not be null.
290      */
291     @Nonnull
292     @Deprecated
293     C emptyRoutesCase();
294
295     /**
296      * Return the table-type-specific empty routes container, as augmented into the
297      * bgp-peer model under /peer/effect-rib-in/tables/routes choice node/routes container. This needs to include all
298      * the skeleton nodes under which the individual routes will be stored.
299      *
300      * @return Protocol-specific container in the routes, may not be null.
301      */
302     @Nonnull
303     S emptyRoutesContainer();
304
305     /**
306      * Construct a Route List Key using new path Id for Families.
307      *
308      * @param pathId   The path identifier
309      * @param routeKey RouteKey
310      * @return route list Key (RouteKey + pathId)
311      */
312     @Nonnull
313     I createRouteListKey(@Nonnull PathId pathId, @Nonnull String routeKey);
314
315     /**
316      * Construct a Route List Key.
317      *
318      * @param routeKey RouteKey
319      * @return route list Key (RouteKey + empty pathId)
320      */
321     @Nonnull
322     default I createRouteListKey(@Nonnull final String routeKey) {
323         return createRouteListKey(NON_PATH_ID, routeKey);
324     }
325
326     /**
327      * Given a route list key, return the associated path ID.
328      *
329      * @param routeListKey Route list key
330      * @return Path ID
331      */
332     @Nonnull
333     PathId extractPathId(@Nonnull I routeListKey);
334
335     /**
336      * Given a route list key, return the associated path ID.
337      *
338      * @param routeListKey Route list key
339      * @return RouteKey
340      */
341     @Nonnull
342     String extractRouteKey(@Nonnull I routeListKey);
343
344     /**
345      * Extract a route list from the adj-rib-in instantiation of table routes.
346      *
347      * @param routes Table route choice
348      * @return A potentially empty list of routes
349      */
350     @Nonnull
351     List<R> extractAdjRibInRoutes(Routes routes);
352 }