BUG-2383: mark classes/methods as deprecated
[bgpcep.git] / bgp / rib-impl / src / main / java / org / opendaylight / protocol / bgp / rib / impl / RIBImpl.java
1 /*
2  * Copyright (c) 2013 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.impl;
9
10 import com.google.common.base.MoreObjects;
11 import com.google.common.base.MoreObjects.ToStringHelper;
12 import com.google.common.base.Optional;
13 import com.google.common.base.Preconditions;
14 import com.google.common.collect.ImmutableSet;
15 import com.google.common.util.concurrent.FutureCallback;
16 import com.google.common.util.concurrent.Futures;
17 import java.util.ArrayList;
18 import java.util.Collections;
19 import java.util.List;
20 import java.util.Set;
21 import java.util.concurrent.BlockingQueue;
22 import java.util.concurrent.ConcurrentHashMap;
23 import java.util.concurrent.ConcurrentMap;
24 import java.util.concurrent.ExecutionException;
25 import java.util.concurrent.LinkedBlockingQueue;
26 import javax.annotation.concurrent.ThreadSafe;
27 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
28 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
29 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
30 import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction;
31 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
32 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
33 import org.opendaylight.controller.md.sal.common.api.data.TransactionChain;
34 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
35 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
36 import org.opendaylight.controller.md.sal.dom.api.DOMDataBrokerExtension;
37 import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
38 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
39 import org.opendaylight.protocol.bgp.rib.DefaultRibReference;
40 import org.opendaylight.protocol.bgp.rib.impl.spi.AdjRIBsOut;
41 import org.opendaylight.protocol.bgp.rib.impl.spi.AdjRIBsOutRegistration;
42 import org.opendaylight.protocol.bgp.rib.impl.spi.BGPDispatcher;
43 import org.opendaylight.protocol.bgp.rib.impl.spi.RIB;
44 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
45 import org.opendaylight.protocol.bgp.rib.spi.AbstractAdjRIBs;
46 import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsIn;
47 import org.opendaylight.protocol.bgp.rib.spi.BGPObjectComparator;
48 import org.opendaylight.protocol.bgp.rib.spi.Peer;
49 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
50 import org.opendaylight.protocol.framework.ReconnectStrategyFactory;
51 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber;
52 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Address;
53 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.Ipv4Prefix;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv4RoutesCase;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.bgp.rib.rib.loc.rib.tables.routes.Ipv6RoutesCase;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.DestinationIpv4Builder;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.destination.ipv4.Ipv4Prefixes;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.ipv4.prefixes.destination.ipv4.Ipv4PrefixesBuilder;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.update.path.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationIpv4CaseBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.UpdateBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.Nlri;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.WithdrawnRoutes;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes2;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlri;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlriBuilder;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlri;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlriBuilder;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.mp.reach.nlri.AdvertizedRoutesBuilder;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.Route;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibBuilder;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRibBuilder;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.ClusterIdentifier;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
87 import org.opendaylight.yangtools.binding.data.codec.api.BindingCodecTreeFactory;
88 import org.opendaylight.yangtools.sal.binding.generator.impl.GeneratedClassLoadingStrategy;
89 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
90 import org.opendaylight.yangtools.yang.common.QName;
91 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
92 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
93 import org.opendaylight.yangtools.yang.model.api.SchemaContextListener;
94 import org.slf4j.Logger;
95 import org.slf4j.LoggerFactory;
96
97 @ThreadSafe
98 public final class RIBImpl extends DefaultRibReference implements AutoCloseable, RIB, TransactionChainListener, SchemaContextListener {
99     private static final Logger LOG = LoggerFactory.getLogger(RIBImpl.class);
100     private static final Update EOR = new UpdateBuilder().build();
101     private static final TablesKey IPV4_UNICAST_TABLE = new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class);
102     private static final QName RIB_ID_QNAME = QName.cachedReference(QName.create(Rib.QNAME, "id"));
103
104     /*
105      * FIXME: performance: this needs to be turned into a Peer->offset map.
106      *        The offset is used to locate a the per-peer state entry in the
107      *        RIB tables.
108      *
109      *        For the first release, that map is updated whenever configuration
110      *        changes and remains constant on peer flaps. On re-configuration
111      *        a resize task is scheduled, so large tables may take some time
112      *        before they continue reacting to updates.
113      *
114      *        For subsequent releases, if we make the reformat process concurrent,
115      *        we can trigger reformats when Graceful Restart Time expires for a
116      *        particular peer.
117      */
118     private final ConcurrentMap<Peer, AdjRIBsOut> ribOuts = new ConcurrentHashMap<>();
119     private final ReconnectStrategyFactory tcpStrategyFactory;
120     private final ReconnectStrategyFactory sessionStrategyFactory;
121
122     /**
123      * BGP Best Path selection comparator for ingress best path selection.
124      */
125     private final BGPObjectComparator comparator;
126     private final BGPDispatcher dispatcher;
127     private final BindingTransactionChain chain;
128     private final AsNumber localAs;
129     private final Ipv4Address bgpIdentifier;
130     private final ClusterIdentifier clusterId;
131     private final Set<BgpTableType> localTables;
132     private final RIBTables tables;
133     private final BlockingQueue<Peer> peers;
134     private final DataBroker dataBroker;
135     private final DOMDataBroker domDataBroker;
136     private final RIBExtensionConsumerContext extensions;
137     private final YangInstanceIdentifier yangRibId;
138     private final RIBSupportContextRegistryImpl ribContextRegistry;
139     private final Runnable scheduler = new Runnable() {
140         @Override
141         public void run() {
142             try {
143                 final Peer peer = RIBImpl.this.peers.take();
144                 LOG.debug("Advertizing loc-rib to new peer {}.", peer);
145                 for (final BgpTableType key : RIBImpl.this.localTables) {
146
147                     synchronized (RIBImpl.this) {
148                         final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(RIBImpl.this.ribOuts, RIBImpl.this.comparator, RIBImpl.this.chain.newWriteOnlyTransaction());
149                         final AbstractAdjRIBs<?, ?, ?> adj = (AbstractAdjRIBs<?, ?, ?>) RIBImpl.this.tables.get(new TablesKey(key.getAfi(), key.getSafi()));
150                         adj.addAllEntries(trans);
151                         Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
152                             @Override
153                             public void onSuccess(final Void result) {
154                                 LOG.trace("Advertizing {} to peer {} committed successfully", key.getAfi(), peer);
155                             }
156                             @Override
157                             public void onFailure(final Throwable t) {
158                                 LOG.error("Failed to update peer {} with RIB {}", peer, t);
159                             }
160                         });
161                     }
162                 }
163             } catch (final InterruptedException e) {
164                 LOG.info("Scheduler thread was interrupted.", e);
165             }
166         }
167     };
168
169     public RIBImpl(final RibId ribId, final AsNumber localAs, final Ipv4Address localBgpId, final Ipv4Address clusterId, final RIBExtensionConsumerContext extensions,
170         final BGPDispatcher dispatcher, final ReconnectStrategyFactory tcpStrategyFactory, final BindingCodecTreeFactory codecFactory,
171         final ReconnectStrategyFactory sessionStrategyFactory, final DataBroker dps, final DOMDataBroker domDataBroker, final List<BgpTableType> localTables, final GeneratedClassLoadingStrategy classStrategy) {
172         super(InstanceIdentifier.create(BgpRib.class).child(Rib.class, new RibKey(Preconditions.checkNotNull(ribId))));
173         this.chain = dps.createTransactionChain(this);
174         this.localAs = Preconditions.checkNotNull(localAs);
175         this.comparator = new BGPObjectComparator(localAs);
176         this.bgpIdentifier = Preconditions.checkNotNull(localBgpId);
177         this.clusterId = (clusterId == null) ? new ClusterIdentifier(localBgpId) : new ClusterIdentifier(clusterId);
178         this.dispatcher = Preconditions.checkNotNull(dispatcher);
179         this.sessionStrategyFactory = Preconditions.checkNotNull(sessionStrategyFactory);
180         this.tcpStrategyFactory = Preconditions.checkNotNull(tcpStrategyFactory);
181         this.localTables = ImmutableSet.copyOf(localTables);
182         this.tables = new RIBTables(extensions);
183         this.peers = new LinkedBlockingQueue<>();
184         this.dataBroker = dps;
185         this.domDataBroker = Preconditions.checkNotNull(domDataBroker);
186         this.extensions = Preconditions.checkNotNull(extensions);
187         this.ribContextRegistry = RIBSupportContextRegistryImpl.create(extensions, codecFactory, classStrategy);
188         this.yangRibId = YangInstanceIdentifier.builder().node(BgpRib.QNAME).node(Rib.QNAME).nodeWithKey(Rib.QNAME, RIB_ID_QNAME, ribId.getValue()).build();
189
190         LOG.debug("Instantiating RIB table {} at {}", ribId, getInstanceIdentifier());
191
192         final WriteTransaction trans = this.chain.newWriteOnlyTransaction();
193
194         final PolicyDatabase pd  = new PolicyDatabase(localAs.getValue(), localBgpId, this.clusterId);
195
196         final DOMDataBrokerExtension service = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
197         final DOMTransactionChain domChain = this.createPeerChain(this);
198         EffectiveRibInWriter.create((DOMDataTreeChangeService) service, domChain, getYangRibId(), pd, this.ribContextRegistry);
199         LOG.debug("Effective RIB created.");
200
201         // put empty BgpRib if not exists
202         trans.put(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier(),
203             new RibBuilder().setKey(new RibKey(ribId)).setPeer(Collections.<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer> emptyList()).setId(ribId).setLocRib(
204             new LocRibBuilder().setTables(Collections.<Tables> emptyList()).build()).build(), true);
205
206         for (final BgpTableType t : localTables) {
207             final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
208             if (this.tables.create(trans, this, key) == null) {
209                 LOG.debug("Did not create local table for unhandled table type {}", t);
210             }
211
212             // reusing the for cycle
213             // create locRibWriter for each table
214             // FIXME: temporary create writer only for Ipv4
215             if (key.getAfi().equals(Ipv4AddressFamily.class)) {
216                 LocRibWriter.create(this.ribContextRegistry.getRIBSupportContext(key).getRibSupport(), domChain, getYangRibId(), localAs, (DOMDataTreeChangeService) service, pd);
217             }
218         }
219
220         Futures.addCallback(trans.submit(), new FutureCallback<Void>() {
221             @Override
222             public void onSuccess(final Void result) {
223                 LOG.trace("Change committed successfully");
224             }
225
226             @Override
227             public void onFailure(final Throwable t) {
228                 LOG.error("Failed to initiate RIB {}", getInstanceIdentifier(), t);
229             }
230
231         });
232     }
233
234     @Deprecated
235     synchronized void initTables(final byte[] remoteBgpId) {
236     }
237
238     @Override
239     @Deprecated
240     public synchronized void updateTables(final Peer peer, final Update message) {
241         final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
242
243         if (!EOR.equals(message)) {
244             final WithdrawnRoutes wr = message.getWithdrawnRoutes();
245             if (wr != null) {
246                 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
247                 if (ari != null) {
248                     /*
249                      * create MPUnreach for the routes to be handled in the same way as linkstate routes
250                      */
251                     final List<Ipv4Prefixes> prefixes = new ArrayList<>();
252                     for (final Ipv4Prefix p : wr.getWithdrawnRoutes()) {
253                         prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
254                     }
255                     ari.removeRoutes(
256                         trans,
257                         peer,
258                         new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
259                             new WithdrawnRoutesBuilder().setDestinationType(
260                                 new org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev150305.update.path.attributes.mp.unreach.nlri.withdrawn.routes.destination.type.DestinationIpv4CaseBuilder().setDestinationIpv4(
261                                     new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build()).build());
262                 } else {
263                     LOG.debug("Not removing objects from unhandled IPv4 Unicast");
264                 }
265             }
266
267             final PathAttributes attrs = message.getPathAttributes();
268             if (attrs != null) {
269                 final PathAttributes2 mpu = attrs.getAugmentation(PathAttributes2.class);
270                 if (mpu != null) {
271                     final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
272                     final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
273                     // EOR messages do not contain withdrawn routes
274                     if (nlri.getWithdrawnRoutes() != null) {
275                         if (ari != null) {
276                             ari.removeRoutes(trans, peer, nlri);
277                         } else {
278                             LOG.debug("Not removing objects from unhandled NLRI {}", nlri);
279                         }
280                     } else {
281                         ari.markUptodate(trans, peer);
282                     }
283                 }
284             }
285
286             final Nlri ar = message.getNlri();
287             if (ar != null) {
288                 final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
289                 if (ari != null) {
290                     /*
291                      * create MPReach for the routes to be handled in the same way as linkstate routes
292                      */
293                     final List<Ipv4Prefixes> prefixes = new ArrayList<>();
294                     for (final Ipv4Prefix p : ar.getNlri()) {
295                         prefixes.add(new Ipv4PrefixesBuilder().setPrefix(p).build());
296                     }
297                     final MpReachNlriBuilder b = new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(
298                         UnicastSubsequentAddressFamily.class).setAdvertizedRoutes(
299                             new AdvertizedRoutesBuilder().setDestinationType(
300                                 new DestinationIpv4CaseBuilder().setDestinationIpv4(
301                                     new DestinationIpv4Builder().setIpv4Prefixes(prefixes).build()).build()).build());
302                     if (attrs != null) {
303                         b.setCNextHop(attrs.getCNextHop());
304                     }
305
306                     ari.addRoutes(trans, peer, b.build(), attrs);
307                 } else {
308                     LOG.debug("Not adding objects from unhandled IPv4 Unicast");
309                 }
310             }
311
312             if (attrs != null) {
313                 final PathAttributes1 mpr = attrs.getAugmentation(PathAttributes1.class);
314                 if (mpr != null) {
315                     final MpReachNlri nlri = mpr.getMpReachNlri();
316
317                     final AdjRIBsIn<?, ?> ari = this.tables.get(new TablesKey(nlri.getAfi(), nlri.getSafi()));
318                     if (ari != null) {
319                         if (message.equals(ari.endOfRib())) {
320                             ari.markUptodate(trans, peer);
321                         } else {
322                             ari.addRoutes(trans, peer, nlri, attrs);
323                         }
324                     } else {
325                         LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
326                     }
327                 }
328             }
329         } else {
330             final AdjRIBsIn<?, ?> ari = this.tables.get(IPV4_UNICAST_TABLE);
331             if (ari != null) {
332                 ari.markUptodate(trans, peer);
333             } else {
334                 LOG.debug("End-of-RIB for IPv4 Unicast ignored");
335             }
336         }
337
338         Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
339             @Override
340             public void onSuccess(final Void result) {
341                 LOG.debug("RIB modification successfully committed.");
342             }
343
344             @Override
345             public void onFailure(final Throwable t) {
346                 LOG.error("Failed to commit RIB modification", t);
347             }
348         });
349     }
350
351     @Deprecated
352     @Override
353     public synchronized void clearTable(final Peer peer, final TablesKey key) {
354         final AdjRIBsIn<?, ?> ari = this.tables.get(key);
355         if (ari != null) {
356             final AdjRIBsTransactionImpl trans = new AdjRIBsTransactionImpl(this.ribOuts, this.comparator, this.chain.newWriteOnlyTransaction());
357             ari.clear(trans, peer);
358
359             Futures.addCallback(trans.commit(), new FutureCallback<Void>() {
360                 @Override
361                 public void onSuccess(final Void result) {
362                     LOG.trace("Table {} cleared successfully", key);
363                 }
364
365                 @Override
366                 public void onFailure(final Throwable t) {
367                     LOG.error("Failed to clear table {}", key, t);
368                 }
369             });
370         }
371     }
372
373     @Override
374     public String toString() {
375         return addToStringAttributes(MoreObjects.toStringHelper(this)).toString();
376     }
377
378     protected ToStringHelper addToStringAttributes(final ToStringHelper toStringHelper) {
379         return toStringHelper;
380     }
381
382     @SuppressWarnings("unchecked")
383     @Deprecated
384     protected <K, V extends Route> AdjRIBsIn<K, V> getTable(final TablesKey key) {
385         return (AdjRIBsIn<K, V>) this.tables.get(key);
386     }
387
388     @Override
389     public synchronized void close() throws InterruptedException, ExecutionException {
390         final WriteTransaction t = this.chain.newWriteOnlyTransaction();
391         t.delete(LogicalDatastoreType.OPERATIONAL, getInstanceIdentifier());
392         t.submit().get();
393         this.chain.close();
394     }
395
396     @Override
397     public AsNumber getLocalAs() {
398         return this.localAs;
399     }
400
401     @Override
402     public Ipv4Address getBgpIdentifier() {
403         return this.bgpIdentifier;
404     }
405
406     @Override
407     public Set<? extends BgpTableType> getLocalTables() {
408         return this.localTables;
409     }
410
411     @Override
412     public ReconnectStrategyFactory getTcpStrategyFactory() {
413         return this.tcpStrategyFactory;
414     }
415
416     @Override
417     public ReconnectStrategyFactory getSessionStrategyFactory() {
418         return this.sessionStrategyFactory;
419     }
420
421     @Override
422     public BGPDispatcher getDispatcher() {
423         return this.dispatcher;
424     }
425
426     @Deprecated
427     @Override
428     public void initTable(final Peer bgpPeer, final TablesKey key) {
429         // FIXME: BUG-196: support graceful restart
430     }
431
432     @Override
433     public AdjRIBsOutRegistration registerRIBsOut(final Peer peer, final AdjRIBsOut aro) {
434         final AdjRIBsOutRegistration reg = new AdjRIBsOutRegistration(aro) {
435             @Override
436             protected void removeRegistration() {
437                 RIBImpl.this.ribOuts.remove(peer, aro);
438             }
439         };
440
441         this.ribOuts.put(peer, aro);
442         LOG.debug("Registering this peer {} to RIB-Out {}", peer, this.ribOuts);
443         try {
444             this.peers.put(peer);
445             new Thread(this.scheduler).start();
446         } catch (final InterruptedException e) {
447             //
448         }
449         return reg;
450     }
451
452     @Override
453     public void onTransactionChainFailed(final TransactionChain<?, ?> chain, final AsyncTransaction<?, ?> transaction, final Throwable cause) {
454         LOG.error("Broken chain in RIB {} transaction {}", getInstanceIdentifier(), transaction.getIdentifier(), cause);
455     }
456
457     @Override
458     public void onTransactionChainSuccessful(final TransactionChain<?, ?> chain) {
459         LOG.info("RIB {} closed successfully", getInstanceIdentifier());
460     }
461
462     @Override
463     public long getRoutesCount(final TablesKey key) {
464         try {
465             final Optional<Tables> tableMaybe = this.dataBroker.newReadOnlyTransaction().read(LogicalDatastoreType.OPERATIONAL,
466                     getInstanceIdentifier().child(LocRib.class).child(Tables.class, key)).checkedGet();
467             if (tableMaybe.isPresent()) {
468                 final Tables table = tableMaybe.get();
469                 if (table.getRoutes() instanceof Ipv4RoutesCase) {
470                     final Ipv4RoutesCase routesCase = (Ipv4RoutesCase) table.getRoutes();
471                     if (routesCase.getIpv4Routes() != null && routesCase.getIpv4Routes().getIpv4Route() != null) {
472                         return routesCase.getIpv4Routes().getIpv4Route().size();
473                     }
474                 } else if (table.getRoutes() instanceof Ipv6RoutesCase) {
475                     final Ipv6RoutesCase routesCase = (Ipv6RoutesCase) table.getRoutes();
476                     if (routesCase.getIpv6Routes() != null && routesCase.getIpv6Routes().getIpv6Route() != null) {
477                         return routesCase.getIpv6Routes().getIpv6Route().size();
478                     }
479                 }
480             }
481         } catch (final ReadFailedException e) {
482             //no-op
483         }
484         return 0;
485     }
486
487     @Override
488     public YangInstanceIdentifier getYangRibId() {
489         return this.yangRibId;
490     }
491
492     @Override
493     public DOMTransactionChain createPeerChain(final TransactionChainListener listener) {
494         return this.domDataBroker.createTransactionChain(listener);
495     }
496
497     @Override
498     public RIBExtensionConsumerContext getRibExtensions() {
499         return this.extensions;
500     }
501
502     @Override
503     public RIBSupportContextRegistry getRibSupportContext() {
504         return this.ribContextRegistry;
505     }
506
507     @Override
508     public void onGlobalContextUpdated(final SchemaContext context) {
509         this.ribContextRegistry.onSchemaContextUpdated(context);
510     }
511 }