MRI version bumpup for Aluminium
[netvirt.git] / bgpmanager / impl / src / main / java / org / opendaylight / netvirt / bgpmanager / BgpConfigurationManager.java
index 678baa8c37d24784f175b9d231f3ecd975d248b3..280f662204c2184c55228c42917e507288699f4c 100755 (executable)
@@ -10,9 +10,10 @@ package org.opendaylight.netvirt.bgpmanager;
 import static org.opendaylight.netvirt.bgpmanager.oam.BgpConstants.HISTORY_LIMIT;
 import static org.opendaylight.netvirt.bgpmanager.oam.BgpConstants.HISTORY_THRESHOLD;
 
-import com.google.common.base.Optional;
 import com.google.common.base.Preconditions;
 import com.google.common.net.InetAddresses;
+import com.google.common.util.concurrent.Futures;
+import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.ThreadFactoryBuilder;
 import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
 import io.netty.util.concurrent.GlobalEventExecutor;
@@ -31,6 +32,7 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.Timer;
 import java.util.concurrent.Callable;
 import java.util.concurrent.ConcurrentHashMap;
@@ -42,6 +44,7 @@ import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.ScheduledFuture;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 import javax.annotation.PreDestroy;
@@ -51,16 +54,14 @@ import org.apache.thrift.TApplicationException;
 import org.apache.thrift.TException;
 import org.apache.thrift.transport.TTransport;
 import org.eclipse.jdt.annotation.Nullable;
-import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
-import org.opendaylight.controller.md.sal.binding.api.DataBroker;
-import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
-import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
-import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException;
-import org.opendaylight.genius.datastoreutils.AsyncDataTreeChangeListenerBase;
 import org.opendaylight.genius.datastoreutils.SingleTransactionDataBroker;
 import org.opendaylight.genius.mdsalutil.NwConstants;
 import org.opendaylight.genius.utils.clustering.EntityOwnershipUtils;
 import org.opendaylight.infrautils.metrics.MetricProvider;
+import org.opendaylight.mdsal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.mdsal.binding.api.DataBroker;
+import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
+import org.opendaylight.mdsal.common.api.TransactionCommitFailedException;
 import org.opendaylight.mdsal.eos.binding.api.Entity;
 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipCandidateRegistration;
 import org.opendaylight.mdsal.eos.binding.api.EntityOwnershipListenerRegistration;
@@ -86,13 +87,19 @@ import org.opendaylight.netvirt.fibmanager.api.RouteOrigin;
 import org.opendaylight.netvirt.vpnmanager.api.intervpnlink.IVpnLinkService;
 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionHistory;
 import org.opendaylight.ovsdb.utils.mdsal.utils.TransactionType;
+import org.opendaylight.serviceutils.tools.listener.AbstractAsyncDataTreeChangeListener;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfig;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebfd.rev190219.BfdConfigBuilder;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.AddressFamily;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.Bgp;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.BgpControlPlaneType;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EbgpService;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.EncapType;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.InitiateEorInput;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.InitiateEorOutput;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.InitiateEorOutputBuilder;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.TcpMd5SignaturePasswordType;
+//import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.*;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsId;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.AsIdBuilder;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.ConfigServer;
@@ -102,33 +109,39 @@ import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev1509
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.GracefulRestartBuilder;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Logging;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.LoggingBuilder;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Multipath;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathBuilder;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathKey;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Neighbors;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsKey;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Networks;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksBuilder;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksKey;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpath;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathBuilder;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathKey;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.Vrfs;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsBuilder;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.MultipathContainer;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NeighborsContainer;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.NetworksContainer;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfMaxpathContainer;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.VrfsContainer;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTep;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepBuilder;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.dcgw.tep.list.DcgwTepKey;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamilies;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesBuilder;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.AddressFamiliesKey;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihop;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.EbgpMultihopBuilder;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSource;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighbors.UpdateSourceBuilder;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrf;
-import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfs.AddressFamiliesVrfBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.multipathcontainer.Multipath;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.multipathcontainer.MultipathBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.multipathcontainer.MultipathKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.Neighbors;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.NeighborsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.NeighborsKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.AddressFamilies;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.AddressFamiliesBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.AddressFamiliesKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.EbgpMultihop;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.EbgpMultihopBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.UpdateSource;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.neighborscontainer.neighbors.UpdateSourceBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.networkscontainer.Networks;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.networkscontainer.NetworksBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.networkscontainer.NetworksKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfmaxpathcontainer.VrfMaxpath;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfmaxpathcontainer.VrfMaxpathBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfmaxpathcontainer.VrfMaxpathKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.Vrfs;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.VrfsBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.VrfsKey;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.vrfs.AddressFamiliesVrf;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.vrfs.AddressFamiliesVrfBuilder;
+import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.bgp.vrfscontainer.vrfs.AddressFamiliesVrfKey;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.TcpSecurityOption;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOption;
 import org.opendaylight.yang.gen.v1.urn.ericsson.params.xml.ns.yang.ebgp.rev150901.tcp.security.option.grouping.tcp.security.option.TcpMd5SignatureOptionBuilder;
@@ -137,12 +150,16 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.
 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.FibEntries;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTables;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.fibentries.VrfTablesKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.macvrfentries.MacVrfEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.fibmanager.rev150330.vrfentries.VrfEntry;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.l3vpn.rev130911.vpn.instance.op.data.VpnInstanceOpDataEntry;
 import org.opendaylight.yangtools.yang.binding.DataObject;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder;
+import org.opendaylight.yangtools.yang.common.RpcError;
+import org.opendaylight.yangtools.yang.common.RpcResult;
+import org.opendaylight.yangtools.yang.common.RpcResultBuilder;
 import org.opendaylight.yangtools.yang.common.Uint32;
 import org.osgi.framework.BundleContext;
 import org.osgi.util.tracker.ServiceTracker;
@@ -150,7 +167,7 @@ import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 @Singleton
-public class BgpConfigurationManager {
+public class BgpConfigurationManager implements EbgpService {
     private static final Logger LOG = LoggerFactory.getLogger(BgpConfigurationManager.class);
 
     // to have stale FIB map (RD, Prefix)
@@ -184,6 +201,7 @@ public class BgpConfigurationManager {
     private static final String UPD_WARN = "Update operation not supported; Config store updated;"
             + " restore with another Update if needed.";
     private static long bgp_as_num = 0;
+    private static List<Neighbors> nbrList = new ArrayList<>();
     private int bgpKaTime = 0;
     private int bgpHoldTime = 0;
     private int bgpGrRestartTime = 0;
@@ -234,7 +252,7 @@ public class BgpConfigurationManager {
     private int totalExternalMacRoutes;
 
     private final ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor(
-            new ThreadFactoryBuilder().setNameFormat("BgpConfigurationManager-%d").setDaemon(true).build());
+            new ThreadFactoryBuilder().setNameFormat("bgp-config-%d").setDaemon(true).build());
 
     /**
      * this map store the new address families to send to quagga. When it is sended you must clear it.
@@ -248,6 +266,9 @@ public class BgpConfigurationManager {
     // map<rd, map<tep-ip, map<mac, l2vni>>>
     private final Map<String, Map<String, Map<String, Uint32>>> rt2TepMap = new ConcurrentHashMap<>();
 
+    //map<rd+prefix/plen, list (nexthop)>
+    private final Map<String,List> fibMap = new HashMap<>();
+
     private final List<AutoCloseable> listeners = new ArrayList<>();
 
     private final EntityOwnershipUtils entityOwnershipUtils;
@@ -256,6 +277,8 @@ public class BgpConfigurationManager {
     private final MetricProvider metricProvider;
     private final TransactionHistory bgpUpdatesHistory;
 
+    private volatile AtomicBoolean eorSupressedDuetoUpgradeFlag = new AtomicBoolean(false);
+
     @Inject
     public BgpConfigurationManager(final DataBroker dataBroker,
             final EntityOwnershipService entityOwnershipService,
@@ -393,8 +416,8 @@ public class BgpConfigurationManager {
         for (Class<?> reactor : REACTORS) {
             Object obj = createListener(reactor);
             if (obj != null) {
-                AsyncDataTreeChangeListenerBase dcl = (AsyncDataTreeChangeListenerBase) obj;
-                dcl.registerListener(LogicalDatastoreType.CONFIGURATION, dataBroker);
+                AbstractAsyncDataTreeChangeListener dcl = (AbstractAsyncDataTreeChangeListener) obj;
+                dcl.register();
                 listeners.add(dcl);
             }
         }
@@ -473,6 +496,8 @@ public class BgpConfigurationManager {
                     //disconnect the CONFIG SERVER port (which was )opened during I was Owner
                     bgpRouter.disconnect();
                 }
+                stopBgpCountersTask();
+                stopBgpAlarmsTask();
             }
         });
     }
@@ -491,16 +516,19 @@ public class BgpConfigurationManager {
     }
 
     public class ConfigServerReactor
-            extends AsyncDataTreeChangeListenerBase<ConfigServer, ConfigServerReactor>
+            extends AbstractAsyncDataTreeChangeListener<ConfigServer>
             implements ClusteredDataTreeChangeListener<ConfigServer> {
         private static final String YANG_OBJ = "config-server ";
 
         public ConfigServerReactor() {
-            super(ConfigServer.class, ConfigServerReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(ConfigServer.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("ConfigServerReactor", LOG));
         }
 
         @Override
-        protected void add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
+        public void add(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
             LOG.trace("received bgp connect config host {}", val.getHost().getValue());
             if (!isBGPEntityOwner()) {
                 return;
@@ -525,17 +553,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected ConfigServerReactor getDataTreeChangeListener() {
-            return ConfigServerReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<ConfigServer> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(ConfigServer.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
+        public void remove(InstanceIdentifier<ConfigServer> iid, ConfigServer val) {
             LOG.trace("received bgp disconnect");
             if (!isBGPEntityOwner()) {
                 return;
@@ -560,7 +578,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<ConfigServer> iid,
+        public void update(InstanceIdentifier<ConfigServer> iid,
                 ConfigServer oldval, ConfigServer newval) {
             LOG.trace("received bgp Connection update");
             if (!isBGPEntityOwner()) {
@@ -580,18 +598,21 @@ public class BgpConfigurationManager {
         return bgpRouter;
     }
 
-    public class AsIdReactor
-            extends AsyncDataTreeChangeListenerBase<AsId, AsIdReactor>
+    public class AsIdReactor extends AbstractAsyncDataTreeChangeListener<AsId>
             implements ClusteredDataTreeChangeListener<AsId> {
 
         private static final String YANG_OBJ = "as-id ";
 
         public AsIdReactor() {
-            super(AsId.class, AsIdReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(AsId.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("AsIdReactor", LOG));
         }
 
+        @SuppressFBWarnings(value  = "ST_WRITE_TO_STATIC_FROM_INSTANCE_METHOD")
         @Override
-        protected void add(InstanceIdentifier<AsId> iid, AsId val) {
+        public void add(InstanceIdentifier<AsId> iid, AsId val) {
             LOG.error("received bgp add asid {}", val);
             if (!isBGPEntityOwner()) {
                 return;
@@ -613,17 +634,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected AsIdReactor getDataTreeChangeListener() {
-            return AsIdReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<AsId> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(AsId.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<AsId> iid, AsId val) {
+        public void remove(InstanceIdentifier<AsId> iid, AsId val) {
             LOG.error("received delete router config asNum {}", val.getLocalAs());
             if (!isBGPEntityOwner()) {
                 return;
@@ -653,10 +664,11 @@ public class BgpConfigurationManager {
                 }
                 LOG.debug("Removing external routes from FIB");
                 deleteExternalFibRoutes();
-                List<Neighbors> nbrs = conf.getNeighbors();
-                if (nbrs != null && nbrs.size() > 0) {
+                Map<NeighborsKey, Neighbors> keyNeighborsMap = conf.getNeighborsContainer() == null ? null
+                        : conf.getNeighborsContainer().getNeighbors();
+                if (keyNeighborsMap != null && keyNeighborsMap.size() > 0) {
                     LOG.error("Tring to remove the as-id when neighbor config is already present");
-                    for (Neighbors nbr : nbrs) {
+                    for (Neighbors nbr : keyNeighborsMap.values()) {
                         LOG.debug("Removing Neighbor {} from Data store", nbr.getAddress().getValue());
                         delNeighbor(nbr.getAddress().getValue());
                     }
@@ -665,7 +677,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<AsId> iid,
+        public void update(InstanceIdentifier<AsId> iid,
                 AsId oldval, AsId newval) {
             if (!isBGPEntityOwner()) {
                 return;
@@ -674,18 +686,20 @@ public class BgpConfigurationManager {
         }
     }
 
-    public class GracefulRestartReactor
-            extends AsyncDataTreeChangeListenerBase<GracefulRestart, GracefulRestartReactor>
+    public class GracefulRestartReactor extends AbstractAsyncDataTreeChangeListener<GracefulRestart>
             implements ClusteredDataTreeChangeListener<GracefulRestart> {
 
         private static final String YANG_OBJ = "graceful-restart ";
 
         public GracefulRestartReactor() {
-            super(GracefulRestart.class, GracefulRestartReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("GracefulRestartReactor", LOG));
         }
 
         @Override
-        protected void add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
+        public void add(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -706,17 +720,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected GracefulRestartReactor getDataTreeChangeListener() {
-            return GracefulRestartReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<GracefulRestart> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
+        public void remove(InstanceIdentifier<GracefulRestart> iid, GracefulRestart val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -737,7 +741,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<GracefulRestart> iid,
+        public void update(InstanceIdentifier<GracefulRestart> iid,
                 GracefulRestart oldval, GracefulRestart newval) {
             if (!isBGPEntityOwner()) {
                 return;
@@ -760,18 +764,20 @@ public class BgpConfigurationManager {
         }
     }
 
-    public class LoggingReactor
-            extends AsyncDataTreeChangeListenerBase<Logging, LoggingReactor>
+    public class LoggingReactor extends AbstractAsyncDataTreeChangeListener<Logging>
             implements ClusteredDataTreeChangeListener<Logging> {
 
         private static final String YANG_OBJ = "logging ";
 
         public LoggingReactor() {
-            super(Logging.class, LoggingReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(Logging.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("LoggingReactor", LOG));
         }
 
         @Override
-        protected void add(InstanceIdentifier<Logging> iid, Logging val) {
+        public void add(InstanceIdentifier<Logging> iid, Logging val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -791,17 +797,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected LoggingReactor getDataTreeChangeListener() {
-            return LoggingReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<Logging> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(Logging.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<Logging> iid, Logging val) {
+        public void remove(InstanceIdentifier<Logging> iid, Logging val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -822,7 +818,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<Logging> iid,
+        public void update(InstanceIdentifier<Logging> iid,
                 Logging oldval, Logging newval) {
             if (!isBGPEntityOwner()) {
                 return;
@@ -843,24 +839,35 @@ public class BgpConfigurationManager {
         }
     }
 
-    public class NeighborsReactor
-            extends AsyncDataTreeChangeListenerBase<Neighbors, NeighborsReactor>
+    public class NeighborsReactor extends AbstractAsyncDataTreeChangeListener<Neighbors>
             implements ClusteredDataTreeChangeListener<Neighbors> {
 
         private static final String YANG_OBJ = "neighbors ";
 
         public NeighborsReactor() {
-            super(Neighbors.class, NeighborsReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(NeighborsContainer.class).child(Neighbors.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("NeighborsReactor", LOG));
         }
 
         @Override
-        protected void add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
+        public void add(InstanceIdentifier<Neighbors> iid, Neighbors val) {
+            if (nbrList != null && !nbrList.contains(val)) {
+                LOG.trace("Adding nbr {} to nbrlist", val.getAddress().getValue());
+                nbrList.add(val);
+            }
             if (!isBGPEntityOwner()) {
                 return;
             }
             LOG.debug("received add Neighbors config val {}", val.getAddress().getValue());
             synchronized (BgpConfigurationManager.this) {
                 String peerIp = val.getAddress().getValue();
+                String sourceIp = (val.getUpdateSource() == null) ? null :
+                                    val.getUpdateSource().getSourceIp().getValue();
+                int nhops = (val.getEbgpMultihop() == null) ? 0 :
+                                    val.getEbgpMultihop().getNhops().intValue();
+                Map<AddressFamiliesKey, AddressFamilies> keyAddressFamiliesMap = val.getAddressFamilies();
                 long as = val.getRemoteAs().toJava();
                 final String md5Secret = extractMd5Secret(val);
                 BgpRouter br = getClient(YANG_OBJ);
@@ -872,6 +879,19 @@ public class BgpConfigurationManager {
                 try {
                     //itmProvider.buildTunnelsToDCGW(new IpAddress(peerIp.toCharArray()));
                     br.addNeighbor(peerIp, as, md5Secret);
+                    if (nhops != 0) {
+                        br.addEbgpMultihop(peerIp, nhops);
+                    }
+                    if (sourceIp != null) {
+                        br.addUpdateSource(peerIp, sourceIp);
+                    }
+                    if (keyAddressFamiliesMap != null) {
+                        for (AddressFamilies af : keyAddressFamiliesMap.values()) {
+                            af_afi afi = af_afi.findByValue(af.getAfi().intValue());
+                            af_safi safi = af_safi.findByValue(af.getSafi().intValue());
+                            br.addAddressFamily(af.getPeerIp().getValue(), afi, safi);
+                        }
+                    }
 
                 } catch (TException | BgpRouterException e) {
                     LOG.error("{} Add received exception; {}", YANG_OBJ, ADD_WARN, e);
@@ -880,17 +900,11 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected NeighborsReactor getDataTreeChangeListener() {
-            return NeighborsReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<Neighbors> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(Neighbors.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
+        public void remove(InstanceIdentifier<Neighbors> iid, Neighbors val) {
+            if (nbrList != null && nbrList.contains(val)) {
+                LOG.trace("Removing nbr {} from nbr list", val.getAddress().getValue());
+                nbrList.remove(val);
+            }
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -925,7 +939,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<Neighbors> iid,
+        public void update(InstanceIdentifier<Neighbors> iid,
                 Neighbors oldval, Neighbors newval) {
             if (!isBGPEntityOwner()) {
                 return;
@@ -934,18 +948,20 @@ public class BgpConfigurationManager {
         }
     }
 
-    public class EbgpMultihopReactor
-            extends AsyncDataTreeChangeListenerBase<EbgpMultihop, EbgpMultihopReactor>
+    public class EbgpMultihopReactor extends AbstractAsyncDataTreeChangeListener<EbgpMultihop>
             implements ClusteredDataTreeChangeListener<EbgpMultihop> {
 
         private static final String YANG_OBJ = "ebgp-multihop ";
 
         public EbgpMultihopReactor() {
-            super(EbgpMultihop.class, EbgpMultihopReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(NeighborsContainer.class).child(Neighbors.class)
+                    .child(EbgpMultihop.class), org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("EbgpMultihopReactor", LOG));
         }
 
         @Override
-        protected void add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
+        public void add(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -967,17 +983,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected EbgpMultihopReactor getDataTreeChangeListener() {
-            return EbgpMultihopReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<EbgpMultihop> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(EbgpMultihop.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
+        public void remove(InstanceIdentifier<EbgpMultihop> iid, EbgpMultihop val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -999,7 +1005,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<EbgpMultihop> iid,
+        public void update(InstanceIdentifier<EbgpMultihop> iid,
                 EbgpMultihop oldval, EbgpMultihop newval) {
             if (!isBGPEntityOwner()) {
                 return;
@@ -1008,18 +1014,20 @@ public class BgpConfigurationManager {
         }
     }
 
-    public class UpdateSourceReactor
-            extends AsyncDataTreeChangeListenerBase<UpdateSource, UpdateSourceReactor>
+    public class UpdateSourceReactor extends AbstractAsyncDataTreeChangeListener<UpdateSource>
             implements ClusteredDataTreeChangeListener<UpdateSource> {
 
         private static final String YANG_OBJ = "update-source ";
 
         public UpdateSourceReactor() {
-            super(UpdateSource.class, UpdateSourceReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(NeighborsContainer.class).child(Neighbors.class)
+                    .child(UpdateSource.class), org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("UpdateSourceReactor", LOG));
         }
 
         @Override
-        protected void add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
+        public void add(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1041,17 +1049,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected UpdateSourceReactor getDataTreeChangeListener() {
-            return UpdateSourceReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<UpdateSource> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(UpdateSource.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
+        public void remove(InstanceIdentifier<UpdateSource> iid, UpdateSource val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1073,7 +1071,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<UpdateSource> iid,
+        public void update(InstanceIdentifier<UpdateSource> iid,
                 UpdateSource oldval, UpdateSource newval) {
             if (!isBGPEntityOwner()) {
                 return;
@@ -1082,18 +1080,20 @@ public class BgpConfigurationManager {
         }
     }
 
-    public class AddressFamiliesReactor
-            extends AsyncDataTreeChangeListenerBase<AddressFamilies, AddressFamiliesReactor>
+    public class AddressFamiliesReactor extends AbstractAsyncDataTreeChangeListener<AddressFamilies>
             implements ClusteredDataTreeChangeListener<AddressFamilies> {
 
         private static final String YANG_OBJ = "address-families ";
 
         public AddressFamiliesReactor() {
-            super(AddressFamilies.class, AddressFamiliesReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(NeighborsContainer.class).child(Neighbors.class)
+                    .child(AddressFamilies.class), org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("AddressFamiliesReactor", LOG));
         }
 
         @Override
-        protected void add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
+        public void add(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1117,17 +1117,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected AddressFamiliesReactor getDataTreeChangeListener() {
-            return AddressFamiliesReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<AddressFamilies> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(Neighbors.class).child(AddressFamilies.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
+        public void remove(InstanceIdentifier<AddressFamilies> iid, AddressFamilies val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1151,7 +1141,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<AddressFamilies> iid,
+        public void update(InstanceIdentifier<AddressFamilies> iid,
                 AddressFamilies oldval, AddressFamilies newval) {
             if (!isBGPEntityOwner()) {
                 return;
@@ -1160,23 +1150,19 @@ public class BgpConfigurationManager {
         }
     }
 
-    public class NetworksReactor
-            extends AsyncDataTreeChangeListenerBase<Networks, NetworksReactor>
+    public class NetworksReactor extends AbstractAsyncDataTreeChangeListener<Networks>
             implements ClusteredDataTreeChangeListener<Networks> {
 
         private static final String YANG_OBJ = "networks ";
 
         public NetworksReactor() {
-            super(Networks.class, NetworksReactor.class);
-        }
-
-        @Override
-        public NetworksReactor getDataTreeChangeListener() {
-            return NetworksReactor.this;
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(NetworksContainer.class).child(Networks.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("NetworksReactor", LOG));
         }
 
-        @Override
-        protected void add(InstanceIdentifier<Networks> iid, Networks val) {
+        public void add(InstanceIdentifier<Networks> iid, Networks val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1216,12 +1202,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected InstanceIdentifier<Networks> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(Networks.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<Networks> iid, Networks val) {
+        public void remove(InstanceIdentifier<Networks> iid, Networks val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1268,7 +1249,7 @@ public class BgpConfigurationManager {
 
 
         @Override
-        protected void update(final InstanceIdentifier<Networks> iid,
+        public void update(final InstanceIdentifier<Networks> iid,
                 final Networks oldval, final Networks newval) {
             if (!isBGPEntityOwner()) {
                 return;
@@ -1290,18 +1271,20 @@ public class BgpConfigurationManager {
 
     static Timer timer = new Timer();
 
-    public class VrfsReactor
-            extends AsyncDataTreeChangeListenerBase<Vrfs, VrfsReactor>
+    public class VrfsReactor extends AbstractAsyncDataTreeChangeListener<Vrfs>
             implements ClusteredDataTreeChangeListener<Vrfs> {
 
         private static final String YANG_OBJ = "vrfs ";
 
         public VrfsReactor() {
-            super(Vrfs.class, VrfsReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(VrfsContainer.class).child(Vrfs.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("VrfsReactor", LOG));
         }
 
         @Override
-        protected void add(InstanceIdentifier<Vrfs> iid, Vrfs vrfs) {
+        public void add(InstanceIdentifier<Vrfs> iid, Vrfs vrfs) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1315,8 +1298,9 @@ public class BgpConfigurationManager {
                     return;
                 }
                 try {
-                    List<AddressFamiliesVrf> vrfAddrFamilyList = vrfs.getAddressFamiliesVrf();
-                    for (AddressFamiliesVrf vrfAddrFamily : vrfAddrFamilyList) {
+                    Map<AddressFamiliesVrfKey, AddressFamiliesVrf> keyAddressFamiliesVrfMap
+                            = vrfs.getAddressFamiliesVrf();
+                    for (AddressFamiliesVrf vrfAddrFamily : keyAddressFamiliesVrfMap.values()) {
                         /*add to br the new vrfs arguments*/
                         br.addVrf(BgpUtil.getLayerType(vrfAddrFamily), rd, vrfs.getImportRts(),
                                 vrfs.getExportRts(), vrfAddrFamily.getAfi().toJava(), vrfAddrFamily.getSafi().toJava());
@@ -1328,7 +1312,7 @@ public class BgpConfigurationManager {
                     }
 
                     for (AddressFamiliesVrf adf : vrfAddrFamilyListFromMap) {
-                        if (vrfAddrFamilyList.contains(adf)) {
+                        if (keyAddressFamiliesVrfMap.values().contains(adf)) {
                             mapNewAdFamily.remove(rd);
                         } else  if (adf != null) {
 
@@ -1350,17 +1334,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected VrfsReactor getDataTreeChangeListener() {
-            return VrfsReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<Vrfs> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(Vrfs.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
+        public void remove(InstanceIdentifier<Vrfs> iid, Vrfs val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1376,7 +1350,7 @@ public class BgpConfigurationManager {
                 try {
                     List<AddressFamiliesVrf> adf = mapNewAdFamily.get(rd);
                     adf = adf != null ? adf : new ArrayList<>();
-                    for (AddressFamiliesVrf s : val.getAddressFamiliesVrf()) {
+                    for (AddressFamiliesVrf s : val.getAddressFamiliesVrf().values()) {
                         br.delVrf(rd, s.getAfi().toJava(), s.getSafi().toJava());
                         adf.remove(s);// remove in the map the vrf in waiting for advertise quagga
                     }
@@ -1390,7 +1364,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<Vrfs> iid,
+        public void update(InstanceIdentifier<Vrfs> iid,
                 Vrfs oldval, Vrfs newval) {
             if (oldval != null && newval != null) {
                 LOG.debug("received update Vrfs config val {}, VRFS: Update getting triggered for VRFS rd {}",
@@ -1409,11 +1383,13 @@ public class BgpConfigurationManager {
             List<AddressFamiliesVrf> newlistAdFamilies = new ArrayList<>();
             if (oldval != null) {
                 oldlistAdFamilies = oldval.getAddressFamiliesVrf() == null
-                        ? new ArrayList<>() : oldval.getAddressFamiliesVrf();
+                        ? new ArrayList<>()
+                        : new ArrayList<AddressFamiliesVrf>(oldval.getAddressFamiliesVrf().values());
             }
             if (newval != null) {
                 newlistAdFamilies = newval.getAddressFamiliesVrf() == null
-                        ? new ArrayList<>() : newval.getAddressFamiliesVrf();
+                        ? new ArrayList<>()
+                        : new ArrayList<AddressFamiliesVrf>(newval.getAddressFamiliesVrf().values());
             }
             /*find old AddressFamily to remove from new configuration*/
             for (AddressFamiliesVrf adVrf : oldlistAdFamilies) {
@@ -1458,19 +1434,19 @@ public class BgpConfigurationManager {
         }
     }
 
-    public class BgpReactor
-            extends AsyncDataTreeChangeListenerBase<Bgp, BgpReactor>
+    public class BgpReactor extends AbstractAsyncDataTreeChangeListener<Bgp>
             implements ClusteredDataTreeChangeListener<Bgp> {
 
         private static final String YANG_OBJ = "Bgp ";
 
         public BgpReactor() {
-            super(Bgp.class, BgpReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Bgp.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("BgpReactor", LOG));
         }
 
-
         @Override
-        protected void add(InstanceIdentifier<Bgp> iid, Bgp val) {
+        public void add(InstanceIdentifier<Bgp> iid, Bgp val) {
             LOG.debug("received add Bgp config");
 
             try {
@@ -1487,17 +1463,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected BgpReactor getDataTreeChangeListener() {
-            return BgpReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<Bgp> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<Bgp> iid, Bgp val) {
+        public void remove(InstanceIdentifier<Bgp> iid, Bgp val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1507,7 +1473,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<Bgp> iid,
+        public void update(InstanceIdentifier<Bgp> iid,
                 Bgp oldval, Bgp newval) {
             if (!isBGPEntityOwner()) {
                 return;
@@ -1518,39 +1484,30 @@ public class BgpConfigurationManager {
     }
 
     @SuppressWarnings("deprecation")
-    public class MultipathReactor
-            extends AsyncDataTreeChangeListenerBase<Multipath, MultipathReactor>
+    public class MultipathReactor extends AbstractAsyncDataTreeChangeListener<Multipath>
             implements ClusteredDataTreeChangeListener<Multipath> {
 
         private static final String YANG_OBJ = "multipath ";
 
         public MultipathReactor() {
-            super(Multipath.class, MultipathReactor.class);
-        }
-
-
-        @Override
-        protected MultipathReactor getDataTreeChangeListener() {
-            return MultipathReactor.this;
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(Bgp.class)
+                    .child(MultipathContainer.class).child(Multipath.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("MultipathReactor", LOG));
         }
 
         @Override
-        protected InstanceIdentifier<Multipath> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(Multipath.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<Multipath> iid, Multipath val) {
+        public void remove(InstanceIdentifier<Multipath> iid, Multipath val) {
             executor.execute(new MultipathStatusChange(val));
         }
 
         @Override
-        protected void update(InstanceIdentifier<Multipath> iid, Multipath oldval, Multipath newval) {
+        public void update(InstanceIdentifier<Multipath> iid, Multipath oldval, Multipath newval) {
             executor.execute(new MultipathStatusChange(newval));
         }
 
         @Override
-        protected void add(InstanceIdentifier<Multipath> key, Multipath dataObjectModification) {
+        public void add(InstanceIdentifier<Multipath> key, Multipath dataObjectModification) {
             executor.execute(new MultipathStatusChange(dataObjectModification));
         }
 
@@ -1596,25 +1553,16 @@ public class BgpConfigurationManager {
     }
 
     @SuppressWarnings("deprecation")
-    public class VrfMaxpathReactor
-            extends AsyncDataTreeChangeListenerBase<VrfMaxpath, VrfMaxpathReactor>
+    public class VrfMaxpathReactor extends AbstractAsyncDataTreeChangeListener<VrfMaxpath>
             implements ClusteredDataTreeChangeListener<VrfMaxpath> {
 
         private static final String YANG_OBJ = "vrfMaxpath ";
 
         public VrfMaxpathReactor() {
-            super(VrfMaxpath.class, VrfMaxpathReactor.class);
-        }
-
-
-        @Override
-        protected VrfMaxpathReactor getDataTreeChangeListener() {
-            return VrfMaxpathReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<VrfMaxpath> getWildCardPath() {
-            return InstanceIdentifier.create(Bgp.class).child(VrfMaxpath.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION,
+                    InstanceIdentifier.create(Bgp.class).child(VrfMaxpathContainer.class).child(VrfMaxpath.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("VrfMaxpathReactor", LOG));
         }
 
         class VrfMaxPathConfigurator implements Runnable {
@@ -1645,7 +1593,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void remove(InstanceIdentifier<VrfMaxpath> iid, VrfMaxpath vrfMaxPathVal) {
+        public void remove(InstanceIdentifier<VrfMaxpath> iid, VrfMaxpath vrfMaxPathVal) {
             if (isBGPEntityOwner()) {
                 synchronized (BgpConfigurationManager.this) {
                     BgpRouter br = getClient(YANG_OBJ);
@@ -1662,7 +1610,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<VrfMaxpath> iid,
+        public void update(InstanceIdentifier<VrfMaxpath> iid,
                               VrfMaxpath oldval, VrfMaxpath newval) {
             if (!Objects.equals(oldval.getMaxpaths(), newval.getMaxpaths())) {
                 executor.execute(new VrfMaxPathConfigurator(newval));
@@ -1670,7 +1618,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void add(InstanceIdentifier<VrfMaxpath> instanceIdentifier, VrfMaxpath vrfMaxpathVal) {
+        public void add(InstanceIdentifier<VrfMaxpath> instanceIdentifier, VrfMaxpath vrfMaxpathVal) {
             executor.execute(new VrfMaxPathConfigurator(vrfMaxpathVal));
         }
 
@@ -1680,18 +1628,19 @@ public class BgpConfigurationManager {
         }
     }
 
-    public class BfdConfigReactor
-            extends AsyncDataTreeChangeListenerBase<BfdConfig, BfdConfigReactor>
+    public class BfdConfigReactor extends AbstractAsyncDataTreeChangeListener<BfdConfig>
             implements ClusteredDataTreeChangeListener<BfdConfig> {
 
         private static final String YANG_OBJ = "BfdConfig ";
 
         public BfdConfigReactor() {
-            super(BfdConfig.class, BfdConfigReactor.class);
+            super(dataBroker, LogicalDatastoreType.CONFIGURATION, InstanceIdentifier.create(BfdConfig.class),
+                    org.opendaylight.infrautils.utils.concurrent.Executors
+                            .newListeningSingleThreadExecutor("BfdConfigReactor", LOG));
         }
 
         @Override
-        protected void add(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
+        public void add(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1720,17 +1669,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected BfdConfigReactor getDataTreeChangeListener() {
-            return BfdConfigReactor.this;
-        }
-
-        @Override
-        protected InstanceIdentifier<BfdConfig> getWildCardPath() {
-            return InstanceIdentifier.create(BfdConfig.class);
-        }
-
-        @Override
-        protected void remove(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
+        public void remove(InstanceIdentifier<BfdConfig> iid, BfdConfig val) {
             if (!isBGPEntityOwner()) {
                 return;
             }
@@ -1750,7 +1689,7 @@ public class BgpConfigurationManager {
         }
 
         @Override
-        protected void update(InstanceIdentifier<BfdConfig> iid,
+        public void update(InstanceIdentifier<BfdConfig> iid,
                               BfdConfig oldval, BfdConfig newval) {
             LOG.debug("received bfd config: updated oldval bfd enabled {}"
                     + "min-rx {} min-tx {} detect-mul {} mhop {}",
@@ -1798,7 +1737,13 @@ public class BgpConfigurationManager {
     public long getStalePathtime(int defValue, AsId asId) {
         long spt = 0;
         try {
-            spt = getConfig().getGracefulRestart().getStalepathTime().toJava();
+            InstanceIdentifier<GracefulRestart> id =
+                    InstanceIdentifier.create(Bgp.class).child(GracefulRestart.class);
+            Optional<GracefulRestart> gracefulRestartOptional = SingleTransactionDataBroker.syncReadOptional(dataBroker,
+                    LogicalDatastoreType.CONFIGURATION, id);
+            if (gracefulRestartOptional.isPresent()) {
+                spt = gracefulRestartOptional.get().getStalepathTime().toJava();
+            }
         } catch (NullPointerException e) {
             try {
                 spt = asId.getStalepathTime().toJava();
@@ -1807,6 +1752,9 @@ public class BgpConfigurationManager {
                 LOG.trace("BGP AS id is not set using graceful");
                 spt = defValue;
             }
+        } catch (InterruptedException | ExecutionException e) {
+            LOG.trace("Exception while reading GracefulRestart DS for the As {}", asId.getStalepathTime());
+            spt = defValue;
         }
         if (spt == 0) {
             LOG.trace("BGP config/Stale-path time is not set using graceful/start-bgp");
@@ -1893,16 +1841,17 @@ public class BgpConfigurationManager {
     }
 
     private void doRouteSync() {
-        LOG.error("Starting BGP route sync");
-        try {
-            bgpRouter.initRibSync(bgpSyncHandle);
-        } catch (BgpRouterException e) {
-            LOG.error("Route sync aborted, exception when initializing", e);
-            return;
-        }
-        while (bgpSyncHandle.getState() != BgpSyncHandle.DONE) {
-            for (af_afi afi : af_afi.values()) {
+        for (af_afi afi : af_afi.values()) {
+            try {
+                bgpRouter.initRibSync(bgpSyncHandle);
+            } catch (BgpRouterException e) {
+                LOG.error("Route sync aborted, exception when initializing", e);
+                return;
+            }
+            LOG.error("Starting BGP route sync for afi {}", afi.getValue());
+            while (bgpSyncHandle.getState() != BgpSyncHandle.DONE) {
                 Routes routes = null;
+                int noUpdates = 0;
                 try {
                     routes = bgpRouter.doRibSync(bgpSyncHandle, afi);
                 } catch (TException | BgpRouterException e) {
@@ -1911,6 +1860,7 @@ public class BgpConfigurationManager {
                 }
                 Iterator<Update> updates = routes.getUpdatesIterator();
                 while (updates.hasNext()) {
+                    noUpdates++;
                     Update update = updates.next();
                     String rd = update.getRd();
                     String nexthop = update.getNexthop();
@@ -1938,13 +1888,14 @@ public class BgpConfigurationManager {
                            update.getRoutermac(),
                            afi);
                 }
+                LOG.error("No of updates for afi {} is {}", afi.getValue(), noUpdates);
             }
         }
         try {
             LOG.error("Ending BGP route-sync");
             bgpRouter.endRibSync(bgpSyncHandle);
         } catch (BgpRouterException e) {
-            // Ignored?
+            LOG.error("Route sync aborted, exception when ending", e);
         }
     }
 
@@ -2096,6 +2047,8 @@ public class BgpConfigurationManager {
     }
 
     public void peerDown(String ipAddress, long asNumber) {
+        PeerDownEvent peerDownEvent = new PeerDownEvent(ipAddress,asNumber);
+        bgpUpdatesHistory.addToHistory(TransactionType.ADD, peerDownEvent);
         List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
         if (tepIpList == null) {
             LOG.error("No Tep IP configured for DCGW {} on a peerDown", ipAddress);
@@ -2107,6 +2060,8 @@ public class BgpConfigurationManager {
     }
 
     public void peerUp(String ipAddress, long asNumber) {
+        PeerUpEvent peerUpEvent = new PeerUpEvent(ipAddress,asNumber);
+        bgpUpdatesHistory.addToHistory(TransactionType.ADD, peerUpEvent);
         List<String> tepIpList = bgpUtil.getDcgwTepConfig(ipAddress);
         if (tepIpList == null) {
             LOG.error("No Tep IP configured for DCGW {} on a peerUp", ipAddress);
@@ -2211,10 +2166,11 @@ public class BgpConfigurationManager {
                     }
                 }
 
-                //afs
-                List<AddressFamilies> afs = replayNbr.getNbr().getAddressFamilies();
-                if (afs != null) {
-                    for (AddressFamilies af : afs) {
+                //keyAddressFamiliesMap
+                Map<AddressFamiliesKey, AddressFamilies> keyAddressFamiliesMap
+                        = replayNbr.getNbr().getAddressFamilies();
+                if (keyAddressFamiliesMap != null) {
+                    for (AddressFamilies af : keyAddressFamiliesMap.values()) {
                         af_afi afi = af_afi.findByValue(af.getAfi().intValue());
                         af_safi safi = af_safi.findByValue(af.getSafi().intValue());
                         try {
@@ -2262,8 +2218,8 @@ public class BgpConfigurationManager {
         while (0 != bgpDSretryCount.decrementAndGet()) {
             try {
                 return SingleTransactionDataBroker.syncReadOptional(dataBroker, LogicalDatastoreType.CONFIGURATION,
-                        InstanceIdentifier.create(Bgp.class)).orNull();
-            } catch (ReadFailedException e) {
+                        InstanceIdentifier.create(Bgp.class)).orElse(null);
+            } catch (InterruptedException | ExecutionException e) {
                 //Config DS may not be up, so sleep for 1 second and retry
                 LOG.debug("failed to get bgp config, may be DS is yet in consistent state(?)", e);
                 try {
@@ -2392,10 +2348,13 @@ public class BgpConfigurationManager {
             }
         }
 
-        List<Neighbors> neighbors = config.getNeighbors();
-        if (neighbors != null) {
-            LOG.error("configuring existing Neighbors present for replay total neighbors {}", neighbors.size());
-            boolean neighborConfigReplayResult = replayNbrConfig(neighbors, br);
+        Map<NeighborsKey, Neighbors> keyNeighborsMap = config.getNeighborsContainer() == null ? null
+                : config.getNeighborsContainer().getNeighbors();
+        if (keyNeighborsMap != null) {
+            LOG.error("configuring existing Neighbors present for replay total keyNeighborsMap {}",
+                    keyNeighborsMap.values().size());
+            boolean neighborConfigReplayResult
+                    = replayNbrConfig(new ArrayList<Neighbors>(keyNeighborsMap.values()), br);
             if (neighborConfigReplayResult == false) {
                 replaySucceded = false;
             }
@@ -2420,12 +2379,13 @@ public class BgpConfigurationManager {
         } catch (Exception e) {
             LOG.error("Replay:addGr() received exception: ", e);
         }
-        List<Vrfs> vrfs = config.getVrfs();
-        if (vrfs == null) {
-            vrfs = new ArrayList<>();
+        Map<VrfsKey, Vrfs> keyVrfsMap = config.getVrfsContainer() == null ? null
+                : config.getVrfsContainer().getVrfs();
+        if (keyVrfsMap == null) {
+            keyVrfsMap = new HashMap<VrfsKey, Vrfs>();
         }
-        for (Vrfs vrf : vrfs) {
-            for (AddressFamiliesVrf adf : vrf.getAddressFamiliesVrf()) {
+        for (Vrfs vrf : keyVrfsMap.values()) {
+            for (AddressFamiliesVrf adf : vrf.getAddressFamiliesVrf().values()) {
                 try {
                     br.addVrf(BgpUtil.getLayerType(adf), vrf.getRd(), vrf.getImportRts(),
                             vrf.getExportRts(), adf.getAfi().toJava(), adf.getSafi().toJava());
@@ -2435,9 +2395,11 @@ public class BgpConfigurationManager {
             }
         }
 
-        List<Networks> ln = config.getNetworks();
-        if (ln != null) {
-            for (Networks net : ln) {
+
+        Map<NetworksKey, Networks> keyNetworksMap = config.getNetworksContainer() == null ? null
+                : config.getNetworksContainer().getNetworks();
+        if (keyNetworksMap != null) {
+            for (Networks net : keyNetworksMap.values()) {
                 String rd = net.getRd();
                 String pfxlen = net.getPrefixLen();
                 String nh = net.getNexthop().getValue();
@@ -2468,10 +2430,11 @@ public class BgpConfigurationManager {
         }
 
 
-        List<Multipath> multipaths = config.getMultipath();
+        Map<MultipathKey, Multipath> keyMultipathMap = config.getMultipathContainer() == null ? null
+                : config.getMultipathContainer().getMultipath();
 
-        if (multipaths != null) {
-            for (Multipath multipath : multipaths) {
+        if (keyMultipathMap != null) {
+            for (Multipath multipath : keyMultipathMap.values()) {
                 if (multipath != null) {
                     af_afi afi = af_afi.findByValue(multipath.getAfi().intValue());
                     af_safi safi = af_safi.findByValue(multipath.getSafi().intValue());
@@ -2483,14 +2446,15 @@ public class BgpConfigurationManager {
                             br.disableMultipath(afi, safi);
                         }
                     } catch (TException | BgpRouterException e) {
-                        LOG.info("Replay:multipaths() received exception", e);
+                        LOG.info("Replay:keyMultipathMap() received exception", e);
                     }
                 }
             }
         }
-        List<VrfMaxpath> vrfMaxpaths = config.getVrfMaxpath();
-        if (vrfMaxpaths != null) {
-            for (VrfMaxpath vrfMaxpath : vrfMaxpaths) {
+        Map<VrfMaxpathKey, VrfMaxpath> keyVrfMaxpathMap = config.getVrfMaxpathContainer() == null ? null
+                : config.getVrfMaxpathContainer().getVrfMaxpath();
+        if (keyVrfMaxpathMap != null) {
+            for (VrfMaxpath vrfMaxpath : keyVrfMaxpathMap.values()) {
                 try {
                     br.multipaths(vrfMaxpath.getRd(), vrfMaxpath.getMaxpaths().toJava());
                 } catch (TException | BgpRouterException e) {
@@ -2603,7 +2567,7 @@ public class BgpConfigurationManager {
             String nbrIp, long remoteAs, @Nullable final TcpMd5SignaturePasswordType md5Secret) {
         Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
         InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
                         .child(Neighbors.class, new NeighborsKey(nbrAddr));
         InstanceIdentifier<Neighbors> iid = iib.build();
         TcpSecurityOption tcpSecOption = null;
@@ -2619,7 +2583,7 @@ public class BgpConfigurationManager {
         Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
         Ipv4Address srcAddr = new Ipv4Address(srcIp);
         InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
                         .child(Neighbors.class, new NeighborsKey(nbrAddr))
                         .child(UpdateSource.class);
         InstanceIdentifier<UpdateSource> iid = iib.build();
@@ -2631,7 +2595,7 @@ public class BgpConfigurationManager {
     public void addEbgpMultihop(String nbrIp, int hops) {
         Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
         InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
                         .child(Neighbors.class, new NeighborsKey(nbrAddr))
                         .child(EbgpMultihop.class);
         InstanceIdentifier<EbgpMultihop> iid = iib.build();
@@ -2643,7 +2607,7 @@ public class BgpConfigurationManager {
     public void addAddressFamily(String nbrIp, int afi, int safi) {
         Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
         InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
                         .child(Neighbors.class, new NeighborsKey(nbrAddr))
                         .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
         InstanceIdentifier<AddressFamilies> iid = iib.build();
@@ -2658,6 +2622,7 @@ public class BgpConfigurationManager {
             Ipv4Address nexthop = nh != null ? new Ipv4Address(nh) : null;
             Uint32 label = lbl;
             InstanceIdentifier<Networks> iid = InstanceIdentifier.builder(Bgp.class)
+                    .child(NetworksContainer.class)
                     .child(Networks.class, new NetworksKey(pfx, rd)).build();
             NetworksBuilder networksBuilder = new NetworksBuilder().setRd(rd).setPrefixLen(pfx).setNexthop(nexthop)
                                                 .setLabel(label).setEthtag(BgpConstants.DEFAULT_ETH_TAG);
@@ -2682,7 +2647,7 @@ public class BgpConfigurationManager {
         Vrfs vrf = bgpUtil.getVrfFromRd(rd);
         List<AddressFamiliesVrf> adfList = new ArrayList<>(1);
         if (vrf != null) {
-            adfList = vrf.getAddressFamiliesVrf();
+            adfList = new ArrayList<AddressFamiliesVrf>(vrf.getAddressFamiliesVrf().values());
         }
         AddressFamiliesVrfBuilder adfBuilder = new AddressFamiliesVrfBuilder();
         if (addressFamily.equals(AddressFamily.IPV4)) {
@@ -2698,6 +2663,7 @@ public class BgpConfigurationManager {
         AddressFamiliesVrf adf = adfBuilder.build();
         adfList.add(adf);
         InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib = InstanceIdentifier.builder(Bgp.class)
+                .child(VrfsContainer.class)
                 .child(Vrfs.class, new VrfsKey(rd));
         InstanceIdentifier<Vrfs> iid = iib.build();
         Vrfs dto = new VrfsBuilder().setRd(rd).setImportRts(irts)
@@ -2797,7 +2763,7 @@ public class BgpConfigurationManager {
     public void delNeighbor(String nbrIp) {
         Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
         InstanceIdentifier.InstanceIdentifierBuilder<Neighbors> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
                         .child(Neighbors.class, new NeighborsKey(nbrAddr));
         InstanceIdentifier<Neighbors> iid = iib.build();
         delete(iid);
@@ -2806,7 +2772,7 @@ public class BgpConfigurationManager {
     public void delUpdateSource(String nbrIp) {
         Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
         InstanceIdentifier.InstanceIdentifierBuilder<UpdateSource> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
                         .child(Neighbors.class, new NeighborsKey(nbrAddr))
                         .child(UpdateSource.class);
         InstanceIdentifier<UpdateSource> iid = iib.build();
@@ -2816,7 +2782,7 @@ public class BgpConfigurationManager {
     public void delEbgpMultihop(String nbrIp) {
         Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
         InstanceIdentifier.InstanceIdentifierBuilder<EbgpMultihop> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
                         .child(Neighbors.class, new NeighborsKey(nbrAddr))
                         .child(EbgpMultihop.class);
         InstanceIdentifier<EbgpMultihop> iid = iib.build();
@@ -2826,7 +2792,7 @@ public class BgpConfigurationManager {
     public void delAddressFamily(String nbrIp, int afi, int safi) {
         Ipv4Address nbrAddr = new Ipv4Address(nbrIp);
         InstanceIdentifier.InstanceIdentifierBuilder<AddressFamilies> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(NeighborsContainer.class)
                         .child(Neighbors.class, new NeighborsKey(nbrAddr))
                         .child(AddressFamilies.class, new AddressFamiliesKey((long) afi, (long) safi));
         InstanceIdentifier<AddressFamilies> iid = iib.build();
@@ -2835,7 +2801,7 @@ public class BgpConfigurationManager {
 
     public void delPrefix(String rd, String pfx) {
         InstanceIdentifier.InstanceIdentifierBuilder<Networks> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(NetworksContainer.class)
                         .child(Networks.class, new NetworksKey(pfx, rd));
         InstanceIdentifier<Networks> iid = iib.build();
         delete(iid);
@@ -2868,20 +2834,22 @@ public class BgpConfigurationManager {
         }
 
         InstanceIdentifier.InstanceIdentifierBuilder<Vrfs> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(VrfsContainer.class)
                         .child(Vrfs.class, new VrfsKey(rd));
 
         InstanceIdentifier<Vrfs> iid = iib.build();
 
         @SuppressWarnings("static-access")
         InstanceIdentifier<Bgp> iid6 =  iid.builder(Bgp.class).build()
+                .child(MultipathContainer.class)
                 .child(Multipath.class, new MultipathKey(adfBuilder.getAfi(), adfBuilder.getSafi())).create(Bgp.class);
-        InstanceIdentifierBuilder<Vrfs> iib3 = iid6.child(Vrfs.class, new VrfsKey(rd)).builder();
+        InstanceIdentifierBuilder<Vrfs> iib3 =
+                iid6.child(VrfsContainer.class).child(Vrfs.class, new VrfsKey(rd)).builder();
         InstanceIdentifier<Vrfs> iidFinal = iib3.build();
 
         //** update or delete the vrfs with the rest of AddressFamilies already present in the last list
         AddressFamiliesVrf adfToDel = adfBuilder.build();
-        List<AddressFamiliesVrf> adfListOriginal = new ArrayList<>(vrfOriginal.nonnullAddressFamiliesVrf());
+        List<AddressFamiliesVrf> adfListOriginal = new ArrayList<>(vrfOriginal.nonnullAddressFamiliesVrf().values());
         List<AddressFamiliesVrf> adfListToRemoveFromOriginal = new ArrayList<>();
         adfListOriginal.forEach(adf -> {
             if (adf.equals(adfToDel)) {
@@ -2914,7 +2882,7 @@ public class BgpConfigurationManager {
 
         InstanceIdentifier.InstanceIdentifierBuilder<Multipath> iib =
                 InstanceIdentifier
-                        .builder(Bgp.class)
+                        .builder(Bgp.class).child(MultipathContainer.class)
                         .child(Multipath.class,
                                 new MultipathKey(Long.valueOf(afi.getValue()), Long.valueOf(safi.getValue())));
 
@@ -2925,7 +2893,7 @@ public class BgpConfigurationManager {
     public void setMultipaths(String rd, int maxpath) {
         InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
                 InstanceIdentifier
-                        .builder(Bgp.class)
+                        .builder(Bgp.class).child(VrfMaxpathContainer.class)
                         .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
 
         VrfMaxpath dto = new VrfMaxpathBuilder().setRd(rd).setMaxpaths(maxpath).build();
@@ -2934,7 +2902,7 @@ public class BgpConfigurationManager {
 
     public void delMultipaths(String rd) {
         InstanceIdentifier.InstanceIdentifierBuilder<VrfMaxpath> iib =
-                InstanceIdentifier.builder(Bgp.class)
+                InstanceIdentifier.builder(Bgp.class).child(VrfMaxpathContainer.class)
                         .child(VrfMaxpath.class, new VrfMaxpathKey(rd));
         InstanceIdentifier<VrfMaxpath> iid = iib.build();
         delete(iid);
@@ -2988,15 +2956,16 @@ public class BgpConfigurationManager {
         totalStaledCount = 0;
         try {
             staledFibEntriesMap.clear();
+            fibDSWriter.clearFibMap();
             InstanceIdentifier<FibEntries> id = InstanceIdentifier.create(FibEntries.class);
 
             Optional<FibEntries> fibEntries = SingleTransactionDataBroker.syncReadOptional(dataBroker,
                     LogicalDatastoreType.CONFIGURATION, id);
             if (fibEntries.isPresent()) {
-                List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
-                for (VrfTables vrfTable : staleVrfTables) {
+                Map<VrfTablesKey, VrfTables> staleVrfTablesMap = fibEntries.get().getVrfTables();
+                for (VrfTables vrfTable : staleVrfTablesMap.values()) {
                     Map<String, Uint32> staleFibEntMap = new HashMap<>();
-                    for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
+                    for (VrfEntry vrfEntry : vrfTable.getVrfEntry().values()) {
                         if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
                             //Stale marking and cleanup is only meant for the routes learned through BGP.
                             continue;
@@ -3005,19 +2974,25 @@ public class BgpConfigurationManager {
                             break;
                         }
                         totalStaledCount++;
-                        //Create MAP from staleVrfTables.
-                        vrfEntry.getRoutePaths()
+                        //Create MAP from staleVrfTablesMap.
+                        vrfEntry.getRoutePaths().values()
                                 .forEach(
-                                    routePath -> staleFibEntMap.put(
-                                            appendNextHopToPrefix(vrfEntry.getDestPrefix(),
-                                                    routePath.getNexthopAddress()), routePath.getLabel()));
+                                    routePath -> {
+                                        staleFibEntMap.put(
+                                                appendNextHopToPrefix(vrfEntry.getDestPrefix(),
+                                                        routePath.getNexthopAddress()), routePath.getLabel());
+                                        fibDSWriter.addEntryToFibMap(
+                                                vrfTable.getRouteDistinguisher(),  vrfEntry.getDestPrefix(),
+                                                routePath.getNexthopAddress());
+
+                                    });
                     }
                     staledFibEntriesMap.put(vrfTable.getRouteDistinguisher(), staleFibEntMap);
                 }
             } else {
                 LOG.error("createStaleFibMap:: FIBentries.class is not present");
             }
-        } catch (ReadFailedException e) {
+        } catch (InterruptedException | ExecutionException e) {
             LOG.error("createStaleFibMap:: error ", e);
         }
         LOG.error("created {} staled entries ", totalStaledCount);
@@ -3040,11 +3015,11 @@ public class BgpConfigurationManager {
                     LOG.error("deleteExternalFibRoutes::getVrfTables is null");
                     return;
                 }
-                List<VrfTables> staleVrfTables = fibEntries.get().getVrfTables();
-                for (VrfTables vrfTable : staleVrfTables) {
+                Map<VrfTablesKey, VrfTables> staleVrfTablesMap = fibEntries.get().getVrfTables();
+                for (VrfTables vrfTable : staleVrfTablesMap.values()) {
                     String rd = vrfTable.getRouteDistinguisher();
                     if (vrfTable.getVrfEntry() != null) {
-                        for (VrfEntry vrfEntry : vrfTable.getVrfEntry()) {
+                        for (VrfEntry vrfEntry : vrfTable.getVrfEntry().values()) {
                             if (RouteOrigin.value(vrfEntry.getOrigin()) != RouteOrigin.BGP) {
                                 //route cleanup is only meant for the routes learned through BGP.
                                 continue;
@@ -3053,7 +3028,7 @@ public class BgpConfigurationManager {
                             fibDSWriter.removeFibEntryFromDS(rd, vrfEntry.getDestPrefix());
                         }
                     } else if (vrfTable.getMacVrfEntry() != null) {
-                        for (MacVrfEntry macEntry : vrfTable.getMacVrfEntry()) {
+                        for (MacVrfEntry macEntry : vrfTable.getMacVrfEntry().values()) {
                             if (RouteOrigin.value(macEntry.getOrigin()) != RouteOrigin.BGP) {
                                 //route cleanup is only meant for the routes learned through BGP.
                                 continue;
@@ -3066,7 +3041,7 @@ public class BgpConfigurationManager {
             } else {
                 LOG.error("deleteExternalFibRoutes:: FIBentries.class is not present");
             }
-        } catch (ReadFailedException e) {
+        } catch (InterruptedException | ExecutionException e) {
             LOG.error("deleteExternalFibRoutes:: error ", e);
         }
         LOG.debug("deleted {} fib entries {} mac entries", totalExternalRoutes, totalExternalMacRoutes);
@@ -3156,6 +3131,10 @@ public class BgpConfigurationManager {
         return totalCleared;
     }
 
+    public static List<Neighbors> getNbrList() {
+        return nbrList;
+    }
+
     public BgpCounters getBgpCounters() {
         return bgpCountersReference.get();
     }
@@ -3238,4 +3217,67 @@ public class BgpConfigurationManager {
         }
         return md5Secret;
     } // private method extractMd5Secret
+
+    @SuppressWarnings("checkstyle:IllegalCatch")
+    @Override
+    public ListenableFuture<RpcResult<InitiateEorOutput>> initiateEor(InitiateEorInput input) {
+        boolean returnError = false;
+        String msg = null;
+        String neighborIp = null;
+        if (!isBGPEntityOwner()) {
+            msg = String.format("RPC triggered in Non-EoS Owner");
+            return Futures.immediateFuture(
+                    RpcResultBuilder.<InitiateEorOutput>failed().withError(RpcError.ErrorType.APPLICATION,
+                            msg).build());
+        }
+        if (input == null) {
+            msg = String.format("BGP invalid input for EoR");
+            LOG.error("Error : {}", msg);
+            returnError = true;
+        } else {
+            neighborIp = input.getNeighborIp();
+        }
+        if (eorSupressedDuetoUpgradeFlag.get() == false) {
+            msg = String.format("EoR triggerd by RBU-RPC call before replay"
+                    + "of BGP configuration (or) BGP not restarted");
+            LOG.error("Error : {}", msg);
+        }
+        if ("ALL".compareToIgnoreCase(neighborIp) == 0) {
+            //send EoR for all the neighbor
+            LOG.error("EoR trigger received to ALL neighbors");
+            final int numberOfEORRetries = 3;
+            RetryOnException eorRetry = new RetryOnException(numberOfEORRetries);
+            do {
+                try {
+                    BgpRouter br = bgpRouter;
+                    br.sendEOR();
+                    LOG.debug("RPC: sendEOR {} successful", br);
+                    break;
+                } catch (Exception e) {
+                    eorRetry.errorOccured();
+                    LOG.error("Replay:sedEOR() received exception:", e);
+                }
+            } while (eorRetry.shouldRetry());
+            eorSupressedDuetoUpgradeFlag.set(false);
+        } else if (InetAddresses.isInetAddress(neighborIp)) {
+            //send EoR for only one neighbor
+            msg = String.format("Inidividual neighbors EoR is not supported");
+            LOG.warn("Error : {}", msg);
+            returnError = true;
+        } else {
+            //error
+            msg = String.format("RPC: initiateEor: Invalid input ");
+            LOG.warn("Error : {}", msg);
+            returnError = true;
+        }
+        if (returnError) {
+            return Futures.immediateFuture(
+                    RpcResultBuilder.<InitiateEorOutput>failed().withError(RpcError.ErrorType.APPLICATION,
+                            msg).build());
+        }
+        InitiateEorOutput initiateEorOutput =
+                new InitiateEorOutputBuilder().setRetVal(0L).build();
+        return Futures.immediateFuture(RpcResultBuilder.<InitiateEorOutput>success()
+                .withResult(initiateEorOutput).build());
+    }
 }