X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=bgp%2Frib-impl%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fprotocol%2Fbgp%2Frib%2Fimpl%2FAdjRibOutListener.java;h=3de8380761cca78083eaa17b4401f0177a9eb6e0;hb=refs%2Fchanges%2F40%2F106640%2F3;hp=e8a297024bc66765163f5e38b3a4687b24a9085a;hpb=c450cd6650b91f50e26c6720a10ad2d42f90f780;p=bgpcep.git diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibOutListener.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibOutListener.java index e8a297024b..3de8380761 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibOutListener.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/AdjRibOutListener.java @@ -27,16 +27,13 @@ import org.opendaylight.protocol.bgp.rib.impl.spi.CodecsRegistry; import org.opendaylight.protocol.bgp.rib.impl.state.peer.PrefixesSentCounters; import org.opendaylight.protocol.bgp.rib.spi.IdentifierUtils; import org.opendaylight.protocol.bgp.rib.spi.RIBSupport; -import org.opendaylight.protocol.bgp.rib.spi.RibSupportUtils; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.ipv4.routes.ipv4.routes.Ipv4Route; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.PathId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.Update; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.UpdateBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.path.attributes.Attributes; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.update.message.Nlri; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.update.message.NlriBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.update.message.WithdrawnRoutes; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev200120.update.message.WithdrawnRoutesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.TablesKey; @@ -44,11 +41,12 @@ import org.opendaylight.yangtools.concepts.ListenerRegistration; import org.opendaylight.yangtools.yang.common.QName; import org.opendaylight.yangtools.yang.common.Uint32; import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; +import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier; 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.NormalizedNodes; -import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidate; -import org.opendaylight.yangtools.yang.data.api.schema.tree.DataTreeCandidateNode; +import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidate; +import org.opendaylight.yangtools.yang.data.tree.api.DataTreeCandidateNode; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -57,19 +55,16 @@ import org.slf4j.LoggerFactory; * (message) and sends it down the channel. This class is NOT thread-safe. */ final class AdjRibOutListener implements ClusteredDOMDataTreeChangeListener, PrefixesSentCounters { - private static final Logger LOG = LoggerFactory.getLogger(AdjRibOutListener.class); - private static final QName PREFIX_QNAME = QName.create(Ipv4Route.QNAME, "prefix").intern(); private static final QName PATHID_QNAME = QName.create(Ipv4Route.QNAME, "path-id").intern(); - private final YangInstanceIdentifier.NodeIdentifier routeKeyPrefixLeaf = new YangInstanceIdentifier - .NodeIdentifier(PREFIX_QNAME); - private final YangInstanceIdentifier.NodeIdentifier routeKeyPathIdLeaf = new YangInstanceIdentifier - .NodeIdentifier(PATHID_QNAME); + private static final NodeIdentifier ROUTE_KEY_PREFIX_LEAF = NodeIdentifier.create(PREFIX_QNAME); + private static final NodeIdentifier ROUTE_KEY_PATHID_LEAF = NodeIdentifier.create(PATHID_QNAME); private final ChannelOutputLimiter session; private final Codecs codecs; private final RIBSupport support; + // FIXME: this field needs to be eliminated: either subclass this class or create a filtering ribsupport private final boolean mpSupport; private final ListenerRegistration registerDataTreeChangeListener; private final LongAdder prefixesSentCounter = new LongAdder(); @@ -81,7 +76,7 @@ final class AdjRibOutListener implements ClusteredDOMDataTreeChangeListener, Pre final ChannelOutputLimiter session, final boolean mpSupport) { this.session = requireNonNull(session); this.support = requireNonNull(support); - this.codecs = registry.getCodecs(this.support); + codecs = registry.getCodecs(this.support); this.mpSupport = mpSupport; this.tablesKey = requireNonNull(tablesKey); final YangInstanceIdentifier adjRibOutId = ribId.node(PEER_NID).node(IdentifierUtils.domPeerId(peerId)) @@ -91,8 +86,8 @@ final class AdjRibOutListener implements ClusteredDOMDataTreeChangeListener, Pre * in data store. Within this first ODTC execution we should advertise present routes and than * send EOR marker. initialState flag is distinguishing between first ODTC execution and the rest. */ - this.initalState = true; - this.registerDataTreeChangeListener = service.registerDataTreeChangeListener( + initalState = true; + registerDataTreeChangeListener = service.registerDataTreeChangeListener( new DOMDataTreeIdentifier(LogicalDatastoreType.OPERATIONAL, adjRibOutId), this); } @@ -114,27 +109,22 @@ final class AdjRibOutListener implements ClusteredDOMDataTreeChangeListener, Pre } @Override - public void onDataTreeChanged(final Collection changes) { + public void onDataTreeChanged(final List changes) { LOG.debug("Data change received for AdjRibOut {}", changes); for (final DataTreeCandidate tc : changes) { LOG.trace("Change {} type {}", tc.getRootNode(), tc.getRootNode().getModificationType()); for (final DataTreeCandidateNode child : tc.getRootNode().getChildNodes()) { - processSupportedFamilyRoutes(child); + for (final DataTreeCandidateNode route : support.changedRoutes(child)) { + processRouteChange(route); + } } } if (initalState) { - final Update endOfRib = BgpPeerUtil.createEndOfRib(this.tablesKey); - this.session.write(endOfRib); - this.initalState = false; - } - this.session.flush(); - } - - private void processSupportedFamilyRoutes(final DataTreeCandidateNode child) { - final Collection changedRoutes = this.support.changedRoutes(child); - for (final DataTreeCandidateNode route : changedRoutes) { - processRouteChange(route); + final Update endOfRib = BgpPeerUtil.createEndOfRib(tablesKey); + session.write(endOfRib); + initalState = false; } + session.flush(); } private void processRouteChange(final DataTreeCandidateNode route) { @@ -146,20 +136,20 @@ final class AdjRibOutListener implements ClusteredDOMDataTreeChangeListener, Pre case DELETE: case DISAPPEARED: // FIXME: we can batch deletions into a single batch - update = withdraw((MapEntryNode) route.getDataBefore().get()); + update = withdraw((MapEntryNode) route.getDataBefore().orElseThrow()); LOG.debug("Withdrawing routes {}", update); break; case APPEARED: case SUBTREE_MODIFIED: case WRITE: - update = advertise((MapEntryNode) route.getDataAfter().get()); + update = advertise((MapEntryNode) route.getDataAfter().orElseThrow()); LOG.debug("Advertising routes {}", update); break; default: LOG.warn("Ignoring unhandled modification type {}", route.getModificationType()); return; } - this.session.write(update); + session.write(update); } private Attributes routeAttributes(final MapEntryNode route) { @@ -167,66 +157,61 @@ final class AdjRibOutListener implements ClusteredDOMDataTreeChangeListener, Pre LOG.debug("AdjRibOut parsing route {}", NormalizedNodes.toStringTree(route)); } final ContainerNode advertisedAttrs = (ContainerNode) NormalizedNodes.findNode(route, - this.support.routeAttributesIdentifier()).orElse(null); - return this.codecs.deserializeAttributes(advertisedAttrs); + support.routeAttributesIdentifier()).orElse(null); + return codecs.deserializeAttributes(advertisedAttrs); } private Update withdraw(final MapEntryNode route) { - if (!this.mpSupport) { - return buildUpdate(Collections.emptyList(), Collections.singleton(route), routeAttributes(route)); - } - return this.support.buildUpdate(Collections.emptyList(), Collections.singleton(route), routeAttributes(route)); + return mpSupport + ? support.buildUpdate(Collections.emptyList(), Collections.singleton(route), routeAttributes(route)) + : buildUpdate(Collections.emptyList(), Collections.singleton(route), routeAttributes(route)); } private Update advertise(final MapEntryNode route) { - this.prefixesSentCounter.increment(); - if (!this.mpSupport) { - return buildUpdate(Collections.singleton(route), Collections.emptyList(), routeAttributes(route)); - } - return this.support.buildUpdate(Collections.singleton(route), Collections.emptyList(), routeAttributes(route)); + prefixesSentCounter.increment(); + return mpSupport + ? support.buildUpdate(Collections.singleton(route), Collections.emptyList(), routeAttributes(route)) + : buildUpdate(Collections.singleton(route), Collections.emptyList(), routeAttributes(route)); } - private Update buildUpdate( + private static Update buildUpdate( final @NonNull Collection advertised, final @NonNull Collection withdrawn, final @NonNull Attributes attr) { - final UpdateBuilder ub = new UpdateBuilder().setWithdrawnRoutes(extractWithdrawnRoutes(withdrawn)) - .setNlri(extractNlris(advertised)); - ub.setAttributes(attr); - return ub.build(); - } - - private List extractNlris(final Collection routes) { - return routes.stream().map(ipv4Route -> new NlriBuilder().setPrefix(new Ipv4Prefix(extractPrefix(ipv4Route))) - .setPathId(extractPathId(ipv4Route)).build()).collect(Collectors.toList()); - } - - private List extractWithdrawnRoutes(final Collection routes) { - return routes.stream().map(ipv4Route -> new WithdrawnRoutesBuilder() - .setPrefix(new Ipv4Prefix(extractPrefix(ipv4Route))).setPathId(extractPathId(ipv4Route)).build()) - .collect(Collectors.toList()); + return new UpdateBuilder() + .setWithdrawnRoutes(withdrawn.stream() + .map(ipv4Route -> new WithdrawnRoutesBuilder() + .setPrefix(extractPrefix(ipv4Route)) + .setPathId(extractPathId(ipv4Route)) + .build()) + .collect(Collectors.toList())) + .setNlri(advertised.stream() + .map(ipv4Route -> new NlriBuilder() + .setPrefix(extractPrefix(ipv4Route)) + .setPathId(extractPathId(ipv4Route)).build()) + .collect(Collectors.toList())) + .setAttributes(attr).build(); } - private String extractPrefix(final MapEntryNode ipv4Route) { - return (String) ipv4Route.findChildByArg(this.routeKeyPrefixLeaf).get().body(); + private static Ipv4Prefix extractPrefix(final MapEntryNode ipv4Route) { + return new Ipv4Prefix((String) ipv4Route.getChildByArg(ROUTE_KEY_PREFIX_LEAF).body()); } - private PathId extractPathId(final MapEntryNode ipv4Route) { - return ipv4Route.findChildByArg(this.routeKeyPathIdLeaf) - .map(dataContainerChild -> new PathId((Uint32) dataContainerChild.body())) - .orElse(null); + private static PathId extractPathId(final MapEntryNode ipv4Route) { + final var pathId = ipv4Route.childByArg(ROUTE_KEY_PATHID_LEAF); + return pathId == null ? null : new PathId((Uint32) pathId.body()); } public void close() { - this.registerDataTreeChangeListener.close(); + registerDataTreeChangeListener.close(); } boolean isMpSupported() { - return this.mpSupport; + return mpSupport; } @Override public long getPrefixesSentCount() { - return this.prefixesSentCounter.longValue(); + return prefixesSentCounter.longValue(); } }