Bug 4488: Metadata not available for modification NodeModification 32/36132/5
authorMilos Fabian <milfabia@cisco.com>
Fri, 11 Mar 2016 12:03:09 +0000 (13:03 +0100)
committerGerrit Code Review <gerrit@opendaylight.org>
Thu, 24 Mar 2016 09:33:00 +0000 (09:33 +0000)
To resovle tis race condition problem, modify EffectiveRibInWriter to
work on per peer basis instead of a global per RIB instance.
The EffectiveRibInWriter is now listening on paricular peer's AdjRibIn tables.
The writer is started when a session goes up and closed when the session goes down.
Peer role is not tracked via data changes rather directly set at creation.

The possitive side effect is better error recovery in a case of failure in
EffectiveRibInWriter.
Disadvantage of this change is tighter coupling between components
(peer, eff-rib-in writer and policy tracker).

Change-Id: I650bae8638a2a4818bdd925a5f4ca2274b79d5c6
Signed-off-by: Milos Fabian <milfabia@cisco.com>
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/EffectiveRibInWriter.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBImpl.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java

index ea3ec9564a2a96da6e6541d11ca14e486ca46cb1..2472b5cdf941d1205aab086b40e123589ef006e7 100644 (file)
@@ -59,6 +59,7 @@ public class ApplicationPeer implements AutoCloseable, org.opendaylight.protocol
     private final DOMTransactionChain chain;
     private final DOMTransactionChain writerChain;
     private final BGPConfigModuleTracker moduleTracker;
+    private final EffectiveRibInWriter effectiveRibInWriter;
 
     private AdjRibInWriter writer;
 
@@ -67,8 +68,11 @@ public class ApplicationPeer implements AutoCloseable, org.opendaylight.protocol
         this.targetRib = Preconditions.checkNotNull(targetRib);
         this.rawIdentifier = InetAddresses.forString(ipAddress.getValue()).getAddress();
         final NodeIdentifierWithPredicates peerId = IdentifierUtils.domPeerId(RouterIds.createPeerId(ipAddress));
-        this.adjRibsInId = this.targetRib.getYangRibId().node(Peer.QNAME).node(peerId).node(AdjRibIn.QNAME).node(Tables.QNAME);
+        final YangInstanceIdentifier peerIId = this.targetRib.getYangRibId().node(Peer.QNAME).node(peerId);
+        this.adjRibsInId = peerIId.node(AdjRibIn.QNAME).node(Tables.QNAME);
         this.chain = this.targetRib.createPeerChain(this);
+        this.effectiveRibInWriter = EffectiveRibInWriter.create(this.targetRib.getService(), this.targetRib.createPeerChain(this), peerIId, this.targetRib.getImportPolicyPeerTracker(),
+                this.targetRib.getRibSupportContext(), PeerRole.Internal);
         this.writerChain = this.targetRib.createPeerChain(this);
         this.writer = AdjRibInWriter.create(this.targetRib.getYangRibId(), PeerRole.Internal, this.writerChain);
         this.writer = this.writer.transform(RouterIds.createPeerId(ipAddress), this.targetRib.getRibSupportContext(), this.targetRib.getLocalTablesKeys(), true);
@@ -177,6 +181,7 @@ public class ApplicationPeer implements AutoCloseable, org.opendaylight.protocol
 
     @Override
     public void close() {
+        this.effectiveRibInWriter.close();
         this.writer.removePeer();
         this.chain.close();
         this.writerChain.close();
index 46cc38a2459e2d6d6915b78e68a5ec09a5540aa6..f9c1956e1a158f8d43b1f0e5f08029bb6ae35ce6 100644 (file)
@@ -58,6 +58,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily;
 import org.opendaylight.yangtools.yang.binding.Notification;
+import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -79,6 +80,8 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer
     private DOMTransactionChain chain;
     @GuardedBy("this")
     private AdjRibInWriter ribWriter;
+    @GuardedBy("this")
+    private EffectiveRibInWriter effRibInWriter;
 
     private final RIB rib;
     private final String name;
@@ -86,6 +89,7 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer
     private BGPPeerRuntimeRegistration runtimeReg;
     private long sessionEstablishedCounter = 0L;
     private final Set<AdjRibOutListener> adjRibOutListenerSet = new HashSet<>();
+    private final PeerRole peerRole;
 
     public BGPPeer(final String name, final RIB rib) {
         this(name, rib, PeerRole.Ibgp);
@@ -95,6 +99,7 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer
         this.rib = Preconditions.checkNotNull(rib);
         this.name = name;
         this.chain = rib.createPeerChain(this);
+        this.peerRole = role;
         this.ribWriter = AdjRibInWriter.create(rib.getYangRibId(), role, this.chain);
     }
 
@@ -197,8 +202,10 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer
         this.session = session;
         this.rawIdentifier = InetAddresses.forString(session.getBgpId().getValue()).getAddress();
         final PeerId peerId = RouterIds.createPeerId(session.getBgpId());
+        final YangInstanceIdentifier peerIId = this.rib.getYangRibId().node(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer.QNAME).node(IdentifierUtils.domPeerId(peerId));
         createAdjRibOutListener(peerId);
-
+        this.effRibInWriter = EffectiveRibInWriter.create(this.rib.getService(), this.rib.createPeerChain(this), peerIId, ((RIBImpl)this.rib).getImportPolicyPeerTracker(),
+                this.rib.getRibSupportContext(), this.peerRole);
         this.ribWriter = this.ribWriter.transform(peerId, this.rib.getRibSupportContext(), this.tables, false);
         this.sessionEstablishedCounter++;
         if (this.registrator != null) {
@@ -231,7 +238,7 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer
         // not particularly nice
         if (context != null && this.session instanceof BGPSessionImpl) {
             this.adjRibOutListenerSet.add(AdjRibOutListener.create(peerId, key, this.rib.getYangRibId(), this.rib.getCodecsRegistry(),
-                context.getRibSupport(), ((RIBImpl) this.rib).getService(), ((BGPSessionImpl) this.session).getLimiter(), mpSupport));
+                context.getRibSupport(), this.rib.getService(), ((BGPSessionImpl) this.session).getLimiter(), mpSupport));
         }
     }
 
@@ -241,6 +248,9 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer
             adjRibOutListener.close();
         }
         this.adjRibOutListenerSet.clear();
+        if (this.effRibInWriter != null) {
+            this.effRibInWriter.close();
+        }
         this.ribWriter.removePeer();
         this.tables.clear();
     }
index c4188cf1686d85e26e5044e4231679cc10884dfb..31c5cfaed9e8b0ff6aec04c141296d770b0f8409 100644 (file)
@@ -22,7 +22,7 @@ import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContext;
 import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContextRegistry;
 import org.opendaylight.protocol.bgp.rib.spi.RIBSupport;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.AdjRibIn;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.peer.EffectiveRibIn;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
@@ -42,7 +42,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 /**
- * Implementation of the BGP import policy. Listens on all Adj-RIB-In, inspects all inbound
+ * Implementation of the BGP import policy. Listens on peer's Adj-RIB-In, inspects all inbound
  * routes in the context of the advertising peer's role and applies the inbound policy.
  *
  * Inbound policy is applied as follows:
@@ -52,30 +52,27 @@ import org.slf4j.LoggerFactory;
  *    advertising peer's role
  * 3) output admitting routes with edited attributes into /bgp-rib/rib/peer/effective-rib-in/tables/routes
  *
- * Note that we maintain the peer roles using a DCL, even if we could look up our internal
- * structures. This is done so we maintain causality and loose coupling.
  */
 @NotThreadSafe
 final class EffectiveRibInWriter implements AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(EffectiveRibInWriter.class);
     protected static final NodeIdentifier TABLE_ROUTES = new NodeIdentifier(Routes.QNAME);
-    private static final NodeIdentifier ADJRIBIN_NID = new NodeIdentifier(AdjRibIn.QNAME);
-    private static final NodeIdentifier TABLES_NID = new NodeIdentifier(Tables.QNAME);
 
     private final class AdjInTracker implements AutoCloseable, DOMDataTreeChangeListener {
         private final RIBSupportContextRegistry registry;
-        private final YangInstanceIdentifier ribId;
+        private final YangInstanceIdentifier peerIId;
+        private final YangInstanceIdentifier effRibTables;
         private final ListenerRegistration<?> reg;
         private final DOMTransactionChain chain;
 
-        AdjInTracker(final DOMDataTreeChangeService service, final RIBSupportContextRegistry registry, final DOMTransactionChain chain, final YangInstanceIdentifier ribId) {
+        AdjInTracker(final DOMDataTreeChangeService service, final RIBSupportContextRegistry registry, final DOMTransactionChain chain, final YangInstanceIdentifier peerIId) {
             this.registry = Preconditions.checkNotNull(registry);
             this.chain = Preconditions.checkNotNull(chain);
-            this.ribId = Preconditions.checkNotNull(ribId);
+            this.peerIId = Preconditions.checkNotNull(peerIId);
+            this.effRibTables = this.peerIId.node(EffectiveRibIn.QNAME).node(Tables.QNAME);
 
-            final YangInstanceIdentifier tableId = ribId.node(Peer.QNAME).node(Peer.QNAME);
-            final DOMDataTreeIdentifier treeId = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, tableId);
-            LOG.debug("Registered Effective RIB on {}", tableId);
+            final DOMDataTreeIdentifier treeId = new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, this.peerIId.node(AdjRibIn.QNAME).node(Tables.QNAME));
+            LOG.debug("Registered Effective RIB on {}", this.peerIId);
             this.reg = service.registerDataTreeChangeListener(treeId, this);
         }
 
@@ -119,8 +116,7 @@ final class EffectiveRibInWriter implements AutoCloseable {
             }
         }
 
-        private void processTableChildren(final DOMDataWriteTransaction tx, final RIBSupport ribSupport, final NodeIdentifierWithPredicates peerKey, final YangInstanceIdentifier tablePath, final Collection<DataTreeCandidateNode> children) {
-            final AbstractImportPolicy policy = EffectiveRibInWriter.this.peerPolicyTracker.policyFor(IdentifierUtils.peerId(peerKey));
+        private void processTableChildren(final DOMDataWriteTransaction tx, final RIBSupport ribSupport, final YangInstanceIdentifier tablePath, final Collection<DataTreeCandidateNode> children) {
 
             for (final DataTreeCandidateNode child : children) {
                 final PathArgument childIdentifier = child.getIdentifier();
@@ -137,11 +133,11 @@ final class EffectiveRibInWriter implements AutoCloseable {
                     // No-op
                     break;
                 case SUBTREE_MODIFIED:
-                    processModifiedRouteTables(child, childIdentifier,tx, ribSupport, policy, childPath, childDataAfter);
+                    processModifiedRouteTables(child, childIdentifier,tx, ribSupport, importPolicy, childPath, childDataAfter);
                     break;
                 case APPEARED:
                 case WRITE:
-                    writeRouteTables(child, childIdentifier,tx, ribSupport, policy, childPath, childDataAfter);
+                    writeRouteTables(child, childIdentifier,tx, ribSupport, importPolicy, childPath, childDataAfter);
 
                     break;
                 default:
@@ -180,26 +176,26 @@ final class EffectiveRibInWriter implements AutoCloseable {
             return this.registry.getRIBSupportContext(tableKey);
         }
 
-        private YangInstanceIdentifier effectiveTablePath(final NodeIdentifierWithPredicates peerKey, final NodeIdentifierWithPredicates tableKey) {
-            return this.ribId.node(Peer.QNAME).node(peerKey).node(EffectiveRibIn.QNAME).node(Tables.QNAME).node(tableKey);
+        private YangInstanceIdentifier effectiveTablePath(final NodeIdentifierWithPredicates tableKey) {
+            return this.effRibTables.node(tableKey);
         }
 
-        private void modifyTable(final DOMDataWriteTransaction tx, final NodeIdentifierWithPredicates peerKey, final NodeIdentifierWithPredicates tableKey, final DataTreeCandidateNode table) {
+        private void modifyTable(final DOMDataWriteTransaction tx, final NodeIdentifierWithPredicates tableKey, final DataTreeCandidateNode table) {
             final RIBSupportContext ribSupport = getRibSupport(tableKey);
-            final YangInstanceIdentifier tablePath = effectiveTablePath(peerKey, tableKey);
+            final YangInstanceIdentifier tablePath = effectiveTablePath(tableKey);
 
-            processTableChildren(tx, ribSupport.getRibSupport(), peerKey, tablePath, table.getChildNodes());
+            processTableChildren(tx, ribSupport.getRibSupport(), tablePath, table.getChildNodes());
         }
 
-        private void writeTable(final DOMDataWriteTransaction tx, final NodeIdentifierWithPredicates peerKey, final NodeIdentifierWithPredicates tableKey, final DataTreeCandidateNode table) {
+        private void writeTable(final DOMDataWriteTransaction tx, final NodeIdentifierWithPredicates tableKey, final DataTreeCandidateNode table) {
             final RIBSupportContext ribSupport = getRibSupport(tableKey);
-            final YangInstanceIdentifier tablePath = effectiveTablePath(peerKey, tableKey);
+            final YangInstanceIdentifier tablePath = effectiveTablePath(tableKey);
 
             // Create an empty table
             LOG.trace("Create Empty table", tablePath);
             ribSupport.clearTable(tx, tablePath);
 
-            processTableChildren(tx, ribSupport.getRibSupport(), peerKey, tablePath, table.getChildNodes());
+            processTableChildren(tx, ribSupport.getRibSupport(), tablePath, table.getChildNodes());
         }
 
         @Override
@@ -212,32 +208,12 @@ final class EffectiveRibInWriter implements AutoCloseable {
             for (final DataTreeCandidate tc : changes) {
                 final YangInstanceIdentifier rootPath = tc.getRootPath();
 
-                // Obtain the peer's key
-                final NodeIdentifierWithPredicates peerKey = IdentifierUtils.peerKey(rootPath);
                 final DataTreeCandidateNode root = tc.getRootNode();
-
-                //Perform first PeerRoleChange, since it will remove peer from policy if peer session is close
-                peerRoleChange(root, rootPath);
-
-                if (tc.getRootNode().getModificationType().equals(ModificationType.DELETE)) {
-                    continue;
-                }
-                    // filter out any change outside AdjRibsIn
-                final DataTreeCandidateNode ribIn =  root.getModifiedChild(ADJRIBIN_NID);
-                if (ribIn == null) {
-                    LOG.debug("Skipping change {}", root.getIdentifier());
-                    continue;
-                }
-                final DataTreeCandidateNode tables = ribIn.getModifiedChild(TABLES_NID);
-                if (tables == null) {
-                    LOG.debug("Skipping change {}", root.getIdentifier());
-                    continue;
-                }
-                for (final DataTreeCandidateNode table : tables.getChildNodes()) {
+                for (final DataTreeCandidateNode table : root.getChildNodes()) {
                     if (tx == null) {
                         tx = this.chain.newWriteOnlyTransaction();
                     }
-                    changeDataTree(tx, rootPath, root, peerKey, table);
+                    changeDataTree(tx, rootPath, root, table);
                 }
             }
             if (tx != null) {
@@ -246,7 +222,7 @@ final class EffectiveRibInWriter implements AutoCloseable {
         }
 
         private void changeDataTree(final DOMDataWriteTransaction tx, final YangInstanceIdentifier rootPath,
-            final DataTreeCandidateNode root, final NodeIdentifierWithPredicates peerKey, final DataTreeCandidateNode table) {
+            final DataTreeCandidateNode root, final DataTreeCandidateNode table) {
             final PathArgument lastArg = table.getIdentifier();
             Verify.verify(lastArg instanceof NodeIdentifierWithPredicates, "Unexpected type %s in path %s", lastArg.getClass(), rootPath);
             final NodeIdentifierWithPredicates tableKey = (NodeIdentifierWithPredicates) lastArg;
@@ -254,20 +230,20 @@ final class EffectiveRibInWriter implements AutoCloseable {
             switch (modificationType) {
             case DELETE:
             case DISAPPEARED:
-                final YangInstanceIdentifier effectiveTablePath = effectiveTablePath(peerKey, tableKey);
+                final YangInstanceIdentifier effectiveTablePath = effectiveTablePath(tableKey);
                 LOG.debug("Delete Effective Table {} modification type {}, ", effectiveTablePath, modificationType);
                 // delete the corresponding effective table
                 tx.delete(LogicalDatastoreType.OPERATIONAL, effectiveTablePath);
                 break;
             case SUBTREE_MODIFIED:
-                modifyTable(tx, peerKey, tableKey, table);
+                modifyTable(tx, tableKey, table);
                 break;
             case UNMODIFIED:
                 LOG.info("Ignoring spurious notification on {} data {}", rootPath, table);
                 break;
             case APPEARED:
             case WRITE:
-                writeTable(tx, peerKey, tableKey, table);
+                writeTable(tx, tableKey, table);
                 break;
             default:
                 LOG.warn("Ignoring unhandled root {}", root);
@@ -277,30 +253,23 @@ final class EffectiveRibInWriter implements AutoCloseable {
 
         @Override
         public void close() {
-            // FIXME: wipe all effective routes?
             this.reg.close();
         }
     }
 
-    private void peerRoleChange(final DataTreeCandidateNode root, final YangInstanceIdentifier rootPath) {
-        final DataTreeCandidateNode roleChange =  root.getModifiedChild(AbstractPeerRoleTracker.PEER_ROLE_NID);
-        if (roleChange != null) {
-            EffectiveRibInWriter.this.peerPolicyTracker.onDataTreeChanged(roleChange, IdentifierUtils.peerPath(rootPath));
-        }
-    }
-
-    private final ImportPolicyPeerTracker peerPolicyTracker;
     private final AdjInTracker adjInTracker;
+    private final AbstractImportPolicy importPolicy;
 
     static EffectiveRibInWriter create(@Nonnull final DOMDataTreeChangeService service, @Nonnull final DOMTransactionChain chain,
-        @Nonnull final YangInstanceIdentifier ribId, @Nonnull final PolicyDatabase pd, @Nonnull final RIBSupportContextRegistry registry) {
-        return new EffectiveRibInWriter(service, chain, ribId, pd, registry);
+        @Nonnull final YangInstanceIdentifier peerIId, @Nonnull final ImportPolicyPeerTracker importPolicyPeerTracker, @Nonnull final RIBSupportContextRegistry registry, final PeerRole peerRole) {
+        return new EffectiveRibInWriter(service, chain, peerIId, importPolicyPeerTracker, registry, peerRole);
     }
 
-    private EffectiveRibInWriter(final DOMDataTreeChangeService service, final DOMTransactionChain chain, final YangInstanceIdentifier ribId,
-        final PolicyDatabase pd, final RIBSupportContextRegistry registry) {
-        this.peerPolicyTracker = new ImportPolicyPeerTracker(pd);
-        this.adjInTracker = new AdjInTracker(service, registry, chain, ribId);
+    private EffectiveRibInWriter(final DOMDataTreeChangeService service, final DOMTransactionChain chain, final YangInstanceIdentifier peerIId,
+        final ImportPolicyPeerTracker importPolicyPeerTracker, final RIBSupportContextRegistry registry, final PeerRole peerRole) {
+        importPolicyPeerTracker.peerRoleChanged(peerIId, peerRole);
+        this.importPolicy = importPolicyPeerTracker.policyFor(IdentifierUtils.peerId((NodeIdentifierWithPredicates) peerIId.getLastPathArgument()));
+        this.adjInTracker = new AdjInTracker(service, registry, chain, peerIId);
     }
 
     @Override
index 727b0ad4fed60dc1faf72914a4d0a8fff57bd60c..7bf8549119a9f80f6f4f1b1998528c07ea650083 100644 (file)
@@ -101,12 +101,12 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
     private final YangInstanceIdentifier yangRibId;
     private final RIBSupportContextRegistryImpl ribContextRegistry;
     private final CodecsRegistryImpl codecsRegistry;
-    private final EffectiveRibInWriter efWriter;
     private final DOMDataBrokerExtension service;
     private final List<LocRibWriter> locRibs = new ArrayList<>();
     private final BGPConfigModuleTracker configModuleTracker;
     private final BGPOpenConfigProvider openConfigProvider;
     private final CacheDisconnectedPeers cacheDisconnectedPeers;
+    private final ImportPolicyPeerTracker importPolicyPeerTracker;
 
     public RIBImpl(final RibId ribId, final AsNumber localAs, final Ipv4Address localBgpId, final Ipv4Address clusterId, final RIBExtensionConsumerContext extensions,
         final BGPDispatcher dispatcher, final ReconnectStrategyFactory tcpStrategyFactory, final BindingCodecTreeFactory codecFactory,
@@ -159,17 +159,17 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
             LOG.error("Failed to initiate RIB {}", this.yangRibId, e);
         }
         final ClusterIdentifier cId = (clusterId == null) ? new ClusterIdentifier(localBgpId) : new ClusterIdentifier(clusterId);
-        final PolicyDatabase pd  = new PolicyDatabase(localAs.getValue(), localBgpId, cId);
+        final PolicyDatabase policyDatabase  = new PolicyDatabase(localAs.getValue(), localBgpId, cId);
+        this.importPolicyPeerTracker = new ImportPolicyPeerTracker(policyDatabase);
 
         final DOMDataBrokerExtension domDatatreeChangeService = this.domDataBroker.getSupportedExtensions().get(DOMDataTreeChangeService.class);
         this.service = domDatatreeChangeService;
-        this.efWriter = EffectiveRibInWriter.create(getService(), createPeerChain(this), getYangRibId(), pd, this.ribContextRegistry);
         LOG.debug("Effective RIB created.");
 
         for (final BgpTableType t : this.localTables) {
             final TablesKey key = new TablesKey(t.getAfi(), t.getSafi());
             this.localTablesKeys.add(key);
-            startLocRib(key, pd);
+            startLocRib(key, policyDatabase);
         }
 
         if (this.configModuleTracker != null) {
@@ -229,7 +229,6 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
         t.delete(LogicalDatastoreType.OPERATIONAL, getYangRibId());
         t.submit().get();
         this.domChain.close();
-        this.efWriter.close();
         for (final LocRibWriter locRib : this.locRibs) {
             try {
                 locRib.close();
@@ -316,6 +315,7 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
         return this.localTablesKeys;
     }
 
+    @Override
     public DOMDataTreeChangeService getService() {
         return (DOMDataTreeChangeService) this.service;
     }
@@ -359,4 +359,8 @@ public final class RIBImpl extends DefaultRibReference implements AutoCloseable,
     public CacheDisconnectedPeers getCacheDisconnectedPeers() {
         return this.cacheDisconnectedPeers;
     }
+
+    public ImportPolicyPeerTracker getImportPolicyPeerTracker() {
+        return this.importPolicyPeerTracker;
+    }
 }
index b411204c74e5d01afe2748364cf1eb49ea02ac06..8db65388a39e057e51d6319f9aaa228352903769 100644 (file)
@@ -11,6 +11,7 @@ import com.google.common.base.Optional;
 import java.util.Set;
 import javax.annotation.Nonnull;
 import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener;
+import org.opendaylight.controller.md.sal.dom.api.DOMDataTreeChangeService;
 import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain;
 import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigProvider;
 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
@@ -93,4 +94,11 @@ public interface RIB {
      * @return
      */
     CacheDisconnectedPeers getCacheDisconnectedPeers();
+
+    /**
+     * Return instance of DOMDataTreeChangeService, where consumer can register to
+     * listen on DOM data changes.
+     * @return DOMDataTreeChangeService
+     */
+    DOMDataTreeChangeService getService();
 }