Handle end-of-RIB messages 73/3173/1
authorRobert Varga <rovarga@cisco.com>
Thu, 28 Nov 2013 06:32:57 +0000 (07:32 +0100)
committerRobert Varga <rovarga@cisco.com>
Thu, 28 Nov 2013 07:36:10 +0000 (08:36 +0100)
Change-Id: I65af34c42d1b9e2f51d256a518a73a6f5f99dca4
Signed-off-by: Robert Varga <rovarga@cisco.com>
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/LinkstateAdjRIBsIn.java
bgp/linkstate/src/main/java/org/opendaylight/protocol/bgp/linkstate/RIBActivator.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/Ipv4AdjRIBsIn.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/Ipv6AdjRIBsIn.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/RIBActivator.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/RIBTables.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AbstractAdjRIBsIn.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AdjRIBsIn.java
bgp/rib-spi/src/main/java/org/opendaylight/protocol/bgp/rib/spi/AdjRIBsInFactory.java
integration-tests/src/test/java/org/opendaylight/protocol/integration/bgp/ParserToSalTest.java

index 7862acf55f26cdbf2f5bf9805ccec62756cc875b..6b0f053d5d7cdcf2c3dd42bf41139a8179124c43 100644 (file)
@@ -50,7 +50,7 @@ import com.google.common.base.Preconditions;
 
 final class LinkstateAdjRIBsIn extends AbstractAdjRIBsIn<CLinkstateDestination, LinkstateRoute> {
        private static abstract class LinkstateRIBEntryData<LSATTR extends LinkStateAttribute> extends
-                       RIBEntryData<CLinkstateDestination, LinkstateRoute> {
+       RIBEntryData<CLinkstateDestination, LinkstateRoute> {
                private final LSATTR lsattr;
 
                protected LinkstateRIBEntryData(final PathAttributes attributes, final LSATTR lsattr) {
@@ -77,8 +77,8 @@ final class LinkstateAdjRIBsIn extends AbstractAdjRIBsIn<CLinkstateDestination,
                }
        }
 
-       LinkstateAdjRIBsIn(final Comparator<PathAttributes> comparator, final TablesKey key) {
-               super(comparator, key);
+       LinkstateAdjRIBsIn(final DataModificationTransaction trans, final Comparator<PathAttributes> comparator, final TablesKey key) {
+               super(trans, comparator, key);
        }
 
        @Override
index 7e034590660efcc9834539fb30397deef4339e9d..360afc9e437946ad322263ab1d692a1b5f9064c1 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.protocol.bgp.linkstate;
 
 import java.util.Comparator;
 
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsIn;
 import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsInFactory;
 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderActivator;
@@ -32,8 +33,8 @@ public final class RIBActivator implements RIBExtensionProviderActivator {
 
                reg = context.registerAdjRIBsInFactory(LinkstateAddressFamily.class, LinkstateSubsequentAddressFamily.class, new AdjRIBsInFactory() {
                        @Override
-                       public AdjRIBsIn createAdjRIBsIn(final Comparator<PathAttributes> comparator, final TablesKey key) {
-                               return new LinkstateAdjRIBsIn(comparator, key);
+                       public AdjRIBsIn createAdjRIBsIn(final DataModificationTransaction trans, final Comparator<PathAttributes> comparator, final TablesKey key) {
+                               return new LinkstateAdjRIBsIn(trans, comparator, key);
                        }
                });
        }
index 8713cec960ade5c9fd7f4cabf371eae612a9b7d5..b99e8e1930819fb67fe6bf04001d91b1a2bcbb14 100644 (file)
@@ -25,8 +25,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 final class Ipv4AdjRIBsIn extends AbstractAdjRIBsIn<Ipv4Prefix, Ipv4Route> {
-       Ipv4AdjRIBsIn(final Comparator<PathAttributes> comparator, final TablesKey key) {
-               super(comparator, key);
+       Ipv4AdjRIBsIn(final DataModificationTransaction trans, final Comparator<PathAttributes> comparator, final TablesKey key) {
+               super(trans, comparator, key);
        }
 
        @Override
index 81b0b14d246430fc1ed961b0609033b410257671..dd077170d160660bb31c8ae96f6ac7a0be3499a4 100644 (file)
@@ -25,8 +25,8 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 
 final class Ipv6AdjRIBsIn extends AbstractAdjRIBsIn<Ipv6Prefix, Ipv6Route> {
-       Ipv6AdjRIBsIn(final Comparator<PathAttributes> comparator, final TablesKey key) {
-               super(comparator, key);
+       Ipv6AdjRIBsIn(final DataModificationTransaction trans, final Comparator<PathAttributes> comparator, final TablesKey key) {
+               super(trans, comparator, key);
        }
 
        @Override
index e18601aebbca4b703296fcd17513c21a6cb3ab26..a7fa5dc200f1ee4e72068fb6a41de82220d8056e 100644 (file)
@@ -9,6 +9,7 @@ package org.opendaylight.protocol.bgp.rib.impl;
 
 import java.util.Comparator;
 
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsIn;
 import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsInFactory;
 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderActivator;
@@ -34,15 +35,15 @@ public final class RIBActivator implements RIBExtensionProviderActivator {
 
                v4reg = context.registerAdjRIBsInFactory(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class, new AdjRIBsInFactory() {
                        @Override
-                       public AdjRIBsIn createAdjRIBsIn(final Comparator<PathAttributes> comparator, final TablesKey key) {
-                               return new Ipv4AdjRIBsIn(comparator, key);
+                       public AdjRIBsIn createAdjRIBsIn(final DataModificationTransaction trans, final Comparator<PathAttributes> comparator, final TablesKey key) {
+                               return new Ipv4AdjRIBsIn(trans, comparator, key);
                        }
                });
 
                v6reg = context.registerAdjRIBsInFactory(Ipv6AddressFamily.class, UnicastSubsequentAddressFamily.class, new AdjRIBsInFactory() {
                        @Override
-                       public AdjRIBsIn createAdjRIBsIn(final Comparator<PathAttributes> comparator, final TablesKey key) {
-                               return new Ipv6AdjRIBsIn(comparator, key);
+                       public AdjRIBsIn createAdjRIBsIn(final DataModificationTransaction trans, final Comparator<PathAttributes> comparator, final TablesKey key) {
+                               return new Ipv6AdjRIBsIn(trans, comparator, key);
                        }
                });
 
index a7e4e0571788f65d8b6ebbcfcc6ab0e316076774..a7382ec7a848090c89ce51fedc288a14151b0512 100644 (file)
@@ -15,6 +15,7 @@ import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
 import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsIn;
 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.UpdateBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.Nlri;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.WithdrawnRoutes;
@@ -44,6 +45,7 @@ import com.google.common.util.concurrent.JdkFutureAdapters;
 @ThreadSafe
 public class RIBImpl {
        private static final Logger LOG = LoggerFactory.getLogger(RIBImpl.class);
+       private static final Update EOR = new UpdateBuilder().build();
        private final DataProviderService dps;
        private final RIBTables tables;
 
@@ -55,11 +57,19 @@ public class RIBImpl {
        synchronized void updateTables(final BGPPeer peer, final Update message) {
                final DataModificationTransaction trans = this.dps.beginTransaction();
 
-               // FIXME: detect and handle end-of-RIB markers
+               if (EOR.equals(message)) {
+                       final AdjRIBsIn ari = this.tables.getOrCreate(trans, new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
+                       if (ari != null) {
+                               ari.markUptodate(trans, peer);
+                       } else {
+                               LOG.debug("End-of-RIB for IPv4 Unicast ignored");
+                       }
+                       return;
+               }
 
                final WithdrawnRoutes wr = message.getWithdrawnRoutes();
                if (wr != null) {
-                       final AdjRIBsIn ari = this.tables.getOrCreate(new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
+                       final AdjRIBsIn ari = this.tables.getOrCreate(trans, new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
                        if (ari != null) {
                                ari.removeRoutes(trans, peer, new MpUnreachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).setWithdrawnRoutes(
                                                new WithdrawnRoutesBuilder().setDestinationType(new DestinationIpv4Builder().setIpv4Prefixes(wr.getWithdrawnRoutes()).build()).build()).build());
@@ -73,7 +83,7 @@ public class RIBImpl {
                if (mpu != null) {
                        final MpUnreachNlri nlri = mpu.getMpUnreachNlri();
 
-                       final AdjRIBsIn ari = this.tables.getOrCreate(new TablesKey(nlri.getAfi(), nlri.getSafi()));
+                       final AdjRIBsIn ari = this.tables.getOrCreate(trans, new TablesKey(nlri.getAfi(), nlri.getSafi()));
                        if (ari != null) {
                                ari.removeRoutes(trans, peer, nlri);
                        } else {
@@ -83,7 +93,7 @@ public class RIBImpl {
 
                final Nlri ar = message.getNlri();
                if (ar != null) {
-                       final AdjRIBsIn ari = this.tables.getOrCreate(new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
+                       final AdjRIBsIn ari = this.tables.getOrCreate(trans, new TablesKey(Ipv4AddressFamily.class, UnicastSubsequentAddressFamily.class));
                        if (ari != null) {
                                ari.addRoutes(trans, peer, new MpReachNlriBuilder().setAfi(Ipv4AddressFamily.class).setSafi(UnicastSubsequentAddressFamily.class).
                                                setCNextHop(attrs.getCNextHop()).setAdvertizedRoutes(
@@ -97,9 +107,12 @@ public class RIBImpl {
                if (mpr != null) {
                        final MpReachNlri nlri = mpr.getMpReachNlri();
 
-                       final AdjRIBsIn ari = this.tables.getOrCreate(new TablesKey(nlri.getAfi(), nlri.getSafi()));
+                       final AdjRIBsIn ari = this.tables.getOrCreate(trans, new TablesKey(nlri.getAfi(), nlri.getSafi()));
                        if (ari != null) {
                                ari.addRoutes(trans, peer, nlri, attrs);
+                               if (message.equals(ari.endOfRib())) {
+                                       ari.markUptodate(trans, peer);
+                               }
                        } else {
                                LOG.debug("Not adding objects from unhandled NLRI {}", nlri);
                        }
index 5bac74a1fa5a36e180c02815c1fc0edd42a773f4..f214ee905b686be4dca3473f8b39045bea5e9b08 100644 (file)
@@ -4,6 +4,7 @@ import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Map;
 
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsIn;
 import org.opendaylight.protocol.bgp.rib.spi.AdjRIBsInFactory;
 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext;
@@ -26,7 +27,7 @@ final class RIBTables {
                return tables.get(key);
        }
 
-       public synchronized AdjRIBsIn getOrCreate(final TablesKey key) {
+       public synchronized AdjRIBsIn getOrCreate(final DataModificationTransaction trans, final TablesKey key) {
                if (tables.containsKey(key)) {
                        return tables.get(key);
                }
@@ -36,7 +37,7 @@ final class RIBTables {
                        return null;
                }
 
-               final AdjRIBsIn table = Preconditions.checkNotNull(f.createAdjRIBsIn(comparator, key));
+               final AdjRIBsIn table = Preconditions.checkNotNull(f.createAdjRIBsIn(trans, comparator, key));
                tables.put(key, table);
                return table;
        }
index d5ab30dc08f7c38de65ed35abfd05cd9ea352c8a..2ce2c6684b1b9af503d0d3828397a15bc4b109e5 100644 (file)
@@ -17,8 +17,15 @@ import javax.annotation.concurrent.ThreadSafe;
 
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.UpdateBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributesBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.PathAttributes1Builder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlriBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.LocRib;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
@@ -88,7 +95,7 @@ public abstract class AbstractAdjRIBsIn<ID, DATA extends DataObject> implements
                        LOG.trace("Electing state {} to supersede {}", candidate, currentState);
 
                        if (this.currentState == null || !this.currentState.equals(candidate)) {
-                               transaction.putRuntimeData(getName(), candidate.getDataObject(this.key));
+                               transaction.putOperationalData(getName(), candidate.getDataObject(this.key));
                                this.currentState = candidate;
                        }
                }
@@ -117,12 +124,33 @@ public abstract class AbstractAdjRIBsIn<ID, DATA extends DataObject> implements
        private static final Logger LOG = LoggerFactory.getLogger(AbstractAdjRIBsIn.class);
        private final Comparator<PathAttributes> comparator;
        private final InstanceIdentifier<Tables> basePath;
+       private final Update eor;
+
        @GuardedBy("this")
        private final Map<ID, RIBEntry> entries = new HashMap<>();
 
-       protected AbstractAdjRIBsIn(final Comparator<PathAttributes> comparator, final TablesKey key) {
+       @GuardedBy("this")
+       private final Map<Peer, Boolean> peers = new HashMap<>();
+
+       protected AbstractAdjRIBsIn(final DataModificationTransaction trans, final Comparator<PathAttributes> comparator, final TablesKey key) {
                this.comparator = Preconditions.checkNotNull(comparator);
                this.basePath = InstanceIdentifier.builder(LocRib.class).child(Tables.class, key).toInstance();
+
+               eor = new UpdateBuilder().setPathAttributes(
+                               new PathAttributesBuilder().addAugmentation(
+                                               PathAttributes1.class,
+                                               new PathAttributes1Builder().setMpReachNlri(
+                                                               new MpReachNlriBuilder().setAfi(key.getAfi()).setSafi(key.getSafi()).build()).build()).build()).build();
+
+               trans.putOperationalData(basePath, new TablesBuilder().setAfi(key.getAfi()).setSafi(key.getSafi()).setUptodate(Boolean.FALSE).build());
+       }
+
+       private void setUptodate(final DataModificationTransaction trans, final Boolean uptodate) {
+               final Tables t = (Tables) trans.readOperationalData(basePath);
+               if (t == null || !uptodate.equals(t.isUptodate())) {
+                       LOG.debug("Table {} switching uptodate to {}", uptodate);
+                       trans.putOperationalData(basePath, new TablesBuilder(t).setUptodate(uptodate).build());
+               }
        }
 
        @Override
@@ -135,6 +163,9 @@ public abstract class AbstractAdjRIBsIn<ID, DATA extends DataObject> implements
                                i.remove();
                        }
                }
+
+               peers.remove(peer);
+               setUptodate(trans, peers.values().contains(Boolean.FALSE) == false);
        }
 
        protected abstract InstanceIdentifier<?> identifierForKey(final InstanceIdentifier<Tables> basePath, final ID id);
@@ -147,6 +178,10 @@ public abstract class AbstractAdjRIBsIn<ID, DATA extends DataObject> implements
                }
 
                e.setState(trans, peer, data);
+               if (!peers.containsKey(peer)) {
+                       peers.put(peer, Boolean.FALSE);
+                       setUptodate(trans, Boolean.FALSE);
+               }
        }
 
        protected synchronized void remove(final DataModificationTransaction trans, final Peer peer, final ID id) {
@@ -156,4 +191,15 @@ public abstract class AbstractAdjRIBsIn<ID, DATA extends DataObject> implements
                        this.entries.remove(id);
                }
        }
+
+       @Override
+       public final void markUptodate(final DataModificationTransaction trans, final Peer peer) {
+               peers.put(peer, Boolean.TRUE);
+               setUptodate(trans, peers.values().contains(Boolean.FALSE) == false);
+       }
+
+       @Override
+       public final Update endOfRib() {
+               return eor;
+       }
 }
index 01a262cd63bd04c8d833090d74c663781ff720a3..3b394fd002a1f8cbe1e03faefdc497202da4ab48 100644 (file)
@@ -8,12 +8,15 @@
 package org.opendaylight.protocol.bgp.rib.spi;
 
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.Update;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.update.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpReachNlri;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.path.attributes.MpUnreachNlri;
 
 public interface AdjRIBsIn {
-       public void addRoutes(DataModificationTransaction trans, Peer peer, MpReachNlri nlri, PathAttributes attributes);
-       public void removeRoutes(DataModificationTransaction trans, Peer peer, MpUnreachNlri nlri);
-       public void clear(DataModificationTransaction trans, Peer peer);
+       void addRoutes(DataModificationTransaction trans, Peer peer, MpReachNlri nlri, PathAttributes attributes);
+       void removeRoutes(DataModificationTransaction trans, Peer peer, MpUnreachNlri nlri);
+       void clear(DataModificationTransaction trans, Peer peer);
+       void markUptodate(DataModificationTransaction trans,  Peer peer);
+       Update endOfRib();
 }
index 70bf882553e3c6df382356b6ba2600960751ac5d..a6a1388f6637a2edfc4d7d004a39aef99cb7550d 100644 (file)
@@ -9,9 +9,10 @@ package org.opendaylight.protocol.bgp.rib.spi;
 
 import java.util.Comparator;
 
+import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev130919.PathAttributes;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey;
 
 public interface AdjRIBsInFactory {
-       public AdjRIBsIn createAdjRIBsIn(final Comparator<PathAttributes> comparator, final TablesKey key);
+       public AdjRIBsIn createAdjRIBsIn(final DataModificationTransaction trans, final Comparator<PathAttributes> comparator, final TablesKey key);
 }
index 77a14c8058e8865d52c5d78a231dd98b6c620160..943093a2c832ac1f73f80977da9e40ead129e4a3 100644 (file)
@@ -8,6 +8,7 @@
 package org.opendaylight.protocol.integration.bgp;
 
 import java.util.Collection;
+import java.util.HashMap;
 import java.util.List;
 import java.util.concurrent.ExecutionException;
 import java.util.concurrent.Future;
@@ -27,9 +28,9 @@ import org.mockito.stubbing.Answer;
 import org.opendaylight.controller.md.sal.common.api.TransactionStatus;
 import org.opendaylight.controller.sal.binding.api.data.DataModificationTransaction;
 import org.opendaylight.controller.sal.binding.api.data.DataProviderService;
-import org.opendaylight.protocol.bgp.linkstate.RIBActivator;
 import org.opendaylight.protocol.bgp.parser.spi.pojo.ServiceLoaderBGPExtensionProviderContext;
 import org.opendaylight.protocol.bgp.rib.impl.BGPPeer;
+import org.opendaylight.protocol.bgp.rib.impl.RIBActivator;
 import org.opendaylight.protocol.bgp.rib.impl.RIBImpl;
 import org.opendaylight.protocol.bgp.rib.mock.BGPMock;
 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
@@ -106,23 +107,36 @@ public class ParserToSalTest {
                        }
                }).when(this.mockedTransaction).commit();
 
+               final HashMap<Object, Object> data = new HashMap<>();
+
                Mockito.doAnswer(new Answer<String>() {
                        @Override
                        public String answer(final InvocationOnMock invocation) throws Throwable {
                                final Object[] args = invocation.getArguments();
-                               for (final Object a : args) {
-                                       LOG.debug("Arg: {}", a);
-                               }
+                               LOG.debug("Put key {} value {}", args[0]);
+                               LOG.debug("Put value {}", args[1]);
+                               data.put(args[0], args[1]);
                                return null;
                        }
 
-               }).when(this.mockedTransaction).putRuntimeData(Matchers.any(InstanceIdentifier.class), Matchers.any(DataObject.class));
+               }).when(this.mockedTransaction).putOperationalData(Matchers.any(InstanceIdentifier.class), Matchers.any(DataObject.class));
+
+               Mockito.doAnswer(new Answer<Object>() {
+                       @Override
+                       public Object answer(final InvocationOnMock invocation) throws Throwable {
+                               final Object[] args = invocation.getArguments();
+                               LOG.debug("Get key {}", args[0]);
+                               return data.get(args[0]);
+                       }
+
+               }).when(this.mockedTransaction).readOperationalData(Matchers.any(InstanceIdentifier.class));
        }
 
        @Test
        public void test() {
                final RIBExtensionProviderContext ext = new SimpleRIBExtensionProviderContext();
                new RIBActivator().startRIBExtensionProvider(ext);
+               new org.opendaylight.protocol.bgp.linkstate.RIBActivator().startRIBExtensionProvider(ext);
                final RIBImpl rib = new RIBImpl(ext, this.providerService);
                final BGPPeer peer = new BGPPeer(rib, "peer-" + this.mock.toString());
 
@@ -133,7 +147,7 @@ public class ParserToSalTest {
                        }
                }, null);
                Mockito.verify(this.mockedTransaction, Mockito.times(24)).commit();
-               Mockito.verify(this.mockedTransaction, Mockito.times(40)).putRuntimeData(Matchers.any(InstanceIdentifier.class),
+               Mockito.verify(this.mockedTransaction, Mockito.times(67)).putOperationalData(Matchers.any(InstanceIdentifier.class),
                                Matchers.any(DataObject.class));
        }