MVPN RFC6514 Extendend communities
[bgpcep.git] / bmp / bmp-impl / src / test / java / org / opendaylight / protocol / bmp / impl / app / BmpMonitorImplTest.java
1 /*
2  * Copyright (c) 2015 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.protocol.bmp.impl.app;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertNull;
15 import static org.junit.Assert.assertTrue;
16 import static org.mockito.Matchers.any;
17 import static org.mockito.Mockito.doAnswer;
18 import static org.opendaylight.protocol.bmp.parser.message.TestUtil.createRouteMonMsgWithEndOfRibMarker;
19 import static org.opendaylight.protocol.bmp.parser.message.TestUtil.createRouteMonitMsg;
20 import static org.opendaylight.protocol.util.CheckUtil.readDataOperational;
21 import static org.opendaylight.protocol.util.CheckUtil.waitFutureSuccess;
22
23 import com.google.common.net.InetAddresses;
24 import io.netty.bootstrap.Bootstrap;
25 import io.netty.channel.Channel;
26 import io.netty.channel.ChannelFuture;
27 import io.netty.channel.ChannelInitializer;
28 import io.netty.channel.ChannelOption;
29 import io.netty.channel.EventLoopGroup;
30 import io.netty.channel.epoll.Epoll;
31 import io.netty.channel.epoll.EpollEventLoopGroup;
32 import io.netty.channel.epoll.EpollSocketChannel;
33 import io.netty.channel.nio.NioEventLoopGroup;
34 import io.netty.channel.socket.SocketChannel;
35 import io.netty.channel.socket.nio.NioSocketChannel;
36 import java.net.InetSocketAddress;
37 import java.util.List;
38 import javassist.ClassPool;
39 import org.junit.After;
40 import org.junit.Before;
41 import org.junit.Test;
42 import org.mockito.Mock;
43 import org.mockito.MockitoAnnotations;
44 import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
45 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
46 import org.opendaylight.controller.md.sal.common.api.data.ReadFailedException;
47 import org.opendaylight.controller.md.sal.dom.api.DOMDataWriteTransaction;
48 import org.opendaylight.mdsal.binding.dom.adapter.BindingToNormalizedNodeCodec;
49 import org.opendaylight.mdsal.binding.dom.codec.gen.impl.StreamWriterGenerator;
50 import org.opendaylight.mdsal.binding.dom.codec.impl.BindingNormalizedNodeCodecRegistry;
51 import org.opendaylight.mdsal.binding.generator.impl.GeneratedClassLoadingStrategy;
52 import org.opendaylight.mdsal.binding.generator.impl.ModuleInfoBackedContext;
53 import org.opendaylight.mdsal.binding.generator.util.JavassistUtils;
54 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonService;
55 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceProvider;
56 import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegistration;
57 import org.opendaylight.protocol.bgp.inet.RIBActivator;
58 import org.opendaylight.protocol.bgp.parser.impl.BGPActivator;
59 import org.opendaylight.protocol.bgp.parser.spi.BGPExtensionProviderContext;
60 import org.opendaylight.protocol.bgp.parser.spi.pojo.SimpleBGPExtensionProviderContext;
61 import org.opendaylight.protocol.bgp.rib.spi.RIBExtensionProviderContext;
62 import org.opendaylight.protocol.bgp.rib.spi.SimpleRIBExtensionProviderContext;
63 import org.opendaylight.protocol.bmp.api.BmpDispatcher;
64 import org.opendaylight.protocol.bmp.impl.BmpDispatcherImpl;
65 import org.opendaylight.protocol.bmp.impl.BmpHandlerFactory;
66 import org.opendaylight.protocol.bmp.impl.config.BmpDeployerDependencies;
67 import org.opendaylight.protocol.bmp.impl.session.DefaultBmpSessionFactory;
68 import org.opendaylight.protocol.bmp.impl.spi.BmpMonitoringStation;
69 import org.opendaylight.protocol.bmp.parser.BmpActivator;
70 import org.opendaylight.protocol.bmp.parser.message.TestUtil;
71 import org.opendaylight.protocol.bmp.spi.registry.BmpMessageRegistry;
72 import org.opendaylight.protocol.bmp.spi.registry.SimpleBmpExtensionProviderContext;
73 import org.opendaylight.protocol.util.CheckUtil;
74 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
75 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
76 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.bmp.monitor.monitor.router.peer.pre.policy.rib.tables.routes.Ipv4RoutesCase;
77 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet.rev180329.update.attributes.mp.reach.nlri.advertized.routes.destination.type.DestinationIpv4Case;
78 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.message.rev180329.open.message.BgpParameters;
79 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.CParameters1;
80 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.mp.capabilities.MultiprotocolCapability;
81 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.multiprotocol.rev180329.update.attributes.mp.reach.nlri.AdvertizedRoutes;
82 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.PeerId;
83 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.rib.rev180329.rib.Tables;
84 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.Ipv4AddressFamily;
85 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.types.rev180329.UnicastSubsequentAddressFamily;
86 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.AdjRibInType;
87 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.InitiationMessage;
88 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.PeerType;
89 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.RouteMirroringMessage;
90 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.StatsReportsMessage;
91 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.peer.up.ReceivedOpen;
92 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.peer.up.SentOpen;
93 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.message.rev180329.stat.Tlvs;
94 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.BmpMonitor;
95 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.MonitorId;
96 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.RouterId;
97 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.Status;
98 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.bmp.monitor.Monitor;
99 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.bmp.monitor.MonitorKey;
100 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.peers.Peer;
101 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.peers.PeerKey;
102 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.peers.peer.Mirrors;
103 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.peers.peer.PeerSession;
104 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.peers.peer.PostPolicyRib;
105 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.peers.peer.PrePolicyRib;
106 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.peers.peer.Stats;
107 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.routers.Router;
108 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bmp.monitor.rev180329.routers.RouterKey;
109 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
110 import org.opendaylight.yangtools.yang.binding.KeyedInstanceIdentifier;
111 import org.opendaylight.yangtools.yang.binding.util.BindingReflections;
112 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
113 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
114 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
115 import org.opendaylight.yangtools.yang.data.impl.schema.Builders;
116 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
117
118 public class BmpMonitorImplTest extends AbstractConcurrentDataBrokerTest {
119     // the local port and address where the monitor (ODL) will listen for incoming BMP request
120     private static final int MONITOR_LOCAL_PORT = 12345;
121     private static final String MONITOR_LOCAL_ADDRESS = "127.0.0.10";
122     private static final String MONITOR_LOCAL_ADDRESS_2 = "127.0.0.11";
123     // the router (monitee) address where we are going to simulate a BMP request from
124     private static final String REMOTE_ROUTER_ADDRESS_1 = "127.0.0.12";
125     private static final String REMOTE_ROUTER_ADDRESS_2 = "127.0.0.13";
126     private static final Ipv4Address PEER1 = new Ipv4Address("20.20.20.20");
127     private static final MonitorId MONITOR_ID = new MonitorId("monitor");
128     private static final KeyedInstanceIdentifier<Monitor, MonitorKey> MONITOR_IID = InstanceIdentifier
129         .create(BmpMonitor.class).child(Monitor.class, new MonitorKey(MONITOR_ID));
130     private static final PeerId PEER_ID = new PeerId(PEER1.getValue());
131     private static final InstanceIdentifier<BmpMonitor> BMP_II = InstanceIdentifier.create(BmpMonitor.class);
132     private BindingToNormalizedNodeCodec mappingService;
133     private RIBActivator ribActivator;
134     private BGPActivator bgpActivator;
135     private BmpActivator bmpActivator;
136     private BmpDispatcher dispatcher;
137     private BmpMonitoringStation bmpApp;
138     private BmpMessageRegistry msgRegistry;
139     private RIBExtensionProviderContext ribExtension;
140     private ClusterSingletonService singletonService;
141     private ClusterSingletonService singletonService2;
142     @Mock
143     private ClusterSingletonServiceRegistration singletonServiceRegistration;
144     @Mock
145     private ClusterSingletonServiceRegistration singletonServiceRegistration2;
146     @Mock
147     private ClusterSingletonServiceProvider clusterSSProv;
148     @Mock
149     private ClusterSingletonServiceProvider clusterSSProv2;
150
151     @Before
152     public void setUp() throws Exception {
153         MockitoAnnotations.initMocks(this);
154
155         doAnswer(invocationOnMock -> {
156             BmpMonitorImplTest.this.singletonService = (ClusterSingletonService) invocationOnMock.getArguments()[0];
157             this.singletonService.instantiateServiceInstance();
158             return BmpMonitorImplTest.this.singletonServiceRegistration;
159         }).when(this.clusterSSProv).registerClusterSingletonService(any(ClusterSingletonService.class));
160
161         doAnswer(invocationOnMock -> BmpMonitorImplTest.this.singletonService.closeServiceInstance())
162             .when(this.singletonServiceRegistration).close();
163
164         doAnswer(invocationOnMock -> {
165             this.singletonService2 = (ClusterSingletonService) invocationOnMock.getArguments()[0];
166             this.singletonService2.instantiateServiceInstance();
167             return BmpMonitorImplTest.this.singletonServiceRegistration2;
168         }).when(this.clusterSSProv2).registerClusterSingletonService(any(ClusterSingletonService.class));
169
170         doAnswer(invocationOnMock -> BmpMonitorImplTest.this.singletonService2.closeServiceInstance())
171             .when(this.singletonServiceRegistration2).close();
172
173         this.mappingService = new BindingToNormalizedNodeCodec(GeneratedClassLoadingStrategy
174                 .getTCCLClassLoadingStrategy(),
175             new BindingNormalizedNodeCodecRegistry(StreamWriterGenerator
176                     .create(JavassistUtils.forClassPool(ClassPool.getDefault()))));
177         final ModuleInfoBackedContext moduleInfoBackedContext = ModuleInfoBackedContext.create();
178         moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(InitiationMessage.class));
179         moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(CParameters1.class));
180         moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(BgpParameters.class));
181         moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(MultiprotocolCapability.class));
182         moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(DestinationIpv4Case.class));
183         moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(AdvertizedRoutes.class));
184         moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(SentOpen.class));
185         moduleInfoBackedContext.registerModuleInfo(BindingReflections.getModuleInfo(ReceivedOpen.class));
186         this.mappingService.onGlobalContextUpdated(moduleInfoBackedContext.tryToCreateSchemaContext().get());
187         this.ribActivator = new RIBActivator();
188         this.ribExtension = new SimpleRIBExtensionProviderContext();
189         this.ribActivator.startRIBExtensionProvider(this.ribExtension);
190
191         this.bgpActivator = new BGPActivator();
192         final BGPExtensionProviderContext context = new SimpleBGPExtensionProviderContext();
193         this.bgpActivator.start(context);
194         final SimpleBmpExtensionProviderContext ctx = new SimpleBmpExtensionProviderContext();
195         this.bmpActivator = new BmpActivator(context);
196         this.bmpActivator.start(ctx);
197         this.msgRegistry = ctx.getBmpMessageRegistry();
198
199         this.dispatcher = new BmpDispatcherImpl(new NioEventLoopGroup(), new NioEventLoopGroup(),
200             ctx.getBmpMessageRegistry(), new DefaultBmpSessionFactory());
201
202         final InetSocketAddress inetAddress = new InetSocketAddress(InetAddresses.forString(MONITOR_LOCAL_ADDRESS),
203             MONITOR_LOCAL_PORT);
204
205         final DOMDataWriteTransaction wTx = getDomBroker().newWriteOnlyTransaction();
206         final ContainerNode parentNode = Builders.containerBuilder().withNodeIdentifier(
207                 new NodeIdentifier(BmpMonitor.QNAME))
208                 .addChild(ImmutableNodes.mapNodeBuilder(Monitor.QNAME).build()).build();
209         wTx.merge(LogicalDatastoreType.OPERATIONAL, YangInstanceIdentifier.of(BmpMonitor.QNAME), parentNode);
210         wTx.submit();
211
212         final BmpDeployerDependencies bmpDependecies = new BmpDeployerDependencies(getDataBroker(), getDomBroker(),
213             this.ribExtension, this.mappingService.getCodecFactory(), getSchemaContext(), this.clusterSSProv);
214         this.bmpApp = new BmpMonitoringStationImpl(bmpDependecies, this.dispatcher, MONITOR_ID, inetAddress, null);
215         readDataOperational(getDataBroker(), BMP_II, monitor -> {
216             assertEquals(1, monitor.getMonitor().size());
217             final Monitor bmpMonitor = monitor.getMonitor().get(0);
218             assertEquals(MONITOR_ID, bmpMonitor.getMonitorId());
219             assertEquals(0, bmpMonitor.getRouter().size());
220             assertEquals(MONITOR_ID, bmpMonitor.getMonitorId());
221             assertEquals(0, bmpMonitor.getRouter().size());
222             return monitor;
223         });
224     }
225
226     @After
227     public void tearDown() throws Exception {
228         this.ribActivator.close();
229         this.bgpActivator.close();
230         this.bmpActivator.close();
231         this.dispatcher.close();
232         this.bmpApp.close();
233         this.mappingService.close();
234
235         readDataOperational(getDataBroker(), BMP_II, monitor -> {
236             assertTrue(monitor.getMonitor().isEmpty());
237             return monitor;
238         });
239     }
240
241     @Test
242     public void testRouterMonitoring() throws Exception {
243         // first test if a single router monitoring is working
244         final Channel channel1 = testMonitoringStation(REMOTE_ROUTER_ADDRESS_1);
245         readDataOperational(getDataBroker(), MONITOR_IID, monitor -> {
246             assertEquals(1, monitor.getRouter().size());
247             return monitor;
248         });
249
250         final Channel channel2 = testMonitoringStation(REMOTE_ROUTER_ADDRESS_2);
251         readDataOperational(getDataBroker(), MONITOR_IID, monitor -> {
252             assertEquals(2, monitor.getRouter().size());
253             return monitor;
254         });
255
256         // initiate another BMP request from router 1, create a redundant connection
257         // we expect the connection to be closed
258         final Channel channel3 = connectTestClient(REMOTE_ROUTER_ADDRESS_1, this.msgRegistry);
259
260
261         // channel 1 should still be open, while channel3 should be closed
262         CheckUtil.checkEquals(() -> assertTrue(channel1.isOpen()));
263         CheckUtil.checkEquals(() -> assertFalse(channel3.isOpen()));
264
265         // now if we close the channel 1 and try it again, it should succeed
266         waitFutureSuccess(channel1.close());
267
268         // channel 2 is still open
269         readDataOperational(getDataBroker(), MONITOR_IID, monitor -> {
270             assertEquals(1, monitor.getRouter().size());
271             return monitor;
272         });
273
274         final Channel channel4 = testMonitoringStation(REMOTE_ROUTER_ADDRESS_1);
275         readDataOperational(getDataBroker(), MONITOR_IID, monitor -> {
276             assertEquals(2, monitor.getRouter().size());
277             return monitor;
278         });
279
280         // close all channel altogether
281         waitFutureSuccess(channel2.close());
282         Thread.sleep(100);
283
284         // sleep for a while to avoid intermittent InMemoryDataTree modification conflict
285         waitFutureSuccess(channel4.close());
286
287         readDataOperational(getDataBroker(), MONITOR_IID, monitor -> {
288             assertEquals(0, monitor.getRouter().size());
289             return monitor;
290         });
291     }
292
293     private static void waitWriteAndFlushSuccess(final ChannelFuture channelFuture) {
294         waitFutureSuccess(channelFuture);
295     }
296
297     private Channel testMonitoringStation(final String remoteRouterIpAddr) throws InterruptedException,
298             ReadFailedException {
299         final Channel channel = connectTestClient(remoteRouterIpAddr, this.msgRegistry);
300         final RouterId routerId = getRouterId(remoteRouterIpAddr);
301
302         readDataOperational(getDataBroker(), MONITOR_IID, monitor -> {
303             assertFalse(monitor.getRouter().isEmpty());
304             // now find the current router instance
305             Router router = null;
306             for (final Router r : monitor.getRouter()) {
307                 if (routerId.equals(r.getRouterId())) {
308                     router = r;
309                     break;
310                 }
311             }
312             assertNotNull(router);
313             assertEquals(Status.Down, router.getStatus());
314             assertTrue(router.getPeer().isEmpty());
315             return router;
316         });
317
318         waitWriteAndFlushSuccess(channel.writeAndFlush(TestUtil
319                 .createInitMsg("description", "name", "some info")));
320
321         readDataOperational(getDataBroker(), MONITOR_IID, monitor -> {
322             assertFalse(monitor.getRouter().isEmpty());
323             Router retRouter = null;
324             for (final Router r : monitor.getRouter()) {
325                 if (routerId.equals(r.getRouterId())) {
326                     retRouter = r;
327                     break;
328                 }
329             }
330
331             assertEquals("some info;", retRouter.getInfo());
332             assertEquals("name", retRouter.getName());
333             assertEquals("description", retRouter.getDescription());
334             assertEquals(routerId, retRouter.getRouterId());
335             assertTrue(retRouter.getPeer().isEmpty());
336             assertEquals(Status.Up, retRouter.getStatus());
337             return retRouter;
338         });
339
340         waitWriteAndFlushSuccess(channel.writeAndFlush(TestUtil.createPeerUpNotification(PEER1, true)));
341         final KeyedInstanceIdentifier<Router, RouterKey> routerIId =
342                 MONITOR_IID.child(Router.class, new RouterKey(routerId));
343
344         readDataOperational(getDataBroker(), routerIId, router -> {
345             final List<Peer> peers = router.getPeer();
346             assertEquals(1, peers.size());
347             final Peer peer = peers.get(0);
348             assertEquals(PeerType.Global, peer.getType());
349             assertEquals(PEER_ID, peer.getPeerId());
350             assertEquals(PEER1, peer.getBgpId());
351             assertEquals(TestUtil.IPV4_ADDRESS_10, peer.getAddress().getIpv4Address());
352             assertEquals(TestUtil.PEER_AS, peer.getAs());
353             assertNull(peer.getPeerDistinguisher());
354             assertNull(peer.getStats());
355
356             assertNotNull(peer.getPrePolicyRib());
357             assertEquals(1, peer.getPrePolicyRib().getTables().size());
358             final Tables prePolicyTable = peer.getPrePolicyRib().getTables().get(0);
359             assertEquals(Ipv4AddressFamily.class, prePolicyTable.getAfi());
360             assertEquals(UnicastSubsequentAddressFamily.class, prePolicyTable.getSafi());
361             assertFalse(prePolicyTable.getAttributes().isUptodate());
362             assertNotNull(prePolicyTable.getRoutes());
363
364             assertNotNull(peer.getPostPolicyRib());
365             assertEquals(1, peer.getPostPolicyRib().getTables().size());
366             final Tables postPolicyTable = peer.getPrePolicyRib().getTables().get(0);
367             assertEquals(Ipv4AddressFamily.class, postPolicyTable.getAfi());
368             assertEquals(UnicastSubsequentAddressFamily.class, postPolicyTable.getSafi());
369             assertFalse(postPolicyTable.getAttributes().isUptodate());
370             assertNotNull(postPolicyTable.getRoutes());
371
372             assertNotNull(peer.getPeerSession());
373             final PeerSession peerSession = peer.getPeerSession();
374             assertEquals(TestUtil.IPV4_ADDRESS_10, peerSession.getLocalAddress().getIpv4Address());
375             assertEquals(TestUtil.PEER_LOCAL_PORT, peerSession.getLocalPort());
376             assertEquals(TestUtil.PEER_REMOTE_PORT, peerSession.getRemotePort());
377             assertEquals(Status.Up, peerSession.getStatus());
378             assertNotNull(peerSession.getReceivedOpen());
379             assertNotNull(peerSession.getSentOpen());
380             return router;
381         });
382
383
384         final StatsReportsMessage statsMsg = TestUtil.createStatsReportMsg(PEER1);
385         waitWriteAndFlushSuccess(channel.writeAndFlush(statsMsg));
386         final KeyedInstanceIdentifier<Peer, PeerKey> peerIId = routerIId.child(Peer.class, new PeerKey(PEER_ID));
387
388         readDataOperational(getDataBroker(), peerIId.child(Stats.class), peerStats -> {
389             assertNotNull(peerStats.getTimestampSec());
390             final Tlvs tlvs = statsMsg.getTlvs();
391             assertEquals(tlvs.getAdjRibsInRoutesTlv().getCount(), peerStats.getAdjRibsInRoutes());
392             assertEquals(tlvs.getDuplicatePrefixAdvertisementsTlv().getCount(),
393                     peerStats.getDuplicatePrefixAdvertisements());
394             assertEquals(tlvs.getDuplicateWithdrawsTlv().getCount(), peerStats.getDuplicateWithdraws());
395             assertEquals(tlvs.getInvalidatedAsConfedLoopTlv().getCount(), peerStats.getInvalidatedAsConfedLoop());
396             assertEquals(tlvs.getInvalidatedAsPathLoopTlv().getCount(), peerStats.getInvalidatedAsPathLoop());
397             assertEquals(tlvs.getInvalidatedClusterListLoopTlv().getCount(),
398                     peerStats.getInvalidatedClusterListLoop());
399             assertEquals(tlvs.getInvalidatedOriginatorIdTlv().getCount(), peerStats.getInvalidatedOriginatorId());
400             assertEquals(tlvs.getLocRibRoutesTlv().getCount(), peerStats.getLocRibRoutes());
401             assertEquals(tlvs.getRejectedPrefixesTlv().getCount(), peerStats.getRejectedPrefixes());
402             assertEquals(tlvs.getPerAfiSafiAdjRibInTlv().getCount().toString(),
403                     peerStats.getPerAfiSafiAdjRibInRoutes().getAfiSafi().get(0).getCount().toString());
404             assertEquals(tlvs.getPerAfiSafiLocRibTlv().getCount().toString(),
405                     peerStats.getPerAfiSafiLocRibRoutes().getAfiSafi().get(0).getCount().toString());
406             return peerStats;
407         });
408
409         // route mirror message test
410         final RouteMirroringMessage routeMirrorMsg = TestUtil.createRouteMirrorMsg(PEER1);
411         waitWriteAndFlushSuccess(channel.writeAndFlush(routeMirrorMsg));
412
413         readDataOperational(getDataBroker(), peerIId.child(Mirrors.class), routeMirrors -> {
414             assertNotNull(routeMirrors.getTimestampSec());
415             return routeMirrors;
416         });
417
418         waitWriteAndFlushSuccess(channel.writeAndFlush(createRouteMonitMsg(false, PEER1,
419                 AdjRibInType.PrePolicy)));
420         waitWriteAndFlushSuccess(channel.writeAndFlush(createRouteMonMsgWithEndOfRibMarker(PEER1,
421                 AdjRibInType.PrePolicy)));
422
423         readDataOperational(getDataBroker(), peerIId.child(PrePolicyRib.class), prePolicyRib -> {
424             assertTrue(!prePolicyRib.getTables().isEmpty());
425             final Tables tables = prePolicyRib.getTables().get(0);
426             assertTrue(tables.getAttributes().isUptodate());
427             assertEquals(3, ((Ipv4RoutesCase) tables.getRoutes()).getIpv4Routes().getIpv4Route().size());
428             return tables;
429         });
430
431         waitWriteAndFlushSuccess(channel.writeAndFlush(createRouteMonitMsg(false, PEER1,
432                 AdjRibInType.PostPolicy)));
433         waitWriteAndFlushSuccess(channel.writeAndFlush(createRouteMonMsgWithEndOfRibMarker(PEER1,
434                 AdjRibInType.PostPolicy)));
435
436         readDataOperational(getDataBroker(), peerIId.child(PostPolicyRib.class), postPolicyRib -> {
437             assertTrue(!postPolicyRib.getTables().isEmpty());
438             final Tables tables = postPolicyRib.getTables().get(0);
439             assertTrue(tables.getAttributes().isUptodate());
440             assertEquals(3, ((org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.bgp.inet
441                     .rev180329.bmp.monitor.monitor.router.peer.post.policy.rib.tables.routes.Ipv4RoutesCase)
442                     tables.getRoutes()).getIpv4Routes().getIpv4Route().size());
443             return tables;
444         });
445
446         waitWriteAndFlushSuccess(channel.writeAndFlush(TestUtil.createPeerDownNotification(PEER1)));
447
448         readDataOperational(getDataBroker(), routerIId, router -> {
449             final List<Peer> peersAfterDown = router.getPeer();
450             assertTrue(peersAfterDown.isEmpty());
451             return router;
452         });
453
454         return channel;
455     }
456
457     @Test
458     public void deploySecondInstance() throws Exception {
459         final BmpDeployerDependencies bmpDependecies = new BmpDeployerDependencies(getDataBroker(), getDomBroker(),
460             this.ribExtension, this.mappingService.getCodecFactory(), getSchemaContext(), this.clusterSSProv2);
461
462         final BmpMonitoringStation monitoringStation2 = new BmpMonitoringStationImpl(bmpDependecies,
463             this.dispatcher, new MonitorId("monitor2"),
464                 new InetSocketAddress(InetAddresses.forString(MONITOR_LOCAL_ADDRESS_2), MONITOR_LOCAL_PORT), null);
465
466         readDataOperational(getDataBroker(), BMP_II, monitor -> {
467             assertEquals(2, monitor.getMonitor().size());
468             return monitor;
469         });
470
471         monitoringStation2.close();
472     }
473
474     private static Channel connectTestClient(final String routerIp, final BmpMessageRegistry msgRegistry)
475             throws InterruptedException {
476         final BmpHandlerFactory hf = new BmpHandlerFactory(msgRegistry);
477         final Bootstrap b = new Bootstrap();
478         final EventLoopGroup workerGroup;
479         if (Epoll.isAvailable()) {
480             b.channel(EpollSocketChannel.class);
481             workerGroup = new EpollEventLoopGroup();
482         } else {
483             b.channel(NioSocketChannel.class);
484             workerGroup = new NioEventLoopGroup();
485         }
486         b.group(workerGroup);
487         b.option(ChannelOption.SO_KEEPALIVE, true);
488         b.handler(new ChannelInitializer<SocketChannel>() {
489             @Override
490             protected void initChannel(final SocketChannel ch) throws Exception {
491                 ch.pipeline().addLast(hf.getDecoders());
492                 ch.pipeline().addLast(hf.getEncoders());
493             }
494         });
495         b.localAddress(new InetSocketAddress(routerIp, 0));
496         b.option(ChannelOption.SO_REUSEADDR, true);
497         final ChannelFuture future = b.connect(new InetSocketAddress(MONITOR_LOCAL_ADDRESS, MONITOR_LOCAL_PORT)).sync();
498         waitFutureSuccess(future);
499         return future.channel();
500     }
501
502     private static RouterId getRouterId(final String routerIp) {
503         return new RouterId(new IpAddress(new Ipv4Address(routerIp)));
504     }
505 }