d38532bf9c6f99be2bb71572b365d2b81b06e762
[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.tree.DataTreeCandidateNode;
43
44 /**
45  * Interface implemented for AFI/SAFI-specific RIB extensions. The extensions need
46  * to register an implementation of this class and the RIB core then calls into it
47  * to inquire about details specific to that particular model.
48  */
49 public interface RIBSupport<
50         C extends Routes & DataObject & ChoiceIn<Tables>,
51         S extends ChildOf<? super C>,
52         R extends Route & ChildOf<? super S> & Identifiable<I>,
53         I extends Identifier<R>> {
54     /**
55      * Return the table-type-specific empty table with routes empty container, as augmented into the
56      * bgp-rib model under /rib/tables/routes choice node. This needs to include all
57      * the skeleton nodes under which the individual routes will be stored.
58      *
59      * @return Protocol-specific case in the routes choice, may not be null.
60      */
61     @Nonnull
62     MapEntryNode emptyTable();
63
64     /**
65      * Return the localized identifier of the attributes route member, as expanded
66      * from the route grouping in the specific augmentation of the base routes choice.
67      *
68      * @return The attributes identifier, may not be null.
69      */
70     @Nonnull
71     NodeIdentifier routeAttributesIdentifier();
72
73     /**
74      * Return class object of the Routes Case statement.
75      *
76      * @return Class
77      */
78     @Nonnull
79     Class<C> routesCaseClass();
80
81     /**
82      * Return class object of the Routes Container statement.
83      *
84      * @return Class
85      */
86     @Nonnull
87     Class<S> routesContainerClass();
88
89     /**
90      * Return class object of the Routes List statement.
91      *
92      * @return Class
93      */
94     @Nonnull
95     Class<R> routesListClass();
96
97     @Nonnull
98     default ImmutableCollection<Class<? extends DataObject>> cacheableAttributeObjects() {
99         return ImmutableSet.of();
100     }
101
102     @Nonnull
103     default ImmutableCollection<Class<? extends DataObject>> cacheableNlriObjects() {
104         return ImmutableSet.of();
105     }
106
107     /**
108      * Given the NLRI as ContainerNode, this method should extract withdrawn routes
109      * from the DOM model and delete them from RIBs.
110      *
111      * @param tx        DOMDataWriteTransaction
112      * @param tablePath YangInstanceIdentifier
113      * @param nlri      ContainerNode DOM representation of NLRI in Update message
114      */
115     void deleteRoutes(@Nonnull DOMDataWriteTransaction tx, @Nonnull YangInstanceIdentifier tablePath,
116             @Nonnull ContainerNode nlri);
117
118
119     /**
120      * Given the NLRI as ContainerNode, this method should extract withdrawn routes
121      * from the DOM model and delete them from RIBs.
122      * <p>
123      * Use this method when removing routes stored in RIBs out of the "bgp-rib" module.
124      * Provide {@link NodeIdentifier} with customized "routes" QName.
125      * For default "bgp-rib" RIBs use {@link #deleteRoutes}
126      * </p>
127      *
128      * @param tx           DOMDataWriteTransaction
129      * @param tablePath    YangInstanceIdentifier
130      * @param nlri         ContainerNode DOM representation of NLRI in Update message
131      * @param routesNodeId NodeIdentifier of "routes" data node
132      */
133     void deleteRoutes(@Nonnull DOMDataWriteTransaction tx, @Nonnull YangInstanceIdentifier tablePath,
134             @Nonnull ContainerNode nlri, @Nonnull NodeIdentifier routesNodeId);
135
136     /**
137      * Given the NLRI as ContainerNode, this method should extract advertised routes
138      * from the DOM model and put them into RIBs.
139      *
140      * @param tx         DOMDataWriteTransaction
141      * @param tablePath  YangInstanceIdentifier
142      * @param nlri       ContainerNode DOM representation of NLRI in Update message
143      * @param attributes ContainerNode
144      * @return List of processed route Identifiers
145      */
146     Collection<NodeIdentifierWithPredicates> putRoutes(@Nonnull DOMDataWriteTransaction tx,
147             @Nonnull YangInstanceIdentifier tablePath, @Nonnull ContainerNode nlri, @Nonnull ContainerNode attributes);
148
149     /**
150      * Given the NLRI as ContainerNode, this method should extract advertised routes
151      * from the DOM model and put them into RIBs.
152      * <p>
153      * Use this method when putting routes stored in RIBs out of the "bgp-rib" module.
154      * Provide {@link NodeIdentifier} with customized "routes" QName.
155      * For default "bgp-rib" RIBs use {@link #putRoutes}
156      * </p>
157      *
158      * @param tx           DOMDataWriteTransaction
159      * @param tablePath    YangInstanceIdentifier
160      * @param nlri         ContainerNode DOM representation of NLRI in Update message
161      * @param attributes   ContainerNode
162      * @param routesNodeId NodeIdentifier of "routes" data node
163      * @return List of processed routes identifiers
164      */
165     Collection<NodeIdentifierWithPredicates> putRoutes(@Nonnull DOMDataWriteTransaction tx,
166             @Nonnull YangInstanceIdentifier tablePath, @Nonnull ContainerNode nlri, @Nonnull ContainerNode attributes,
167             @Nonnull NodeIdentifier routesNodeId);
168
169     /**
170      * Returns routes that were modified within this RIB support instance.
171      *
172      * @param routes DataTreeCandidateNode
173      * @return collection of modified nodes or empty collection if no node was modified
174      */
175     @Nonnull
176     Collection<DataTreeCandidateNode> changedRoutes(@Nonnull DataTreeCandidateNode routes);
177
178     /**
179      * Constructs an instance identifier path to routeId.
180      *
181      * @param routesPath YangInstanceIdentifier base path
182      * @param routeId    PathArgument leaf path
183      * @return YangInstanceIdentifier with routesPath + specific RIB support routes path + routeId
184      */
185     @Nonnull
186     default YangInstanceIdentifier routePath(@Nonnull final YangInstanceIdentifier routesPath,
187                                              @Nonnull final PathArgument routeId) {
188         return routesPath(routesPath).node(routeId);
189     }
190
191     /**
192      * Constructs an instance identifier path to routes list.
193      *
194      * @param routesPath YangInstanceIdentifier base path
195      * @return YangInstanceIdentifier with routesPath + specific RIB support routes path
196      */
197     @Nonnull
198     YangInstanceIdentifier routesPath(@Nonnull YangInstanceIdentifier routesPath);
199
200     /**
201      * To send routes out, we'd need to transform the DOM representation of route to
202      * binding-aware format. This needs to be done per each AFI/SAFI.
203      *
204      * @param advertised Collection of advertised routes in DOM format
205      * @param withdrawn  Collection of withdrawn routes in DOM format
206      * @param attr       Attributes MpReach is part of Attributes so we need to pass
207      *                   it as argument, create new AttributesBuilder with existing
208      *                   attributes and add MpReach
209      * @return Update message ready to be sent out
210      */
211     @Nonnull
212     Update buildUpdate(
213             @Nonnull Collection<MapEntryNode> advertised,
214             @Nonnull Collection<MapEntryNode> withdrawn,
215             @Nonnull Attributes attr);
216
217     @Nonnull
218     Class<? extends AddressFamily> getAfi();
219
220     @Nonnull
221     Class<? extends SubsequentAddressFamily> getSafi();
222
223     /**
224      * Creates Route table Peer InstanceIdentifier.
225      *
226      * @param tableKey    table InstanceIdentifier
227      * @param newRouteKey route key
228      * @return InstanceIdentifier
229      */
230     @Nonnull
231     InstanceIdentifier<R> createRouteIdentifier(
232             @Nonnull KeyedInstanceIdentifier<Tables, TablesKey> tableKey,
233             @Nonnull I newRouteKey);
234
235     /**
236      * Creates a route with new path Id and attributes.
237      *
238      * @param route route
239      * @param key route key
240      * @param attributes route attributes
241      * @return Route List key
242      */
243     @Nonnull
244     R createRoute(@Nullable R route, @Nonnull I key, @Nonnull Attributes attributes);
245
246     /**
247      * Returns TablesKey which we are providing support.
248      *
249      * @return TablesKey
250      */
251     TablesKey getTablesKey();
252
253     interface ApplyRoute {
254         void apply(@Nonnull DOMDataWriteTransaction tx, @Nonnull YangInstanceIdentifier base,
255                    @Nonnull NodeIdentifierWithPredicates routeKey,
256                    @Nonnull DataContainerNode<?> route, ContainerNode attributes);
257     }
258
259     /**
260      * Return the table-type-specific empty routes container, as augmented into the
261      * bgp-peer model under /peer/effect-rib-in/tables/routes choice node. This needs to include all
262      * the skeleton nodes under which the individual routes will be stored.
263      *
264      * @return Protocol-specific case in the routes choice, may not be null.
265      */
266     @Nonnull
267     @Deprecated
268     C emptyRoutesCase();
269
270     /**
271      * Return the table-type-specific empty routes container, as augmented into the
272      * bgp-peer model under /peer/effect-rib-in/tables/routes choice node/routes container. This needs to include all
273      * the skeleton nodes under which the individual routes will be stored.
274      *
275      * @return Protocol-specific container in the routes, may not be null.
276      */
277     @Nonnull
278     S emptyRoutesContainer();
279
280     /**
281      * Construct a Route List Key using new path Id for Families.
282      *
283      * @param pathId   The path identifier
284      * @param routeKey RouteKey
285      * @return route list Key (RouteKey + pathId)
286      */
287     @Nonnull
288     I createRouteListKey(@Nonnull PathId pathId, @Nonnull String routeKey);
289
290     /**
291      * Construct a Route List Key.
292      *
293      * @param routeKey RouteKey
294      * @return route list Key (RouteKey + empty pathId)
295      */
296     @Nonnull
297     default I createRouteListKey(@Nonnull final String routeKey) {
298         return createRouteListKey(NON_PATH_ID, routeKey);
299     }
300
301     /**
302      * Given a route list key, return the associated path ID.
303      *
304      * @param routeListKey Route list key
305      * @return Path ID
306      */
307     @Nonnull
308     PathId extractPathId(@Nonnull I routeListKey);
309
310     /**
311      * Given a route list key, return the associated path ID.
312      *
313      * @param routeListKey Route list key
314      * @return RouteKey
315      */
316     @Nonnull
317     String extractRouteKey(@Nonnull I routeListKey);
318
319     /**
320      * Extract a route list from the adj-rib-in instantiation of table routes.
321      *
322      * @param routes Table route choice
323      * @return A potentially empty list of routes
324      */
325     @Nonnull
326     List<R> extractAdjRibInRoutes(Routes routes);
327 }