From: Claudio D. Gasparini Date: Tue, 10 Apr 2018 15:47:25 +0000 (+0200) Subject: Delete routes under eff-rib-in X-Git-Tag: release/fluorine~132 X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=commitdiff_plain;h=3a31aa1e46b39f24bf07a88fe1816666d18adcda;p=bgpcep.git Delete routes under eff-rib-in only if there are present. Change-Id: I7c863999b54a16dec2bcaddd256c6ff7121b0cb5 Signed-off-by: Claudio D. Gasparini --- diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java index cfb36eb92e..b68523a0e4 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ApplicationPeer.java @@ -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); } diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java index c4134249b1..a36e0ac398 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPPeer.java @@ -116,8 +116,6 @@ public class BGPPeer extends BGPPeerStateImpl implements BGPRouteEntryImportPara private final RpcProviderRegistry rpcRegistry; private final PeerRole peerRole; private InstanceIdentifier peerRibOutIId; - private KeyedInstanceIdentifier peerIId; @GuardedBy("this") private AbstractRegistration trackerRegistration; private final LoadingCache> tablesIId @@ -335,6 +333,7 @@ public class BGPPeer extends BGPPeerStateImpl implements BGPRouteEntryImportPara if (this.session instanceof BGPSessionStateProvider) { ((BGPSessionStateProvider) this.session).registerMessagesCounter(this); } + final List addPathTablesType = session.getAdvertisedAddPathTableTypes(); final Set advertizedTableTypes = session.getAdvertisedTableTypes(); final List 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 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 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); diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/EffectiveRibInWriter.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/EffectiveRibInWriter.java index b2226d8c37..43359fd21c 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/EffectiveRibInWriter.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/EffectiveRibInWriter.java @@ -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 { + 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 peerIId, final Set tables) { - this.adjInTracker = new AdjInTracker(peer, rib, chain, peerIId, tables); - } + private final RIBSupportContextRegistry registry; + private final KeyedInstanceIdentifier peerIId; + private final InstanceIdentifier effRibTables; + private final DataBroker databroker; + private ListenerRegistration reg; + private final BindingTransactionChain chain; + private final Map prefixesReceived; + private final Map 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 peerIId, + EffectiveRibInWriter(final BGPRouteEntryImportParameters peer, final RIB rib, + final BindingTransactionChain chain, + final KeyedInstanceIdentifier peerIId, @Nonnull final Set 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 getTableKeys() { - return this.adjInTracker.getTableKeys(); - } - - @Override - public boolean isSupported(final TablesKey tablesKey) { - return this.adjInTracker.isSupported(tablesKey); + private Map buildPrefixesTables(final Set tables) { + final ImmutableMap.Builder 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 { - private final RIBSupportContextRegistry registry; - private final KeyedInstanceIdentifier peerIId; - private final InstanceIdentifier effRibTables; - private final ListenerRegistration reg; - private final BindingTransactionChain chain; - private final Map prefixesReceived; - private final Map prefixesInstalled; - private final BGPRibRoutingPolicy ribPolicies; - private final BGPRouteEntryImportParameters peerImportParameters; - - @SuppressWarnings("unchecked") - AdjInTracker(final BGPRouteEntryImportParameters peer, final RIB rib, - final BindingTransactionChain chain, - final KeyedInstanceIdentifier peerIId, - @Nonnull final Set 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 buildPrefixesTables(final Set tables) { - final ImmutableMap.Builder b = ImmutableMap.builder(); - tables.forEach(table -> b.put(table, new LongAdder())); - return b.build(); - } + @SuppressWarnings("unchecked") + public synchronized void onDataTreeChanged(@Nonnull final Collection> changes) { + LOG.trace("Data changed called to effective RIB. Change : {}", changes); + WriteTransaction tx = null; + for (final DataTreeModification tc : changes) { + final DataObjectModification 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 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> changes) { - LOG.trace("Data changed called to effective RIB. Change : {}", changes); - WriteTransaction tx = null; - for (final DataTreeModification tc : changes) { - final DataObjectModification 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 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 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 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 tablePath, - final Collection> routeChanges) { - for (final DataObjectModification 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 tablePath, + final Collection> routeChanges) { + for (final DataObjectModification 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 tablePath, final Identifier routeKey, - final Route route) { - final InstanceIdentifier routeIID = ribSupport.createRouteIdentifier(tablePath, routeKey); - CountersUtil.increment(this.prefixesReceived.get(tk), tk); - final Optional 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 tablePath, final Identifier routeKey, + final Route route) { + final InstanceIdentifier routeIID = ribSupport.createRouteIdentifier(tablePath, routeKey); + CountersUtil.increment(this.prefixesReceived.get(tk), tk); + final Optional 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 table) { - final Tables newTable = table.getDataAfter(); - if (newTable == null) { - return; - } - final TablesKey tableKey = newTable.getKey(); - final KeyedInstanceIdentifier tablePath - = this.effRibTables.child(Tables.class, tableKey); + @SuppressWarnings("unchecked") + private void writeTable(final WriteTransaction tx, final DataObjectModification table) { + final Tables newTable = table.getDataAfter(); + if (newTable == null) { + return; + } + final TablesKey tableKey = newTable.getKey(); + final KeyedInstanceIdentifier 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 getTableKeys() { - return ImmutableSet.copyOf(this.prefixesReceived.keySet()); - } + @Override + public Set 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(); } }