Delete routes under eff-rib-in 22/70722/2
authorClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Tue, 10 Apr 2018 15:47:25 +0000 (17:47 +0200)
committerClaudio D. Gasparini <claudio.gasparini@pantheon.tech>
Wed, 11 Apr 2018 06:46:53 +0000 (08:46 +0200)
only if there are present.

Change-Id: I7c863999b54a16dec2bcaddd256c6ff7121b0cb5
Signed-off-by: Claudio D. Gasparini <claudio.gasparini@pantheon.tech>
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java
bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/EffectiveRibInWriter.java

index cfb36eb92ec2ab457e52df3f8153ea01615769a6..b68523a0e4bff6a602065eb5b1ecd9bb7b10983d 100644 (file)
@@ -159,8 +159,8 @@ public class ApplicationPeer extends BGPPeerStateImpl implements org.opendayligh
         };
         this.adjRibInWriter = this.adjRibInWriter.transform(this.peerId, context, localTables, Collections.emptyMap(),
                 registerAppPeerListener);
-        this.effectiveRibInWriter = EffectiveRibInWriter
-                .create(this, this.rib, this.rib.createPeerChain(this), this.peerIId, localTables);
+        this.effectiveRibInWriter = new EffectiveRibInWriter(this, this.rib,
+                this.rib.createPeerChain(this), this.peerIId, localTables);
         this.bgpSessionState.registerMessagesCounter(this);
         this.trackerRegistration = this.rib.getPeerTracker().registerPeer(this);
     }
index c4134249b16bc78a31b1b2537f44942c9fdaf3dd..a36e0ac398e401d99fc0dfb5a86661b7b362381a 100644 (file)
@@ -116,8 +116,6 @@ public class BGPPeer extends BGPPeerStateImpl implements BGPRouteEntryImportPara
     private final RpcProviderRegistry rpcRegistry;
     private final PeerRole peerRole;
     private InstanceIdentifier<AdjRibOut> peerRibOutIId;
-    private KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib
-            .rev180329.bgp.rib.rib.Peer, PeerKey> peerIId;
     @GuardedBy("this")
     private AbstractRegistration trackerRegistration;
     private final LoadingCache<TablesKey, KeyedInstanceIdentifier<Tables, TablesKey>> tablesIId
@@ -335,6 +333,7 @@ public class BGPPeer extends BGPPeerStateImpl implements BGPRouteEntryImportPara
         if (this.session instanceof BGPSessionStateProvider) {
             ((BGPSessionStateProvider) this.session).registerMessagesCounter(this);
         }
+
         final List<AddressFamilies> addPathTablesType = session.getAdvertisedAddPathTableTypes();
         final Set<BgpTableType> advertizedTableTypes = session.getAdvertisedTableTypes();
         final List<BgpTableType> advertizedGracefulRestartTableTypes = session.getAdvertisedGracefulRestartTableTypes();
@@ -342,14 +341,18 @@ public class BGPPeer extends BGPPeerStateImpl implements BGPRouteEntryImportPara
                 advertizedTableTypes, addPathTablesType);
         this.rawIdentifier = InetAddresses.forString(session.getBgpId().getValue()).getAddress();
         this.peerId = RouterIds.createPeerId(session.getBgpId());
-        this.peerIId = getInstanceIdentifier().child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns
+        final KeyedInstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib
+                .rev180329.bgp.rib.rib.Peer, PeerKey> peerIId =
+                getInstanceIdentifier().child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns
                 .yang.bgp.rib.rev180329.bgp.rib.rib.Peer.class, new PeerKey(this.peerId));
-        this.peerRibOutIId = this.peerIId.child(AdjRibOut.class);
-
         final Set<TablesKey> setTables = advertizedTableTypes.stream().map(t -> new TablesKey(t.getAfi(), t.getSafi()))
                 .collect(Collectors.toSet());
         this.tables = ImmutableSet.copyOf(setTables);
-
+        this.effRibInWriter = new EffectiveRibInWriter(this, this.rib, this.rib.createPeerChain(this),
+                peerIId, this.tables);
+        registerPrefixesCounters(this.effRibInWriter, this.effRibInWriter);
+        this.peerRibOutIId = peerIId.child(AdjRibOut.class);
+        this.effRibInWriter.init();
         setAdvertizedGracefulRestartTableTypes(advertizedGracefulRestartTableTypes.stream()
                 .map(t -> new TablesKey(t.getAfi(), t.getSafi())).collect(Collectors.toList()));
         this.addPathTableMaps = ImmutableMap.copyOf(mapTableTypesFamilies(addPathTablesType));
@@ -361,11 +364,6 @@ public class BGPPeer extends BGPPeerStateImpl implements BGPRouteEntryImportPara
 
         addBgp4Support();
 
-        this.effRibInWriter = EffectiveRibInWriter.create(this, this.rib, this.rib.createPeerChain(this),
-                this.peerIId, this.tables);
-
-
-        registerPrefixesCounters(this.effRibInWriter, this.effRibInWriter);
         this.ribWriter = this.ribWriter.transform(this.peerId, this.rib.getRibSupportContext(), this.tables,
                 this.addPathTableMaps);
 
index b2226d8c379efec6548266da8f6b02b6f0635ced..43359fd21c85e0ee20ba06680bcdf542a3f62274 100644 (file)
@@ -20,6 +20,7 @@ import javax.annotation.Nonnull;
 import javax.annotation.concurrent.NotThreadSafe;
 import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain;
 import org.opendaylight.controller.md.sal.binding.api.ClusteredDataTreeChangeListener;
+import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.DataObjectModification;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier;
 import org.opendaylight.controller.md.sal.binding.api.DataTreeModification;
@@ -63,262 +64,225 @@ import org.slf4j.LoggerFactory;
  * 3) output admitting routes with edited attributes into /bgp-rib/rib/peer/effective-rib-in/tables/routes
  */
 @NotThreadSafe
-final class EffectiveRibInWriter implements PrefixesReceivedCounters, PrefixesInstalledCounters, AutoCloseable {
-    static final NodeIdentifier TABLE_ROUTES = new NodeIdentifier(Routes.QNAME);
+final class EffectiveRibInWriter implements PrefixesReceivedCounters, PrefixesInstalledCounters,
+        AutoCloseable, ClusteredDataTreeChangeListener<Tables> {
+
     private static final Logger LOG = LoggerFactory.getLogger(EffectiveRibInWriter.class);
-    private final AdjInTracker adjInTracker;
+    static final NodeIdentifier TABLE_ROUTES = new NodeIdentifier(Routes.QNAME);
 
-    private EffectiveRibInWriter(final BGPRouteEntryImportParameters peer, final RIB rib,
-            final BindingTransactionChain chain,
-            final KeyedInstanceIdentifier<Peer, PeerKey> peerIId, final Set<TablesKey> tables) {
-        this.adjInTracker = new AdjInTracker(peer, rib, chain, peerIId, tables);
-    }
+    private final RIBSupportContextRegistry registry;
+    private final KeyedInstanceIdentifier<Peer, PeerKey> peerIId;
+    private final InstanceIdentifier<EffectiveRibIn> effRibTables;
+    private final DataBroker databroker;
+    private ListenerRegistration<?> reg;
+    private final BindingTransactionChain chain;
+    private final Map<TablesKey, LongAdder> prefixesReceived;
+    private final Map<TablesKey, LongAdder> prefixesInstalled;
+    private final BGPRibRoutingPolicy ribPolicies;
+    private final BGPRouteEntryImportParameters peerImportParameters;
 
-    static EffectiveRibInWriter create(final BGPRouteEntryImportParameters peer, @Nonnull final RIB rib,
-            @Nonnull final BindingTransactionChain chain,
-            @Nonnull final KeyedInstanceIdentifier<Peer, PeerKey> peerIId,
+    EffectiveRibInWriter(final BGPRouteEntryImportParameters peer, final RIB rib,
+            final BindingTransactionChain chain,
+            final KeyedInstanceIdentifier<Peer, PeerKey> peerIId,
             @Nonnull final Set<TablesKey> tables) {
-        return new EffectiveRibInWriter(peer, rib, chain, peerIId, tables);
-    }
-
-    @Override
-    public synchronized void close() {
-        this.adjInTracker.close();
+        this.registry = requireNonNull(rib.getRibSupportContext());
+        this.chain = requireNonNull(chain);
+        this.peerIId = requireNonNull(peerIId);
+        this.effRibTables = this.peerIId.child(EffectiveRibIn.class);
+        this.prefixesInstalled = buildPrefixesTables(tables);
+        this.prefixesReceived = buildPrefixesTables(tables);
+        this.ribPolicies = requireNonNull(rib.getRibPolicies());
+        this.databroker = requireNonNull(rib.getDataBroker());
+        this.peerImportParameters = peer;
     }
 
-    @Override
-    public long getPrefixedReceivedCount(final TablesKey tablesKey) {
-        return this.adjInTracker.getPrefixedReceivedCount(tablesKey);
+    @SuppressWarnings("unchecked")
+    public void init() {
+        final DataTreeIdentifier treeId = new DataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
+                this.peerIId.child(AdjRibIn.class).child(Tables.class));
+        LOG.debug("Registered Effective RIB on {}", this.peerIId);
+        this.reg = requireNonNull(this.databroker).registerDataTreeChangeListener(treeId, this);
     }
 
-    @Override
-    public Set<TablesKey> getTableKeys() {
-        return this.adjInTracker.getTableKeys();
-    }
-
-    @Override
-    public boolean isSupported(final TablesKey tablesKey) {
-        return this.adjInTracker.isSupported(tablesKey);
+    private Map<TablesKey, LongAdder> buildPrefixesTables(final Set<TablesKey> tables) {
+        final ImmutableMap.Builder<TablesKey, LongAdder> b = ImmutableMap.builder();
+        tables.forEach(table -> b.put(table, new LongAdder()));
+        return b.build();
     }
 
     @Override
-    public long getPrefixedInstalledCount(@Nonnull final TablesKey tablesKey) {
-        return this.adjInTracker.getPrefixedInstalledCount(tablesKey);
-    }
-
-    @Override
-    public long getTotalPrefixesInstalled() {
-        return this.adjInTracker.getTotalPrefixesInstalled();
-    }
-
-    private static final class AdjInTracker implements PrefixesReceivedCounters, PrefixesInstalledCounters,
-            AutoCloseable, ClusteredDataTreeChangeListener<Tables> {
-        private final RIBSupportContextRegistry registry;
-        private final KeyedInstanceIdentifier<Peer, PeerKey> peerIId;
-        private final InstanceIdentifier<EffectiveRibIn> effRibTables;
-        private final ListenerRegistration<?> reg;
-        private final BindingTransactionChain chain;
-        private final Map<TablesKey, LongAdder> prefixesReceived;
-        private final Map<TablesKey, LongAdder> prefixesInstalled;
-        private final BGPRibRoutingPolicy ribPolicies;
-        private final BGPRouteEntryImportParameters peerImportParameters;
-
-        @SuppressWarnings("unchecked")
-        AdjInTracker(final BGPRouteEntryImportParameters peer, final RIB rib,
-                final BindingTransactionChain chain,
-                final KeyedInstanceIdentifier<Peer, PeerKey> peerIId,
-                @Nonnull final Set<TablesKey> tables) {
-            this.registry = requireNonNull(rib.getRibSupportContext());
-            this.chain = requireNonNull(chain);
-            this.peerIId = requireNonNull(peerIId);
-            this.effRibTables = this.peerIId.child(EffectiveRibIn.class);
-            this.prefixesInstalled = buildPrefixesTables(tables);
-            this.prefixesReceived = buildPrefixesTables(tables);
-            this.ribPolicies = requireNonNull(rib.getRibPolicies());
-            this.peerImportParameters = peer;
-            final DataTreeIdentifier treeId = new DataTreeIdentifier(LogicalDatastoreType.OPERATIONAL,
-                    this.peerIId.child(AdjRibIn.class).child(Tables.class));
-            LOG.debug("Registered Effective RIB on {}", this.peerIId);
-            this.reg = requireNonNull(rib.getDataBroker()).registerDataTreeChangeListener(treeId, this);
-        }
-
-        private Map<TablesKey, LongAdder> buildPrefixesTables(final Set<TablesKey> tables) {
-            final ImmutableMap.Builder<TablesKey, LongAdder> b = ImmutableMap.builder();
-            tables.forEach(table -> b.put(table, new LongAdder()));
-            return b.build();
-        }
+    @SuppressWarnings("unchecked")
+    public synchronized void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<Tables>> changes) {
+        LOG.trace("Data changed called to effective RIB. Change : {}", changes);
+        WriteTransaction tx = null;
+        for (final DataTreeModification<Tables> tc : changes) {
+            final DataObjectModification<Tables> table = tc.getRootNode();
+            if (tx == null) {
+                tx = this.chain.newWriteOnlyTransaction();
+            }
+            final DataObjectModification.ModificationType modificationType = table.getModificationType();
+            switch (modificationType) {
+                case DELETE:
+                    final Tables removeTable = table.getDataBefore();
+                    final TablesKey tableKey = removeTable.getKey();
+                    final KeyedInstanceIdentifier<Tables, TablesKey> effectiveTablePath
+                            = this.effRibTables.child(Tables.class, tableKey);
+                    LOG.debug("Delete Effective Table {} modification type {}, "
+                            , effectiveTablePath, modificationType);
+                    tx.delete(LogicalDatastoreType.OPERATIONAL, effectiveTablePath);
+                    CountersUtil.decrement(this.prefixesInstalled.get(tableKey), tableKey);
+                    break;
+                case SUBTREE_MODIFIED:
+                    final Tables before = table.getDataBefore();
+                    final Tables after = table.getDataAfter();
+                    final TablesKey tk = after.getKey();
+                    LOG.debug("Process table {} type {}, dataAfter {}, dataBefore {}",
+                            tk, modificationType, after, before);
 
-        @Override
-        @SuppressWarnings("unchecked")
-        public synchronized void onDataTreeChanged(@Nonnull final Collection<DataTreeModification<Tables>> changes) {
-            LOG.trace("Data changed called to effective RIB. Change : {}", changes);
-            WriteTransaction tx = null;
-            for (final DataTreeModification<Tables> tc : changes) {
-                final DataObjectModification<Tables> table = tc.getRootNode();
-                if (tx == null) {
-                    tx = this.chain.newWriteOnlyTransaction();
-                }
-                final DataObjectModification.ModificationType modificationType = table.getModificationType();
-                switch (modificationType) {
-                    case DELETE:
-                        final Tables removeTable = table.getDataBefore();
-                        final TablesKey tableKey = removeTable.getKey();
-                        final KeyedInstanceIdentifier<Tables, TablesKey> effectiveTablePath
-                                = this.effRibTables.child(Tables.class, tableKey);
-                        LOG.debug("Delete Effective Table {} modification type {}, "
-                                , effectiveTablePath, modificationType);
-                        tx.delete(LogicalDatastoreType.OPERATIONAL, effectiveTablePath);
-                        CountersUtil.decrement(this.prefixesInstalled.get(tableKey), tableKey);
+                    final KeyedInstanceIdentifier<Tables, TablesKey> tablePath
+                            = this.effRibTables.child(Tables.class, tk);
+                    final RIBSupport ribSupport = this.registry.getRIBSupport(tk);
+                    if (ribSupport == null) {
                         break;
-                    case SUBTREE_MODIFIED:
-                        final Tables before = table.getDataBefore();
-                        final Tables after = table.getDataAfter();
-                        final TablesKey tk = after.getKey();
-                        LOG.debug("Process table {} type {}, dataAfter {}, dataBefore {}",
-                                tk, modificationType, after, before);
+                    }
+                    tx.put(LogicalDatastoreType.OPERATIONAL,
+                            tablePath.child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp
+                                    .rib.rev180329.rib.tables.Attributes.class), after.getAttributes());
 
-                        final KeyedInstanceIdentifier<Tables, TablesKey> tablePath
-                                = this.effRibTables.child(Tables.class, tk);
-                        final RIBSupport ribSupport = this.registry.getRIBSupport(tk);
-                        if (ribSupport == null) {
-                            break;
-                        }
-                        tx.put(LogicalDatastoreType.OPERATIONAL,
-                                tablePath.child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp
-                                        .rib.rev180329.rib.tables.Attributes.class), after.getAttributes());
+                    final DataObjectModification routesChangesContainer =
+                            table.getModifiedChildContainer(ribSupport.routesContainerClass());
 
-                        final DataObjectModification routesChangesContainer =
-                                table.getModifiedChildContainer(ribSupport.routesContainerClass());
-
-                        if (routesChangesContainer == null) {
-                            break;
-                        }
-                        updateRoutes(tx, tk, ribSupport, tablePath, routesChangesContainer.getModifiedChildren());
-                        break;
-                    case WRITE:
-                        writeTable(tx, table);
+                    if (routesChangesContainer == null) {
                         break;
-                    default:
-                        LOG.warn("Ignoring unhandled root {}", table);
-                        break;
-                }
-            }
-            if (tx != null) {
-                tx.submit();
+                    }
+                    updateRoutes(tx, tk, ribSupport, tablePath, routesChangesContainer.getModifiedChildren());
+                    break;
+                case WRITE:
+                    writeTable(tx, table);
+                    break;
+                default:
+                    LOG.warn("Ignoring unhandled root {}", table);
+                    break;
             }
         }
+        if (tx != null) {
+            tx.submit();
+        }
+    }
 
-        @SuppressWarnings("unchecked")
-        private void updateRoutes(
-                final WriteTransaction tx,
-                final TablesKey tableKey, final RIBSupport ribSupport,
-                final KeyedInstanceIdentifier<Tables, TablesKey> tablePath,
-                final Collection<DataObjectModification<? extends DataObject>> routeChanges) {
-            for (final DataObjectModification<? extends DataObject> routeChanged : routeChanges) {
-                final Identifier routeKey
-                        = ((InstanceIdentifier.IdentifiableItem) routeChanged.getIdentifier()).getKey();
-                switch (routeChanged.getModificationType()) {
-                    case SUBTREE_MODIFIED:
-                    case WRITE:
-                        writeRoutes(tx, tableKey, ribSupport, tablePath, routeKey, (Route) routeChanged.getDataAfter());
-                        break;
-                    case DELETE:
-                        final InstanceIdentifier routeIID = ribSupport.createRouteIdentifier(tablePath, routeKey);
-                        tx.delete(LogicalDatastoreType.OPERATIONAL, routeIID);
-                        break;
-                }
+    @SuppressWarnings("unchecked")
+    private void updateRoutes(
+            final WriteTransaction tx,
+            final TablesKey tableKey, final RIBSupport ribSupport,
+            final KeyedInstanceIdentifier<Tables, TablesKey> tablePath,
+            final Collection<DataObjectModification<? extends DataObject>> routeChanges) {
+        for (final DataObjectModification<? extends DataObject> routeChanged : routeChanges) {
+            final Identifier routeKey
+                    = ((InstanceIdentifier.IdentifiableItem) routeChanged.getIdentifier()).getKey();
+            switch (routeChanged.getModificationType()) {
+                case SUBTREE_MODIFIED:
+                case WRITE:
+                    writeRoutes(tx, tableKey, ribSupport, tablePath, routeKey, (Route) routeChanged.getDataAfter());
+                    break;
+                case DELETE:
+                    final InstanceIdentifier routeIID = ribSupport.createRouteIdentifier(tablePath, routeKey);
+                    tx.delete(LogicalDatastoreType.OPERATIONAL, routeIID);
+                    break;
             }
         }
+    }
 
-        @SuppressWarnings("unchecked")
-        private void writeRoutes(final WriteTransaction tx, final TablesKey tk, final RIBSupport ribSupport,
-                final KeyedInstanceIdentifier<Tables, TablesKey> tablePath, final Identifier routeKey,
-                final Route route) {
-            final InstanceIdentifier routeIID = ribSupport.createRouteIdentifier(tablePath, routeKey);
-            CountersUtil.increment(this.prefixesReceived.get(tk), tk);
-            final Optional<Attributes> effAtt = this.ribPolicies
-                    .applyImportPolicies(this.peerImportParameters, route.getAttributes());
-            if (effAtt.isPresent()) {
-                CountersUtil.increment(this.prefixesInstalled.get(tk), tk);
-                tx.put(LogicalDatastoreType.OPERATIONAL, routeIID, route);
-                tx.put(LogicalDatastoreType.OPERATIONAL, routeIID.child(Attributes.class), effAtt.get());
-            } else {
-                tx.delete(LogicalDatastoreType.OPERATIONAL, routeIID);
-            }
+    @SuppressWarnings("unchecked")
+    private void writeRoutes(final WriteTransaction tx, final TablesKey tk, final RIBSupport ribSupport,
+            final KeyedInstanceIdentifier<Tables, TablesKey> tablePath, final Identifier routeKey,
+            final Route route) {
+        final InstanceIdentifier routeIID = ribSupport.createRouteIdentifier(tablePath, routeKey);
+        CountersUtil.increment(this.prefixesReceived.get(tk), tk);
+        final Optional<Attributes> effAtt = this.ribPolicies
+                .applyImportPolicies(this.peerImportParameters, route.getAttributes());
+        if (effAtt.isPresent()) {
+            CountersUtil.increment(this.prefixesInstalled.get(tk), tk);
+            tx.put(LogicalDatastoreType.OPERATIONAL, routeIID, route);
+            tx.put(LogicalDatastoreType.OPERATIONAL, routeIID.child(Attributes.class), effAtt.get());
+        } else {
+            tx.delete(LogicalDatastoreType.OPERATIONAL, routeIID);
         }
+    }
 
-        @SuppressWarnings("unchecked")
-        private void writeTable(final WriteTransaction tx, final DataObjectModification<Tables> table) {
-            final Tables newTable = table.getDataAfter();
-            if (newTable == null) {
-                return;
-            }
-            final TablesKey tableKey = newTable.getKey();
-            final KeyedInstanceIdentifier<Tables, TablesKey> tablePath
-                    = this.effRibTables.child(Tables.class, tableKey);
+    @SuppressWarnings("unchecked")
+    private void writeTable(final WriteTransaction tx, final DataObjectModification<Tables> table) {
+        final Tables newTable = table.getDataAfter();
+        if (newTable == null) {
+            return;
+        }
+        final TablesKey tableKey = newTable.getKey();
+        final KeyedInstanceIdentifier<Tables, TablesKey> tablePath
+                = this.effRibTables.child(Tables.class, tableKey);
 
-            // Create an empty table
-            LOG.trace("Create Empty table", tablePath);
-            if (table.getDataBefore() == null) {
-                tx.put(LogicalDatastoreType.OPERATIONAL, tablePath, new TablesBuilder()
-                        .setAfi(tableKey.getAfi()).setSafi(tableKey.getSafi())
-                        .setRoutes(this.registry.getRIBSupport(tableKey).emptyRoutesContainer())
-                        .setAttributes(newTable.getAttributes()).build());
-            }
+        // Create an empty table
+        LOG.trace("Create Empty table", tablePath);
+        if (table.getDataBefore() == null) {
+            tx.put(LogicalDatastoreType.OPERATIONAL, tablePath, new TablesBuilder()
+                    .setAfi(tableKey.getAfi()).setSafi(tableKey.getSafi())
+                    .setRoutes(this.registry.getRIBSupport(tableKey).emptyRoutesContainer())
+                    .setAttributes(newTable.getAttributes()).build());
+        }
 
-            final RIBSupport ribSupport = this.registry.getRIBSupport(tableKey);
-            final Routes routes = newTable.getRoutes();
-            if (ribSupport == null || routes == null) {
-                return;
-            }
+        final RIBSupport ribSupport = this.registry.getRIBSupport(tableKey);
+        final Routes routes = newTable.getRoutes();
+        if (ribSupport == null || routes == null) {
+            return;
+        }
 
-            final DataObjectModification routesChangesContainer =
-                    table.getModifiedChildContainer(ribSupport.routesContainerClass());
+        final DataObjectModification routesChangesContainer =
+                table.getModifiedChildContainer(ribSupport.routesContainerClass());
 
-            if (routesChangesContainer == null) {
-                return;
-            }
-            updateRoutes(tx, tableKey, ribSupport, tablePath, routesChangesContainer.getModifiedChildren());
+        if (routesChangesContainer == null) {
+            return;
         }
+        updateRoutes(tx, tableKey, ribSupport, tablePath, routesChangesContainer.getModifiedChildren());
+    }
 
-        @Override
-        public synchronized void close() {
+    @Override
+    public synchronized void close() {
+        if (this.reg != null) {
             this.reg.close();
-            this.prefixesReceived.values().forEach(LongAdder::reset);
-            this.prefixesInstalled.values().forEach(LongAdder::reset);
+            this.reg = null;
         }
+        this.prefixesReceived.values().forEach(LongAdder::reset);
+        this.prefixesInstalled.values().forEach(LongAdder::reset);
+    }
 
-        @Override
-        public long getPrefixedReceivedCount(final TablesKey tablesKey) {
-            final LongAdder counter = this.prefixesReceived.get(tablesKey);
-            if (counter == null) {
-                return 0;
-            }
-            return counter.longValue();
+    @Override
+    public long getPrefixedReceivedCount(final TablesKey tablesKey) {
+        final LongAdder counter = this.prefixesReceived.get(tablesKey);
+        if (counter == null) {
+            return 0;
         }
+        return counter.longValue();
+    }
 
-        @Override
-        public Set<TablesKey> getTableKeys() {
-            return ImmutableSet.copyOf(this.prefixesReceived.keySet());
-        }
+    @Override
+    public Set<TablesKey> getTableKeys() {
+        return ImmutableSet.copyOf(this.prefixesReceived.keySet());
+    }
 
-        @Override
-        public boolean isSupported(final TablesKey tablesKey) {
-            return this.prefixesReceived.containsKey(tablesKey);
-        }
+    @Override
+    public boolean isSupported(final TablesKey tablesKey) {
+        return this.prefixesReceived.containsKey(tablesKey);
+    }
 
-        @Override
-        public long getPrefixedInstalledCount(final TablesKey tablesKey) {
-            final LongAdder counter = this.prefixesInstalled.get(tablesKey);
-            if (counter == null) {
-                return 0;
-            }
-            return counter.longValue();
+    @Override
+    public long getPrefixedInstalledCount(final TablesKey tablesKey) {
+        final LongAdder counter = this.prefixesInstalled.get(tablesKey);
+        if (counter == null) {
+            return 0;
         }
+        return counter.longValue();
+    }
 
-        @Override
-        public long getTotalPrefixesInstalled() {
-            return this.prefixesInstalled.values().stream().mapToLong(LongAdder::longValue).sum();
-        }
+    @Override
+    public long getTotalPrefixesInstalled() {
+        return this.prefixesInstalled.values().stream().mapToLong(LongAdder::longValue).sum();
     }
 }