BGPCEP-672: Fix key storage un adj-rib-out 24/67424/4
authorClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Sat, 20 Jan 2018 12:08:18 +0000 (13:08 +0100)
committerClaudio David Gasparini <claudio.gasparini@pantheon.tech>
Sun, 25 Feb 2018 11:41:29 +0000 (11:41 +0000)
list key must not be null, therefore
path-id should always be included.
Reserving PATH-ID 0 for non-supporting
add-path.

Change-Id: I9b0af92e91e7c0b1c7281230a804c7adeff2dbca
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@pantheon.tech>
bgp/config-loader-impl/src/main/java/org/opendaylight/protocol/bgp/config/loader/impl/ConfigLoaderImpl.java
bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/add/AddPathAbstractRouteEntry.java
bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/impl/base/BaseAbstractRouteEntry.java
bgp/path-selection-mode/src/main/java/org/opendaylight/protocol/bgp/mode/spi/AbstractRouteEntry.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/LocRibWriter.java

index ddfd80e0aba38a349ed72e1930430d4ee2dd81b2..a9e2f8cc7967df347f531b6b46b2bb0aaec41347 100644 (file)
@@ -8,10 +8,14 @@
 
 package org.opendaylight.protocol.bgp.config.loader.impl;
 
-import com.google.common.base.Preconditions;
+import static java.util.Objects.requireNonNull;
+
 import java.io.File;
 import java.io.FileInputStream;
+import java.io.IOException;
 import java.io.InputStream;
+import java.net.URISyntaxException;
+import java.nio.file.ClosedWatchServiceException;
 import java.nio.file.WatchEvent;
 import java.nio.file.WatchKey;
 import java.nio.file.WatchService;
@@ -19,7 +23,9 @@ import java.util.HashMap;
 import java.util.Map;
 import java.util.regex.Pattern;
 import javax.annotation.concurrent.GuardedBy;
+import javax.xml.parsers.ParserConfigurationException;
 import javax.xml.stream.XMLInputFactory;
+import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamReader;
 import org.opendaylight.mdsal.binding.dom.codec.api.BindingNormalizedNodeSerializer;
 import org.opendaylight.protocol.bgp.config.loader.spi.ConfigFileProcessor;
@@ -35,6 +41,8 @@ import org.opendaylight.yangtools.yang.model.api.SchemaNode;
 import org.opendaylight.yangtools.yang.model.util.SchemaContextUtil;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.xml.sax.SAXException;
+
 public final class ConfigLoaderImpl implements ConfigLoader, AutoCloseable {
     private static final Logger LOG = LoggerFactory.getLogger(ConfigLoaderImpl.class);
     private static final String INTERRUPTED = "InterruptedException";
@@ -46,36 +54,16 @@ public final class ConfigLoaderImpl implements ConfigLoader, AutoCloseable {
     private final BindingNormalizedNodeSerializer bindingSerializer;
     private final String path;
     private final Thread watcherThread;
+    @GuardedBy("this")
+    private boolean closed = false;
 
     public ConfigLoaderImpl(final SchemaContext schemaContext, final BindingNormalizedNodeSerializer bindingSerializer,
-        final String path, final WatchService watchService) {
-        this.schemaContext = Preconditions.checkNotNull(schemaContext);
-        this.bindingSerializer = Preconditions.checkNotNull(bindingSerializer);
-        this.path = Preconditions.checkNotNull(path);
-        Preconditions.checkNotNull(watchService);
-        this.watcherThread = new Thread(() -> {
-            try {
-                while (!Thread.currentThread().isInterrupted()) {
-                    try {
-                        final WatchKey key = watchService.take();
-                        if (key != null) {
-                            for (final WatchEvent event : key.pollEvents()) {
-                                handleEvent(event.context().toString());
-                            }
-                            final boolean reset = key.reset();
-                            if (!reset) {
-                                LOG.warn("Could not reset the watch key.");
-                                return;
-                            }
-                        }
-                    } catch (final InterruptedException e) {
-                        LOG.warn(INTERRUPTED, e);
-                    }
-                }
-            } catch (final Exception e) {
-                LOG.warn(INTERRUPTED, e);
-            }
-        });
+            final String path, final WatchService watchService) {
+        this.schemaContext = requireNonNull(schemaContext);
+        this.bindingSerializer = requireNonNull(bindingSerializer);
+        this.path = requireNonNull(path);
+        requireNonNull(watchService);
+        this.watcherThread = new Thread(new ConfigLoaderImplRunnable(watchService));
         this.watcherThread.start();
         LOG.info("Config Loader service initiated");
     }
@@ -84,7 +72,8 @@ public final class ConfigLoaderImpl implements ConfigLoader, AutoCloseable {
         final NormalizedNode<?, ?> dto;
         try {
             dto = parseDefaultConfigFile(config, filename);
-        } catch (final Exception e) {
+        } catch (final IOException | XMLStreamException | ParserConfigurationException | SAXException
+                | URISyntaxException e) {
             LOG.warn("Failed to parse config file {}", filename, e);
             return;
         }
@@ -92,7 +81,8 @@ public final class ConfigLoaderImpl implements ConfigLoader, AutoCloseable {
         config.loadConfiguration(dto);
     }
 
-    private NormalizedNode<?, ?> parseDefaultConfigFile(final ConfigFileProcessor config, final String filename) throws Exception {
+    private NormalizedNode<?, ?> parseDefaultConfigFile(final ConfigFileProcessor config, final String filename)
+            throws IOException, XMLStreamException, ParserConfigurationException, SAXException, URISyntaxException {
         final NormalizedNodeResult result = new NormalizedNodeResult();
         final NormalizedNodeStreamWriter streamWriter = ImmutableNormalizedNodeStreamWriter.from(result);
 
@@ -139,13 +129,56 @@ public final class ConfigLoaderImpl implements ConfigLoader, AutoCloseable {
         return this.bindingSerializer;
     }
 
-    private synchronized void handleEvent(final String filename) {
-        this.configServices.entrySet().stream().filter(entry -> Pattern.matches(entry.getKey(), filename)).
-            forEach(entry -> handleConfigFile(entry.getValue(), filename));
-    }
 
     @Override
-    public void close() throws Exception {
+    public synchronized void close() throws Exception {
+        LOG.info("Config Loader service closed");
+        this.closed = true;
         this.watcherThread.interrupt();
     }
-}
+
+    private class ConfigLoaderImplRunnable implements Runnable {
+        @GuardedBy("this")
+        private final WatchService watchService;
+
+        ConfigLoaderImplRunnable(final WatchService watchService) {
+            this.watchService = watchService;
+        }
+
+        @Override
+        public void run() {
+            while (!Thread.currentThread().isInterrupted()) {
+                handleChanges();
+            }
+        }
+
+        private synchronized void handleChanges() {
+            final WatchKey key;
+            try {
+                key = this.watchService.take();
+            } catch (final InterruptedException | ClosedWatchServiceException e) {
+                if (!ConfigLoaderImpl.this.closed) {
+                    LOG.warn(INTERRUPTED, e);
+                    Thread.currentThread().interrupt();
+                }
+                return;
+            }
+
+            if (key != null) {
+                for (final WatchEvent<?> event : key.pollEvents()) {
+                    handleEvent(event.context().toString());
+                }
+                final boolean reset = key.reset();
+                if (!reset) {
+                    LOG.warn("Could not reset the watch key.");
+                }
+            }
+        }
+
+        private synchronized void handleEvent(final String filename) {
+            ConfigLoaderImpl.this.configServices.entrySet().stream()
+                    .filter(entry -> Pattern.matches(entry.getKey(), filename))
+                    .forEach(entry -> handleConfigFile(entry.getValue(), filename));
+        }
+    }
+}
\ No newline at end of file
index c422037b7755859d53b0362b2b68ac0204554403..d9483fe35c5e9b7b800cb731bcbdf8c4198a6e9b 100644 (file)
@@ -7,6 +7,8 @@
  */
 package org.opendaylight.protocol.bgp.mode.impl.add;
 
+import static org.opendaylight.protocol.bgp.parser.spi.PathIdUtil.NON_PATH_ID;
+
 import com.google.common.collect.Lists;
 import com.google.common.primitives.UnsignedInteger;
 import java.util.ArrayList;
@@ -128,8 +130,10 @@ public abstract class AddPathAbstractRouteEntry extends AbstractRouteEntry {
         if(this.removedPaths != null) {
             this.removedPaths.forEach(removedPath -> {
                 final PathArgument routeIdAddPath = ribSupport.getRouteIdAddPath(removedPath.getPathId(), routeIdPA);
-                fillAdjRibsOut(true, null, null, null, routeIdPA, routeIdAddPath, RouterIds.createPeerId(removedPath.getRouteId()),
-                    peerPT, localTK, ribSupport, tx);
+                final PathArgument routeIdAddPathDefault = ribSupport.getRouteIdAddPath(NON_PATH_ID, routeIdPA);
+                fillAdjRibsOut(true, null, null, null,
+                        routeIdAddPathDefault, routeIdAddPath,
+                        RouterIds.createPeerId(removedPath.getRouteId()), peerPT, localTK, ribSupport, tx);
             });
             this.removedPaths = null;
         }
@@ -156,30 +160,38 @@ public abstract class AddPathAbstractRouteEntry extends AbstractRouteEntry {
     private void writeRoutePath(final PeerId destPeer, final PathArgument routeId, final ExportPolicyPeerTracker peerPT,
         final PeerExportGroup peerGroup, final boolean destPeerSupAddPath,
         final BestPath path, final YangInstanceIdentifier rootPath, final TablesKey localTK, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
-        final PathArgument routeIdAddPath = ribSup.getRouteIdAddPath(path.getPathId(), routeId);
         final ContainerNode effectiveAttributes = peerGroup.effectiveAttributes(getRoutePeerIdRole(peerPT,path.getPeerId()), path.getAttributes());
+        PathArgument routeIdAddPath;
         if (destPeerSupAddPath) {
-            writeRoute(destPeer, getAdjRibOutYII(ribSup, rootPath, routeIdAddPath, localTK), effectiveAttributes, createValue(routeIdAddPath, path), ribSup, tx);
+            routeIdAddPath = ribSup.getRouteIdAddPath(path.getPathId(), routeId);
         } else {
-            writeRoute(destPeer, getAdjRibOutYII(ribSup, rootPath, routeId, localTK), effectiveAttributes, createValue(routeId, path), ribSup, tx);
+            routeIdAddPath = ribSup.getRouteIdAddPath(NON_PATH_ID, routeId);
         }
+        writeRoute(destPeer, getAdjRibOutYII(ribSup, rootPath, routeIdAddPath, localTK), effectiveAttributes,
+                createValue(routeIdAddPath, path), ribSup, tx);
     }
 
-    private void addPathToDataStore(final BestPath path, final boolean isFirstBestPath, final PathArgument routeIdPA, final YangInstanceIdentifier locRibTarget,
-        final RIBSupport ribSup, final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final DOMDataWriteTransaction tx) {
+    private void addPathToDataStore(final BestPath path, final boolean isFirstBestPath, final PathArgument routeIdPA,
+            final YangInstanceIdentifier locRibTarget, final RIBSupport ribSup, final ExportPolicyPeerTracker peerPT,
+            final TablesKey localTK, final DOMDataWriteTransaction tx) {
         final PathArgument routeIdAddPath = ribSup.getRouteIdAddPath(path.getPathId(), routeIdPA);
-        final YangInstanceIdentifier pathAddPathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdAddPath);
+        final PathArgument routeIdAddPathDefault = ribSup.getRouteIdAddPath(NON_PATH_ID, routeIdPA);
+        final YangInstanceIdentifier pathAddPathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER),
+                routeIdAddPath);
+
         final MapEntryNode addPathValue = createValue(routeIdAddPath, path);
-        final MapEntryNode value = createValue(routeIdPA, path);
+        final MapEntryNode defaultValue = createValue(routeIdAddPathDefault, path);
         LOG.trace("Selected best value {}", addPathValue);
         fillLocRib(pathAddPathTarget, addPathValue, tx);
-        fillAdjRibsOut(isFirstBestPath, path.getAttributes(), value, addPathValue, routeIdPA, routeIdAddPath, path.getPeerId(), peerPT, localTK,
-            ribSup, tx);
+        fillAdjRibsOut(isFirstBestPath, path.getAttributes(), defaultValue, addPathValue, routeIdAddPathDefault,
+                routeIdAddPath, path.getPeerId(), peerPT, localTK, ribSup, tx);
     }
 
-    private void fillAdjRibsOut(final boolean isFirstBestPath, final ContainerNode attributes, final NormalizedNode<?, ?> value, final MapEntryNode addPathValue,
-        final PathArgument routeId, final PathArgument routeIdAddPath, final PeerId routePeerId, final ExportPolicyPeerTracker peerPT, final TablesKey
-        localTK, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
+    private void fillAdjRibsOut(final boolean isFirstBestPath, final ContainerNode attributes,
+            final MapEntryNode defaultValue, final MapEntryNode addPathValue,
+            final PathArgument routeIdAddPathDefault,
+            final PathArgument routeIdAddPath, final PeerId routePeerId, final ExportPolicyPeerTracker peerPT,
+            final TablesKey localTK, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
         /*
          * We need to keep track of routers and populate adj-ribs-out, too. If we do not, we need to
          * expose from which client a particular route was learned from in the local RIB, and have
@@ -201,7 +213,7 @@ public abstract class AddPathAbstractRouteEntry extends AbstractRouteEntry {
                             update(destPeer, getAdjRibOutYII(ribSup, rootPath, routeIdAddPath, localTK), effectiveAttributes,
                                 addPathValue, ribSup, tx);
                         } else if(!this.oldNonAddPathBestPathTheSame){
-                            update(destPeer, getAdjRibOutYII(ribSup, rootPath, routeId, localTK), effectiveAttributes, value, ribSup, tx);
+                            update(destPeer, getAdjRibOutYII(ribSup, rootPath, routeIdAddPathDefault, localTK), effectiveAttributes, defaultValue, ribSup, tx);
                         }
                     }
                 });
index 3f87a4d6afc0a9ecec6b6a180fa13e030a2db1af..640807eced6d76cdb975daae3bef644a0c014d8d 100644 (file)
@@ -23,6 +23,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.PathArgument;
 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
+import org.opendaylight.yangtools.yang.data.api.schema.MapEntryNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNode;
 import org.opendaylight.yangtools.yang.data.api.schema.NormalizedNodes;
 import org.slf4j.Logger;
@@ -84,7 +85,7 @@ abstract class BaseAbstractRouteEntry extends AbstractRouteEntry {
         final BaseBestPath newBestPath = selector.result();
         final boolean modified = newBestPath == null || !newBestPath.equals(this.bestPath);
         if (modified) {
-            if(this.offsets.isEmpty()) {
+            if (this.offsets.isEmpty()) {
                 this.removedBestPath = this.bestPath;
             }
             LOG.trace("Previous best {}, current best {}", this.bestPath, newBestPath);
@@ -119,9 +120,13 @@ abstract class BaseAbstractRouteEntry extends AbstractRouteEntry {
             final BaseBestPath path = this.bestPath;
             final PeerRole destPeerRole = getRoutePeerIdRole(peerPT, destPeer);
             if (filterRoutes(path.getPeerId(), destPeer, peerPT, localTK, destPeerRole)) {
-                final ContainerNode effAttrib = peerGroup.effectiveAttributes(getRoutePeerIdRole(peerPT,path.getPeerId()), path.getAttributes());
-                writeRoute(destPeer, getAdjRibOutYII(ribSupport, rootPath, routeId, localTK), effAttrib,
-                    createValue(routeId, path), ribSupport, tx);
+                PathArgument routeIdDest = ribSupport.getRouteIdAddPath(path.getPathId(), routeId);
+                if (routeIdDest == null) {
+                    routeIdDest = routeId;
+                }
+                final ContainerNode effAttrib = peerGroup.effectiveAttributes(getRoutePeerIdRole(peerPT, path.getPeerId()), path.getAttributes());
+                writeRoute(destPeer, getAdjRibOutYII(ribSupport, rootPath, routeIdDest, localTK), effAttrib,
+                        createValue(routeIdDest, path), ribSupport, tx);
             }
         }
     }
@@ -129,32 +134,28 @@ abstract class BaseAbstractRouteEntry extends AbstractRouteEntry {
     private void removePathFromDataStore(final BestPath path, final PathArgument routeIdPA, final YangInstanceIdentifier locRibTarget,
         final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
         LOG.trace("Best Path removed {}", path);
-        final PathArgument routeIdAddPath = ribSup.getRouteIdAddPath(path.getPathId(), routeIdPA);
-        final YangInstanceIdentifier pathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdPA);
-        YangInstanceIdentifier pathAddPathTarget = null;
-        if (routeIdAddPath != null) {
-            pathAddPathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdAddPath);
+        PathArgument routeIdTarget = ribSup.getRouteIdAddPath(path.getPathId(), routeIdPA);
+        if (routeIdTarget == null) {
+            routeIdTarget = routeIdPA;
         }
-        fillLocRib(pathAddPathTarget == null ? pathTarget : pathAddPathTarget, null, tx);
-        fillAdjRibsOut(null, null, routeIdPA, path.getPeerId(), peerPT, localTK, ribSup, tx);
+
+        fillLocRib(ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdTarget), null, tx);
+        fillAdjRibsOut(null, null, routeIdTarget, path.getPeerId(), peerPT, localTK, ribSup, tx);
     }
 
     private void addPathToDataStore(final BestPath path, final PathArgument routeIdPA, final YangInstanceIdentifier locRibTarget,
         final RIBSupport ribSup, final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final DOMDataWriteTransaction tx) {
-        final PathArgument routeIdAddPath = ribSup.getRouteIdAddPath(path.getPathId(), routeIdPA);
-        final YangInstanceIdentifier pathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdPA);
-        final NormalizedNode<?, ?> value = createValue(routeIdPA, path);
-        NormalizedNode<?, ?> addPathValue = null;
-        YangInstanceIdentifier pathAddPathTarget = null;
-        if (routeIdAddPath == null) {
-            LOG.trace("Selected best value {}", value);
-        } else {
-            pathAddPathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdAddPath);
-            addPathValue = createValue(routeIdAddPath, path);
-            LOG.trace("Selected best value {}", addPathValue);
+        PathArgument routeIdDest = ribSup.getRouteIdAddPath(path.getPathId(), routeIdPA);
+        if (routeIdDest == null) {
+            routeIdDest = routeIdPA;
         }
-        fillLocRib(pathAddPathTarget == null ? pathTarget : pathAddPathTarget, addPathValue == null ? value : addPathValue, tx);
-        fillAdjRibsOut(path.getAttributes(), value, routeIdPA, path.getPeerId(), peerPT, localTK, ribSup, tx);
+
+        final MapEntryNode value = createValue(routeIdDest, path);
+        LOG.trace("Selected best value {}", value);
+
+        final YangInstanceIdentifier pathAddPathTarget = ribSup.routePath(locRibTarget.node(ROUTES_IDENTIFIER), routeIdDest);
+        fillLocRib( pathAddPathTarget, value, tx);
+        fillAdjRibsOut(path.getAttributes(), value, routeIdDest, path.getPeerId(), peerPT, localTK, ribSup, tx);
     }
 
     final OffsetMap getOffsets() {
@@ -162,9 +163,9 @@ abstract class BaseAbstractRouteEntry extends AbstractRouteEntry {
     }
 
     @VisibleForTesting
-    private void fillAdjRibsOut(final ContainerNode attributes, final NormalizedNode<?, ?> value,
-        final PathArgument routeId, final PeerId routePeerId, final ExportPolicyPeerTracker peerPT,
-        final TablesKey localTK, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
+    private void fillAdjRibsOut(final ContainerNode attributes, final MapEntryNode value,
+            final PathArgument routeId, final PeerId routePeerId, final ExportPolicyPeerTracker peerPT,
+            final TablesKey localTK, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
         /*
          * We need to keep track of routers and populate adj-ribs-out, too. If we do not, we need to
          * expose from which client a particular route was learned from in the local RIB, and have
index 48485bd2fdae28462fc9f2b473073955f14a2e43..864a6e96aa25268cf1c0802fb4caa8d793b42c87 100644 (file)
@@ -33,7 +33,8 @@ public abstract class AbstractRouteEntry implements RouteEntry {
     protected static final NodeIdentifier ROUTES_IDENTIFIER = new NodeIdentifier(Routes.QNAME);
     private static final Logger LOG = LoggerFactory.getLogger(AbstractRouteEntry.class);
 
-    protected final void fillLocRib(final YangInstanceIdentifier routeTarget, final NormalizedNode<?, ?> value, final DOMDataWriteTransaction tx) {
+    protected static void fillLocRib(final YangInstanceIdentifier routeTarget, final NormalizedNode<?, ?> value,
+            final DOMDataWriteTransaction tx) {
         if (value != null) {
             LOG.debug("Write route to LocRib {}", value);
             tx.put(LogicalDatastoreType.OPERATIONAL, routeTarget, value);
@@ -43,16 +44,17 @@ public abstract class AbstractRouteEntry implements RouteEntry {
         }
     }
 
-
-    protected final void update(final PeerId destPeer, final YangInstanceIdentifier routeTarget, final ContainerNode effAttr,
-        final NormalizedNode<?, ?> value, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
+    protected static void update(final PeerId destPeer, final YangInstanceIdentifier routeTarget,
+            final ContainerNode effAttr, final NormalizedNode<?, ?> value, final RIBSupport ribSup,
+            final DOMDataWriteTransaction tx) {
         if (!writeRoute(destPeer, routeTarget, effAttr, value, ribSup, tx)) {
             deleteRoute(destPeer, routeTarget, tx);
         }
     }
 
-    protected final boolean writeRoute(final PeerId destPeer, final YangInstanceIdentifier routeTarget, final ContainerNode effAttrib,
-        final NormalizedNode<?, ?> value, final RIBSupport ribSup, final DOMDataWriteTransaction tx) {
+    protected static boolean writeRoute(final PeerId destPeer, final YangInstanceIdentifier routeTarget,
+            final ContainerNode effAttrib, final NormalizedNode<?, ?> value, final RIBSupport ribSup,
+            final DOMDataWriteTransaction tx) {
         if (effAttrib != null && value != null) {
             LOG.debug("Write route {} to peer AdjRibsOut {}", value, destPeer);
             tx.put(LogicalDatastoreType.OPERATIONAL, routeTarget, value);
@@ -62,16 +64,18 @@ public abstract class AbstractRouteEntry implements RouteEntry {
         return false;
     }
 
-    private void deleteRoute(final PeerId destPeer, final YangInstanceIdentifier routeTarget, final DOMDataWriteTransaction tx) {
+    private static void deleteRoute(final PeerId destPeer, final YangInstanceIdentifier routeTarget,
+            final DOMDataWriteTransaction tx) {
         LOG.trace("Removing {} from transaction for peer {}", routeTarget, destPeer);
         tx.delete(LogicalDatastoreType.OPERATIONAL, routeTarget);
     }
 
-    protected final boolean filterRoutes(final PeerId rootPeer, final PeerId destPeer, final ExportPolicyPeerTracker peerPT,        final TablesKey localTK, final PeerRole destPeerRole) {
+    protected static boolean filterRoutes(final PeerId rootPeer, final PeerId destPeer,
+            final ExportPolicyPeerTracker peerPT, final TablesKey localTK, final PeerRole destPeerRole) {
         return !rootPeer.equals(destPeer) && isTableSupportedAndReady(destPeer, peerPT, localTK) && !PeerRole.Internal.equals(destPeerRole);
     }
 
-    private boolean isTableSupportedAndReady(final PeerId destPeer, final ExportPolicyPeerTracker peerPT, final TablesKey localTK) {
+    private static boolean isTableSupportedAndReady(final PeerId destPeer, final ExportPolicyPeerTracker peerPT, final TablesKey localTK) {
         if (!peerPT.isTableSupported(destPeer) || !peerPT.isTableStructureInitialized(destPeer)) {
             LOG.trace("Route rejected, peer {} does not support this table type {}", destPeer, localTK);
             return false;
@@ -79,16 +83,16 @@ public abstract class AbstractRouteEntry implements RouteEntry {
         return true;
     }
 
-    protected final YangInstanceIdentifier getAdjRibOutYII(final RIBSupport ribSup, final YangInstanceIdentifier rootPath, final PathArgument routeId,
-        final TablesKey localTK) {
+    protected static YangInstanceIdentifier getAdjRibOutYII(final RIBSupport ribSup,
+            final YangInstanceIdentifier rootPath, final PathArgument routeId, final TablesKey localTK) {
         return ribSup.routePath(rootPath.node(AdjRibOut.QNAME).node(Tables.QNAME).node(RibSupportUtils.toYangTablesKey(localTK))
             .node(ROUTES_IDENTIFIER), routeId);
     }
 
-    protected PeerRole getRoutePeerIdRole(final ExportPolicyPeerTracker peerPT, final PeerId routePeerId) {
+    protected static PeerRole getRoutePeerIdRole(final ExportPolicyPeerTracker peerPT, final PeerId routePeerId) {
         for (final PeerRole role : PeerRole.values()) {
             final PeerExportGroup peerGroup = peerPT.getPeerGroup(role);
-            if(peerGroup != null && peerGroup.containsPeer(routePeerId)) {
+            if (peerGroup != null && peerGroup.containsPeer(routePeerId)) {
                 return role;
             }
         }
index 3fcd3ab39a60a60c327c290ee10d4156d534a610..fb74bd4623156a20e25c70733850e34b18fb0a9e 100644 (file)
@@ -192,6 +192,9 @@ final class LocRibWriter implements AutoCloseable, TotalPrefixesCounter, TotalPa
         if (!table.getDataBefore().isPresent() && this.exportPolicyPeerTracker.isTableSupported(peerIdOfNewPeer)) {
             this.exportPolicyPeerTracker.registerPeerAsInitialized(peerIdOfNewPeer);
             LOG.debug("Peer {} table has been created, inserting existent routes", peerIdOfNewPeer);
+            if (this.routeEntries.isEmpty()) {
+                return;
+            }
             final PeerRole newPeerRole = this.exportPolicyPeerTracker.getRole(IdentifierUtils.peerPath(rootPath));
             final PeerExportGroup peerGroup = this.exportPolicyPeerTracker.getPeerGroup(newPeerRole);
             this.routeEntries.entrySet().forEach(entry -> entry.getValue().writeRoute(peerIdOfNewPeer, entry.getKey(),