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