From 2dbddbd4f50dca562f9d2d5078baa2c485bced92 Mon Sep 17 00:00:00 2001 From: Iveta Halanova Date: Tue, 22 Mar 2016 15:35:31 +0100 Subject: [PATCH] BUG-5511: Support Route Refresh operation from BGP Created module for peer-rpc request. Implemented class for handling input. Updated unit tests Change-Id: I1e0f24acc9eb713c9c60f4ab977e7efd892f563a Signed-off-by: Iveta Halanova --- .../main/resources/initial/41-bgp-example.xml | 4 ++ bgp/rib-api/src/main/yang/bgp-peer-rpc.yang | 57 +++++++++++++++ .../rib/impl/BGPApplicationPeerModule.java | 16 ++--- .../yang/bgp/rib/impl/BGPPeerModule.java | 4 +- .../protocol/bgp/rib/impl/BGPPeer.java | 26 +++++-- .../protocol/bgp/rib/impl/BGPSessionImpl.java | 7 +- .../protocol/bgp/rib/impl/BgpPeerRpc.java | 69 ++++++++++++++++++ .../bgp/rib/impl/ChannelOutputLimiter.java | 27 +++---- .../protocol/bgp/rib/impl/spi/RIB.java | 3 +- .../src/main/yang/odl-bgp-rib-impl-cfg.yang | 8 +++ .../rib/impl/AbstractRIBImplModuleTest.java | 65 ++++++++++++++++- .../yang/bgp/rib/impl/BGPPeerModuleTest.java | 12 ++-- .../protocol/bgp/rib/impl/BgpPeerRpcTest.java | 71 +++++++++++++++++++ .../bgp/rib/impl/ParserToSalTest.java | 5 +- .../protocol/bgp/rib/impl/PeerTest.java | 6 +- 15 files changed, 337 insertions(+), 43 deletions(-) create mode 100644 bgp/rib-api/src/main/yang/bgp-peer-rpc.yang create mode 100644 bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BgpPeerRpc.java create mode 100644 bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/BgpPeerRpcTest.java diff --git a/bgp/controller-config/src/main/resources/initial/41-bgp-example.xml b/bgp/controller-config/src/main/resources/initial/41-bgp-example.xml index 4e159fcea8..e1d3671292 100755 --- a/bgp/controller-config/src/main/resources/initial/41-bgp-example.xml +++ b/bgp/controller-config/src/main/resources/initial/41-bgp-example.xml @@ -92,6 +92,10 @@ prefix:bgp-peer-registry global-bgp-peer-registry + + binding:binding-rpc-registry + binding-rpc-broker + prefix:bgp-table-type ipv4-unicast diff --git a/bgp/rib-api/src/main/yang/bgp-peer-rpc.yang b/bgp/rib-api/src/main/yang/bgp-peer-rpc.yang new file mode 100644 index 0000000000..5a0d6a1679 --- /dev/null +++ b/bgp/rib-api/src/main/yang/bgp-peer-rpc.yang @@ -0,0 +1,57 @@ +module bgp-peer-rpc { + namespace "urn:opendaylight:params:xml:ns:yang:bgp-peer-rpc"; + prefix "bgp-rpc"; + + import bgp-multiprotocol { prefix bgp-mp; revision-date 2013-09-19; } + import bgp-rib { prefix rib; revision-date 2013-09-25; } + import yang-ext { prefix ext; revision-date "2013-07-09"; } + + organization "Cisco Systems, Inc."; + contact "Iveta Halanova "; + + description + "Module contains rpc for route refresh request, which is described in rfc2918. + + Copyright (c) 2016 Cisco Systems, Inc. All rights reserved. + + This program and the accompanying materials are made available + under the terms of the Eclipse Public License v1.0 which + accompanies this distribution, and is available at + http://www.eclipse.org/legal/epl-v10.html"; + + revision 2016-03-22 { + description "Initial revision"; + } + + identity peer-context { + description "Identity used to mark the Peer context for binding RPCs in a particular RIB."; + } + + typedef peer-ref { + type instance-identifier; + ext:context-reference "peer-context"; + } + + grouping peer-reference { + leaf peer-ref { + type peer-ref; + mandatory true; + ext:context-reference "peer-context"; + } + } + + grouping rr-msg-args { + uses peer-reference; + uses bgp-mp:bgp-table-type; + } + + rpc route-refresh-request { + input { + uses rr-msg-args; + } + } + + augment "/rib:bgp-rib/rib:rib/rib:peer" { + ext:context-instance "peer-context"; + } +} \ No newline at end of file diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPApplicationPeerModule.java b/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPApplicationPeerModule.java index 92b60a9cc8..21ab950b13 100755 --- a/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPApplicationPeerModule.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPApplicationPeerModule.java @@ -79,7 +79,7 @@ public class BGPApplicationPeerModule extends org.opendaylight.controller.config final RIB r = getTargetRibDependency(); final IpAddress bgpPeerId = new IpAddress(getBgpPeerId()); - final BGPPeer bgpClientPeer = new BGPPeer(bgpPeerId.getIpv4Address().getValue(), r, PeerRole.Internal); + final BGPPeer bgpClientPeer = new BGPPeer(bgpPeerId.getIpv4Address().getValue(), r, PeerRole.Internal, null); final BGPSessionPreferences prefs = new BGPSessionPreferences(r.getLocalAs(), 0, r.getBgpIdentifier(), r.getLocalAs(), Collections.emptyList()); @@ -105,26 +105,26 @@ public class BGPApplicationPeerModule extends org.opendaylight.controller.config public AppPeerModuleTracker(final Optional openConfigProvider) { if (openConfigProvider.isPresent()) { - appProvider = openConfigProvider.get().getOpenConfigMapper(BGPAppPeerInstanceConfiguration.class); + this.appProvider = openConfigProvider.get().getOpenConfigMapper(BGPAppPeerInstanceConfiguration.class); } else { - appProvider = null; + this.appProvider = null; } final InstanceConfigurationIdentifier identifier = new InstanceConfigurationIdentifier(getIdentifier().getInstanceName()); - bgpAppPeerInstanceConfiguration = new BGPAppPeerInstanceConfiguration(identifier, getApplicationRibId().getValue(), + this.bgpAppPeerInstanceConfiguration = new BGPAppPeerInstanceConfiguration(identifier, getApplicationRibId().getValue(), Rev130715Util.getIpv4Address(getBgpPeerId())); } @Override public void onInstanceCreate() { - if (appProvider != null) { - appProvider.writeConfiguration(this.bgpAppPeerInstanceConfiguration); + if (this.appProvider != null) { + this.appProvider.writeConfiguration(this.bgpAppPeerInstanceConfiguration); } } @Override public void onInstanceClose() { - if (appProvider != null) { - appProvider.removeConfiguration(this.bgpAppPeerInstanceConfiguration); + if (this.appProvider != null) { + this.appProvider.removeConfiguration(this.bgpAppPeerInstanceConfiguration); } } diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModule.java b/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModule.java index 359c8f6616..cb673e032f 100755 --- a/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModule.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModule.java @@ -134,9 +134,9 @@ public final class BGPPeerModule extends org.opendaylight.controller.config.yang final BGPPeer bgpClientPeer; final IpAddress host = getNormalizedHost(); if (getPeerRole() != null) { - bgpClientPeer = new BGPPeer(peerName(host), r, getPeerRole()); + bgpClientPeer = new BGPPeer(peerName(host), r, getPeerRole(), getRpcRegistryDependency()); } else { - bgpClientPeer = new BGPPeer(peerName(host), r, PeerRole.Ibgp); + bgpClientPeer = new BGPPeer(peerName(host), r, PeerRole.Ibgp, getRpcRegistryDependency()); } bgpClientPeer.registerRootRuntimeBean(getRootRuntimeBeanRegistratorWrapper()); 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 336f36f7f6..9214214a08 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 @@ -30,6 +30,8 @@ import org.opendaylight.controller.md.sal.common.api.data.AsyncTransaction; import org.opendaylight.controller.md.sal.common.api.data.TransactionChain; import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain; +import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.RoutedRpcRegistration; +import org.opendaylight.controller.sal.binding.api.RpcProviderRegistry; import org.opendaylight.protocol.bgp.rib.impl.spi.BGPSessionStatistics; import org.opendaylight.protocol.bgp.rib.impl.spi.RIB; import org.opendaylight.protocol.bgp.rib.impl.spi.RIBSupportContext; @@ -57,13 +59,17 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.reach.nlri.AdvertizedRoutesBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.mp.unreach.nlri.WithdrawnRoutesBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev160322.BgpPeerRpcService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev160322.PeerContext; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.PeerKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.AddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.UnicastSubsequentAddressFamily; +import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier; import org.opendaylight.yangtools.yang.binding.Notification; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -93,16 +99,15 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer private BGPPeerRuntimeRegistration runtimeReg; private long sessionEstablishedCounter = 0L; private final Map adjRibOutListenerSet = new HashMap(); + private final RpcProviderRegistry rpcRegistry; + private RoutedRpcRegistration rpcRegistration; - public BGPPeer(final String name, final RIB rib) { - this(name, rib, PeerRole.Ibgp); - } - - public BGPPeer(final String name, final RIB rib, final PeerRole role) { + public BGPPeer(final String name, final RIB rib, final PeerRole role, final RpcProviderRegistry rpcRegistry) { this.rib = Preconditions.checkNotNull(rib); this.name = name; this.chain = rib.createPeerChain(this); this.ribWriter = AdjRibInWriter.create(rib.getYangRibId(), role, this.chain); + this.rpcRegistry = rpcRegistry; } @Override @@ -225,6 +230,7 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer LOG.info("Session with peer {} went up with tables {} and Add Path tables {}", this.name, addPathTablesType, session.getAdvertisedAddPathTableTypes()); this.session = session; + this.rawIdentifier = InetAddresses.forString(session.getBgpId().getValue()).getAddress(); final PeerId peerId = RouterIds.createPeerId(session.getBgpId()); createAdjRibOutListener(peerId); @@ -234,6 +240,13 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer if (this.registrator != null) { this.runtimeReg = this.registrator.register(this); } + + if (this.rpcRegistry != null) { + this.rpcRegistration = this.rpcRegistry.addRoutedRpcImplementation(BgpPeerRpcService.class, new BgpPeerRpc(session, this.tables)); + final KeyedInstanceIdentifier path = + this.rib.getInstanceIdentifier().child(org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.Peer.class, new PeerKey(peerId)); + this.rpcRegistration.registerPath(PeerContext.class, path); + } } private void createAdjRibOutListener(final PeerId peerId) { @@ -309,6 +322,9 @@ public class BGPPeer implements BGPSessionListener, Peer, AutoCloseable, BGPPeer @Override public void releaseConnection() { + if (this.rpcRegistration != null) { + this.rpcRegistration.close(); + } addPeerToDisconnectedSharedList(); cleanup(); dropConnection(); diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPSessionImpl.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPSessionImpl.java index 7f8812066a..ce8f658cf1 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPSessionImpl.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BGPSessionImpl.java @@ -252,7 +252,7 @@ public class BGPSessionImpl extends SimpleChannelInboundHandler im } @GuardedBy("this") - private void writeEpilogue(final ChannelFuture future, final Notification msg) { + private ChannelFuture writeEpilogue(final ChannelFuture future, final Notification msg) { future.addListener( new ChannelFutureListener() { @Override @@ -271,6 +271,7 @@ public class BGPSessionImpl extends SimpleChannelInboundHandler im } else if (msg instanceof Notify) { this.sessionStats.updateSentMsgErr((Notify) msg); } + return future; } void flush() { @@ -285,8 +286,8 @@ public class BGPSessionImpl extends SimpleChannelInboundHandler im } } - synchronized void writeAndFlush(final Notification msg) { - writeEpilogue(this.channel.writeAndFlush(msg), msg); + synchronized ChannelFuture writeAndFlush(final Notification msg) { + return writeEpilogue(this.channel.writeAndFlush(msg), msg); } private synchronized void closeWithoutMessage() { diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BgpPeerRpc.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BgpPeerRpc.java new file mode 100644 index 0000000000..26a12fb4d4 --- /dev/null +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/BgpPeerRpc.java @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.protocol.bgp.rib.impl; + +import com.google.common.base.Function; +import com.google.common.base.Preconditions; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.JdkFutureAdapters; +import io.netty.channel.ChannelFuture; +import java.util.Set; +import java.util.concurrent.Future; +import org.opendaylight.protocol.bgp.rib.spi.BGPSession; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.RouteRefresh; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.RouteRefreshBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev160322.BgpPeerRpcService; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev160322.RouteRefreshRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey; +import org.opendaylight.yangtools.yang.common.RpcError.ErrorType; +import org.opendaylight.yangtools.yang.common.RpcResult; +import org.opendaylight.yangtools.yang.common.RpcResultBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +public class BgpPeerRpc implements BgpPeerRpcService { + + private static final Logger LOG = LoggerFactory.getLogger(BgpPeerRpc.class); + private static final String FAILURE_MSG = "Failed to send Route Refresh message"; + + private final BGPSession session; + private final Set supportedFamilies; + + BgpPeerRpc(final BGPSession session, final Set supportedFamilies) { + this.session = Preconditions.checkNotNull(session); + this.supportedFamilies = Preconditions.checkNotNull(supportedFamilies); + } + + @Override + public Future> routeRefreshRequest(final RouteRefreshRequestInput input) { + final ChannelFuture f = sendRRMessage(input); + if (f != null) { + return Futures.transform(JdkFutureAdapters.listenInPoolThread(f), new Function>() { + @Override + public RpcResult apply(final Void input) { + if (f.isSuccess()) { + return RpcResultBuilder.success().build(); + } else { + return RpcResultBuilder.failed().withError(ErrorType.RPC, FAILURE_MSG).build(); + } + } + }); + } + return RpcResultBuilder.failed().withError(ErrorType.RPC, FAILURE_MSG + " due to unsupported address families.").buildFuture(); + } + + private ChannelFuture sendRRMessage(final RouteRefreshRequestInput input) { + if (!this.supportedFamilies.contains(new TablesKey(input.getAfi(), input.getSafi()))) { + LOG.info("Unsupported afi/safi: {}, {}.", input.getAfi(), input.getSafi()); + return null; + } + final RouteRefresh msg = new RouteRefreshBuilder().setAfi(input.getAfi()).setSafi(input.getSafi()).build(); + return ((BGPSessionImpl) this.session).getLimiter().writeAndFlush(msg); + } + +} diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ChannelOutputLimiter.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ChannelOutputLimiter.java index 21150b9431..bf1d253ef6 100644 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ChannelOutputLimiter.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/ChannelOutputLimiter.java @@ -8,6 +8,7 @@ package org.opendaylight.protocol.bgp.rib.impl; import com.google.common.base.Preconditions; +import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; import javax.annotation.concurrent.ThreadSafe; @@ -30,35 +31,35 @@ final class ChannelOutputLimiter extends ChannelInboundHandlerAdapter { } private void ensureWritable() { - if (blocked) { - LOG.trace("Blocked slow path tripped on session {}", session); + if (this.blocked) { + LOG.trace("Blocked slow path tripped on session {}", this.session); synchronized (this) { - while (blocked) { + while (this.blocked) { try { - LOG.debug("Waiting for session {} to become writable", session); + LOG.debug("Waiting for session {} to become writable", this.session); this.wait(); - } catch (InterruptedException e) { + } catch (final InterruptedException e) { throw new IllegalStateException("Interrupted while waiting for channel to come back", e); } } - LOG.debug("Resuming write on session {}", session); + LOG.debug("Resuming write on session {}", this.session); } } } void write(final Notification msg) { ensureWritable(); - session.write(msg); + this.session.write(msg); } - void writeAndFlush(final Notification msg) { + ChannelFuture writeAndFlush(final Notification msg) { ensureWritable(); - session.writeAndFlush(msg); + return this.session.writeAndFlush(msg); } void flush() { - session.flush(); + this.session.flush(); } @Override @@ -66,8 +67,8 @@ final class ChannelOutputLimiter extends ChannelInboundHandlerAdapter { final boolean w = ctx.channel().isWritable(); synchronized (this) { - blocked = !w; - LOG.debug("Writes on session {} {}", session, w ? "unblocked" : "blocked"); + this.blocked = !w; + LOG.debug("Writes on session {} {}", this.session, w ? "unblocked" : "blocked"); if (w) { this.notifyAll(); @@ -82,7 +83,7 @@ final class ChannelOutputLimiter extends ChannelInboundHandlerAdapter { @Override public void channelInactive(final ChannelHandlerContext ctx) throws Exception { synchronized (this) { - blocked = false; + this.blocked = false; this.notifyAll(); } diff --git a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java index b356349b42..c8c086d9f7 100755 --- a/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java +++ b/bgp/rib-impl/src/main/java/org/opendaylight/protocol/bgp/rib/impl/spi/RIB.java @@ -13,6 +13,7 @@ import javax.annotation.Nonnull; import org.opendaylight.controller.md.sal.common.api.data.TransactionChainListener; import org.opendaylight.controller.md.sal.dom.api.DOMTransactionChain; import org.opendaylight.protocol.bgp.openconfig.spi.BGPOpenConfigProvider; +import org.opendaylight.protocol.bgp.rib.RibReference; import org.opendaylight.protocol.bgp.rib.spi.CacheDisconnectedPeers; import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionConsumerContext; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.AsNumber; @@ -24,7 +25,7 @@ import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier; /** * Internal reference to a RIB instance. */ -public interface RIB { +public interface RIB extends RibReference { AsNumber getLocalAs(); Ipv4Address getBgpIdentifier(); diff --git a/bgp/rib-impl/src/main/yang/odl-bgp-rib-impl-cfg.yang b/bgp/rib-impl/src/main/yang/odl-bgp-rib-impl-cfg.yang index 6828a0fbc7..801d563e92 100644 --- a/bgp/rib-impl/src/main/yang/odl-bgp-rib-impl-cfg.yang +++ b/bgp/rib-impl/src/main/yang/odl-bgp-rib-impl-cfg.yang @@ -429,6 +429,14 @@ module odl-bgp-rib-impl-cfg { } } } + container rpc-registry { + uses config:service-ref { + refine type { + mandatory true; + config:required-identity mdsb:binding-rpc-registry; + } + } + } } } diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/controller/config/yang/bgp/rib/impl/AbstractRIBImplModuleTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/controller/config/yang/bgp/rib/impl/AbstractRIBImplModuleTest.java index c4e590c18f..eee2809f01 100755 --- a/bgp/rib-impl/src/test/java/org/opendaylight/controller/config/yang/bgp/rib/impl/AbstractRIBImplModuleTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/controller/config/yang/bgp/rib/impl/AbstractRIBImplModuleTest.java @@ -9,7 +9,6 @@ package org.opendaylight.controller.config.yang.bgp.rib.impl; import static org.mockito.Matchers.any; import static org.mockito.Mockito.mock; - import com.google.common.base.Optional; import com.google.common.collect.Lists; import com.google.common.io.ByteSource; @@ -44,8 +43,14 @@ import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModu import org.opendaylight.controller.config.yang.bgp.rib.spi.RIBExtensionsImplModuleMXBean; import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingAsyncDataBrokerImplModuleFactory; import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingAsyncDataBrokerImplModuleMXBean; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingBrokerImplModuleFactory; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.BindingBrokerImplModuleMXBean; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.ForwardedCompatibleDataBrokerImplModuleFactory; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.ForwardedCompatibleDataBrokerImplModuleMXBean; +import org.opendaylight.controller.config.yang.md.sal.binding.impl.NotificationBrokerImplModuleFactory; import org.opendaylight.controller.config.yang.md.sal.binding.impl.RuntimeMappingModuleFactory; import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomBrokerImplModuleFactory; +import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomBrokerImplModuleMXBean; import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleFactory; import org.opendaylight.controller.config.yang.md.sal.dom.impl.DomInmemoryDataBrokerModuleMXBean; import org.opendaylight.controller.config.yang.md.sal.dom.impl.SchemaServiceImplSingletonModuleFactory; @@ -92,6 +97,9 @@ public abstract class AbstractRIBImplModuleTest extends AbstractConfigTest { private static final String DOM_BROKER_INSTANCE_NAME = "dom-broker-impl"; private static final String BINDING_ASYNC_BROKER_INSTANCE_NAME = "binding-async-broker-instance"; private static final String DOM_ASYNC_DATA_BROKER_INSTANCE = "dom-inmemory-data-broker"; + private static final String BINDING_BROKER_INSTANCE_NAME = "binding-broker-impl"; + private static final String COMPATIBLE_DATA_BROKER_INSTANCE_NAME = "binding-data-compatible-broker-instance"; + private static final String NOTIFICATION_BROKER_INSTANCE_NAME = "notification-broker-impl"; @Mock private ReadWriteTransaction mockedTransaction; @@ -177,7 +185,9 @@ public abstract class AbstractRIBImplModuleTest extends AbstractConfigTest { new SimpleBGPExtensionProviderContextModuleFactory(), new RIBExtensionsImplModuleFactory(), new DomBrokerImplModuleFactory(), new RuntimeMappingModuleFactory(), new HashedWheelTimerModuleFactory(), new BindingAsyncDataBrokerImplModuleFactory(), - new DomInmemoryDataBrokerModuleFactory(), new SchemaServiceImplSingletonModuleFactory()); + new DomInmemoryDataBrokerModuleFactory(), new SchemaServiceImplSingletonModuleFactory(), + new NotificationBrokerImplModuleFactory(), new ForwardedCompatibleDataBrokerImplModuleFactory(), + new BindingBrokerImplModuleFactory()); } @Override @@ -324,4 +334,55 @@ public abstract class AbstractRIBImplModuleTest extends AbstractConfigTest { return resources; } + + public ObjectName createBindingBrokerImpl(final ConfigTransactionJMXClient transaction, final ObjectName dataBrokerON, + final ObjectName notificationBrokerON) throws Exception { + final ObjectName objectName = transaction.createModule(BindingBrokerImplModuleFactory.NAME, BINDING_BROKER_INSTANCE_NAME); + final BindingBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(objectName, BindingBrokerImplModuleMXBean.class); + mxBean.setDataBroker(dataBrokerON); + mxBean.setNotificationService(notificationBrokerON); + mxBean.setBindingMappingService(lookupMappingServiceInstance(transaction)); + mxBean.setDomAsyncBroker(lookupDomBrokerInstance(transaction)); + return objectName; + } + + public static ObjectName lookupDomBrokerInstance(final ConfigTransactionJMXClient transaction) throws InstanceAlreadyExistsException { + try { + return transaction.lookupConfigBean(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME); + } catch (final InstanceNotFoundException e) { + try { + final ObjectName nameCreated = transaction.createModule(DomBrokerImplModuleFactory.NAME, DOM_BROKER_INSTANCE_NAME); + final DomBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, DomBrokerImplModuleMXBean.class); + mxBean.setAsyncDataBroker(lookupDomAsyncDataBroker(transaction)); + return nameCreated; + } catch (final InstanceAlreadyExistsException e1) { + throw new IllegalStateException(e1); + } + } + } + + public ObjectName createCompatibleDataBrokerInstance(final ConfigTransactionJMXClient transaction) + throws InstanceAlreadyExistsException, InstanceNotFoundException { + final ObjectName nameCreated = transaction.createModule(ForwardedCompatibleDataBrokerImplModuleFactory.NAME, COMPATIBLE_DATA_BROKER_INSTANCE_NAME); + final ForwardedCompatibleDataBrokerImplModuleMXBean mxBean = transaction.newMXBeanProxy(nameCreated, ForwardedCompatibleDataBrokerImplModuleMXBean.class); + mxBean.setDataBroker(lookupDataBrokerInstance(transaction)); + return nameCreated; + } + + private static ObjectName lookupDataBrokerInstance(final ConfigTransactionJMXClient transaction) { + try { + return transaction.lookupConfigBean(BindingAsyncDataBrokerImplModuleFactory.NAME, BINDING_ASYNC_BROKER_INSTANCE_NAME); + } catch (final InstanceNotFoundException e) { + try { + return transaction.createModule(RuntimeMappingModuleFactory.NAME, RuntimeMappingModuleFactory.SINGLETON_NAME); + } catch (final InstanceAlreadyExistsException e1) { + throw new IllegalStateException(e1); + } + } + } + + public ObjectName createNotificationBrokerInstance(final ConfigTransactionJMXClient transaction) throws Exception { + final ObjectName objectName = transaction.createModule(NotificationBrokerImplModuleFactory.NAME, NOTIFICATION_BROKER_INSTANCE_NAME); + return objectName; + } } diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModuleTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModuleTest.java index 3e858e05e4..2880bd925b 100755 --- a/bgp/rib-impl/src/test/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModuleTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/controller/config/yang/bgp/rib/impl/BGPPeerModuleTest.java @@ -98,7 +98,7 @@ public class BGPPeerModuleTest extends AbstractRIBImplModuleTest { public void testCreateBean() throws Exception { final CommitStatus status = createBgpPeerInstance(); assertBeanCount(1, FACTORY_NAME); - assertStatus(status, 17, 0, 0); + assertStatus(status, 21, 0, 0); } @Test @@ -106,7 +106,7 @@ public class BGPPeerModuleTest extends AbstractRIBImplModuleTest { NativeTestSupport.assumeSupportedPlatform(); final CommitStatus status = createBgpPeerInstance(true); assertBeanCount(1, FACTORY_NAME); - assertStatus(status, 19, 0, 0); + assertStatus(status, 23, 0, 0); } @Test @@ -134,7 +134,7 @@ public class BGPPeerModuleTest extends AbstractRIBImplModuleTest { assertBeanCount(1, FACTORY_NAME); status = transaction.commit(); assertBeanCount(1, FACTORY_NAME); - assertStatus(status, 0, 0, 17); + assertStatus(status, 0, 0, 21); } @Test @@ -147,7 +147,7 @@ public class BGPPeerModuleTest extends AbstractRIBImplModuleTest { mxBean.setPort(new PortNumber(10)); status = transaction.commit(); assertBeanCount(1, FACTORY_NAME); - assertStatus(status, 0, 1, 16); + assertStatus(status, 0, 1, 20); } private ObjectName createBgpPeerInstance(final ConfigTransactionJMXClient transaction, final IpAddress host, @@ -187,6 +187,10 @@ public class BGPPeerModuleTest extends AbstractRIBImplModuleTest { mxBean.setAdvertizedTable(Lists.newArrayList(BGPTableTypeImplModuleTest.createTableInstance(transaction, new IdentityAttributeRef(Ipv4AddressFamily.QNAME.toString()), new IdentityAttributeRef(MplsLabeledVpnSubsequentAddressFamily.QNAME.toString())))); + + final ObjectName notificationBrokerON = createNotificationBrokerInstance(transaction); + final ObjectName bindingBrokerON = createBindingBrokerImpl(transaction, createCompatibleDataBrokerInstance(transaction), notificationBrokerON); + mxBean.setRpcRegistry(bindingBrokerON); return nameCreated; } diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/BgpPeerRpcTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/BgpPeerRpcTest.java new file mode 100644 index 0000000000..29d343afd6 --- /dev/null +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/BgpPeerRpcTest.java @@ -0,0 +1,71 @@ +/* + * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.protocol.bgp.rib.impl; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import io.netty.channel.ChannelFuture; +import java.util.HashSet; +import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; +import org.junit.Before; +import org.junit.Test; +import org.mockito.Mockito; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev160322.PeerRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev160322.RouteRefreshRequestInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.peer.rpc.rev160322.RouteRefreshRequestInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.TablesKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv6AddressFamily; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.SubsequentAddressFamily; +import org.opendaylight.yangtools.yang.binding.Notification; +import org.opendaylight.yangtools.yang.common.RpcResult; + +public class BgpPeerRpcTest { + + private final Set supportedFamilies = new HashSet(); + private final BGPSessionImpl session = Mockito.mock(BGPSessionImpl.class); + private final BgpPeerRpc rpc = new BgpPeerRpc(this.session, this.supportedFamilies); + private final PeerRef peer = Mockito.mock(PeerRef.class); + + private final ChannelOutputLimiter limiter = new ChannelOutputLimiter(this.session); + private final ChannelFuture future = Mockito.mock(ChannelFuture.class); + + @Before + public void setUp() throws InterruptedException, ExecutionException { + this.supportedFamilies.add(new TablesKey(Ipv4AddressFamily.class, SubsequentAddressFamily.class)); + + Mockito.doReturn(this.limiter).when(this.session).getLimiter(); + Mockito.doReturn(this.future).when(this.session).writeAndFlush(Mockito.any(Notification.class)); + Mockito.doReturn(true).when(this.future).isDone(); + Mockito.doReturn(null).when(this.future).get(); + Mockito.doReturn(true).when(this.future).isSuccess(); + } + + @Test + public void testSuccessRequest() throws InterruptedException, ExecutionException { + final RouteRefreshRequestInput input = new RouteRefreshRequestInputBuilder() + .setAfi(Ipv4AddressFamily.class) + .setSafi(SubsequentAddressFamily.class) + .setPeerRef(this.peer).build(); + final Future> result = this.rpc.routeRefreshRequest(input); + assertTrue(result.get().getErrors().isEmpty()); + } + + @Test + public void testFailedRequest() throws InterruptedException, ExecutionException { + final RouteRefreshRequestInput input = new RouteRefreshRequestInputBuilder() + .setAfi(Ipv6AddressFamily.class) + .setSafi(SubsequentAddressFamily.class) + .setPeerRef(this.peer).build(); + final Future> result = this.rpc.routeRefreshRequest(input); + assertEquals(1, result.get().getErrors().size()); + assertEquals("Failed to send Route Refresh message due to unsupported address families.", result.get().getErrors().iterator().next().getMessage()); + } +} diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ParserToSalTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ParserToSalTest.java index e5df1cebe5..6606fb9408 100755 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ParserToSalTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/ParserToSalTest.java @@ -53,6 +53,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.link import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.linkstate.rev150210.linkstate.routes.linkstate.routes.LinkstateRoute; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.BgpTableType; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.BgpRib; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.RibId; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.Rib; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.RibKey; @@ -136,7 +137,7 @@ public class ParserToSalTest extends AbstractDataBrokerTest { BasePathSelectionModeFactory.createBestPathSelectionStrategy()), GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy()); assertTablesExists(tables, true); rib.onGlobalContextUpdated(this.schemaService.getGlobalContext()); - final BGPPeer peer = new BGPPeer("peer-" + this.mock.toString(), rib); + final BGPPeer peer = new BGPPeer("peer-" + this.mock.toString(), rib, PeerRole.Ibgp, null); final ListenerRegistration reg = this.mock.registerUpdateListener(peer); reg.close(); @@ -151,7 +152,7 @@ public class ParserToSalTest extends AbstractDataBrokerTest { BasePathSelectionModeFactory.createBestPathSelectionStrategy()), GeneratedClassLoadingStrategy.getTCCLClassLoadingStrategy()); rib.onGlobalContextUpdated(this.schemaService.getGlobalContext()); assertTablesExists(tables, true); - final BGPPeer peer = new BGPPeer("peer-" + this.mock.toString(), rib); + final BGPPeer peer = new BGPPeer("peer-" + this.mock.toString(), rib, PeerRole.Ibgp, null); final ListenerRegistration reg = this.mock.registerUpdateListener(peer); reg.close(); diff --git a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/PeerTest.java b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/PeerTest.java index eda7772ecc..4aff5892fa 100644 --- a/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/PeerTest.java +++ b/bgp/rib-impl/src/test/java/org/opendaylight/protocol/bgp/rib/impl/PeerTest.java @@ -10,7 +10,6 @@ package org.opendaylight.protocol.bgp.rib.impl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.mockito.Matchers.any; - import com.google.common.collect.Lists; import io.netty.channel.Channel; import io.netty.channel.ChannelHandler; @@ -51,6 +50,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.mult import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.mp.capabilities.MultiprotocolCapabilityBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev130919.update.attributes.MpUnreachNlriBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.ApplicationRibId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.PeerRole; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.bgp.rib.rib.LocRib; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev130925.rib.Tables; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev130919.Ipv4AddressFamily; @@ -119,7 +119,7 @@ public class PeerTest extends AbstractRIBTestSetup { @Test public void testClassicPeer() throws Exception { - this.classic = new BGPPeer("testPeer", getRib()); + this.classic = new BGPPeer("testPeer", getRib(), PeerRole.Ibgp, null); this.mockSession(); assertEquals("testPeer", this.classic.getName()); this.classic.onSessionUp(this.session); @@ -133,7 +133,7 @@ public class PeerTest extends AbstractRIBTestSetup { assertEquals(3, this.routes.size()); //create new peer so that it gets advertized routes from RIB - try (final BGPPeer testingPeer = new BGPPeer("testingPeer", getRib())) { + try (final BGPPeer testingPeer = new BGPPeer("testingPeer", getRib(), PeerRole.Ibgp, null)) { testingPeer.onSessionUp(this.session); assertEquals(3, this.routes.size()); assertEquals(1, testingPeer.getBgpPeerState().getSessionEstablishedCount().intValue()); -- 2.36.6