2 * Copyright (c) 2016 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.mdsal.dom.broker;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotEquals;
13 import static org.junit.Assert.assertNotNull;
14 import static org.junit.Assert.assertSame;
15 import static org.junit.Assert.assertTrue;
16 import static org.mockito.ArgumentMatchers.any;
17 import static org.mockito.Mockito.doNothing;
18 import static org.mockito.Mockito.doReturn;
19 import static org.mockito.Mockito.mock;
20 import static org.opendaylight.mdsal.dom.broker.TestUtils.TEST_CHILD;
22 import com.google.common.collect.Multimap;
23 import com.google.common.util.concurrent.ListenableFuture;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.List;
28 import java.util.concurrent.CountDownLatch;
29 import java.util.concurrent.ExecutorService;
30 import java.util.concurrent.TimeUnit;
31 import org.junit.Test;
32 import org.opendaylight.mdsal.dom.api.DOMNotification;
33 import org.opendaylight.mdsal.dom.api.DOMNotificationListener;
34 import org.opendaylight.mdsal.dom.api.DOMNotificationPublishService;
35 import org.opendaylight.mdsal.dom.spi.DOMNotificationSubscriptionListener;
36 import org.opendaylight.yangtools.util.ListenerRegistry;
37 import org.opendaylight.yangtools.yang.common.QName;
38 import org.opendaylight.yangtools.yang.model.api.stmt.SchemaNodeIdentifier.Absolute;
40 public class DOMNotificationRouterTest {
43 public void create() throws Exception {
44 assertNotNull(DOMNotificationRouter.create(1024));
48 public void registerNotificationListener() {
49 final var domNotificationRouter = new DOMNotificationRouter(1024);
50 final var domNotificationListener = mock(DOMNotificationListener.class);
52 domNotificationRouter.registerNotificationListener(domNotificationListener,
53 List.of(Absolute.of(QName.create("urn:opendaylight:test-listener", "notif1"))));
54 assertEquals(1, domNotificationRouter.listeners().size());
56 domNotificationRouter.registerNotificationListener(domNotificationListener,
57 List.of(Absolute.of(QName.create("urn:opendaylight:test-listener", "notif2")),
58 Absolute.of(QName.create("urn:opendaylight:test-listener", "notif3"))));
59 assertEquals(3, domNotificationRouter.listeners().size());
63 public void registerNotificationListeners() {
64 final var domNotificationRouter = new DOMNotificationRouter(1024);
65 final var domNotificationListener1 = mock(DOMNotificationListener.class);
66 final var domNotificationListener2 = mock(DOMNotificationListener.class);
68 domNotificationRouter.registerNotificationListeners(
69 Map.of(Absolute.of(QName.create("urn:opendaylight:test-listener", "notif1")), domNotificationListener1,
70 Absolute.of(QName.create("urn:opendaylight:test-listener", "notif2")), domNotificationListener2));
71 assertEquals(2, domNotificationRouter.listeners().size());
74 @SuppressWarnings("checkstyle:IllegalCatch")
76 public void complexTest() throws Exception {
77 final DOMNotificationSubscriptionListener domNotificationSubscriptionListener =
78 mock(DOMNotificationSubscriptionListener.class);
79 doNothing().when(domNotificationSubscriptionListener).onSubscriptionChanged(any());
81 final CountDownLatch latch = new CountDownLatch(1);
82 final DOMNotificationListener domNotificationListener = new TestListener(latch);
83 final DOMNotificationRouter domNotificationRouter = DOMNotificationRouter.create(1024);
85 Multimap<Absolute, ?> listeners = domNotificationRouter.listeners();
87 assertTrue(listeners.isEmpty());
88 assertNotNull(domNotificationRouter.registerNotificationListener(domNotificationListener,
89 Absolute.of(TestModel.TEST_QNAME)));
90 assertNotNull(domNotificationRouter.registerNotificationListener(domNotificationListener,
91 Absolute.of(TestModel.TEST2_QNAME)));
93 listeners = domNotificationRouter.listeners();
95 assertFalse(listeners.isEmpty());
97 ListenerRegistry<DOMNotificationSubscriptionListener> subscriptionListeners =
98 domNotificationRouter.subscriptionListeners();
100 assertEquals(0, subscriptionListeners.streamListeners().count());
101 assertNotNull(domNotificationRouter.registerSubscriptionListener(domNotificationSubscriptionListener));
103 subscriptionListeners = domNotificationRouter.subscriptionListeners();
104 assertSame(domNotificationSubscriptionListener,
105 subscriptionListeners.streamListeners().findAny().orElseThrow());
107 final DOMNotification domNotification = mock(DOMNotification.class);
108 doReturn("test").when(domNotification).toString();
109 doReturn(Absolute.of(TestModel.TEST_QNAME)).when(domNotification).getType();
110 doReturn(TEST_CHILD).when(domNotification).getBody();
112 assertNotNull(domNotificationRouter.offerNotification(domNotification));
115 assertNotNull(domNotificationRouter.offerNotification(domNotification, 1, TimeUnit.SECONDS));
116 assertNotNull(domNotificationRouter.offerNotification(domNotification, 1, TimeUnit.SECONDS));
117 } catch (Exception e) {
118 // FIXME: what is the point here?!
119 assertTrue(e instanceof UnsupportedOperationException);
122 assertNotNull(domNotificationRouter.putNotification(domNotification));
126 public void offerNotification() throws Exception {
127 final DOMNotificationRouter domNotificationRouter = DOMNotificationRouter.create(1024);
128 final DOMNotification domNotification = mock(DOMNotification.class);
129 doReturn(Absolute.of(TestModel.TEST_QNAME)).when(domNotification).getType();
130 doReturn(TEST_CHILD).when(domNotification).getBody();
131 assertNotNull(domNotificationRouter.putNotification(domNotification));
132 assertNotNull(domNotificationRouter.offerNotification(domNotification));
133 assertNotNull(domNotificationRouter.offerNotification(domNotification, 1, TimeUnit.SECONDS));
137 public void testOfferNotificationWithBlocking() throws Exception {
138 final CountDownLatch latch = new CountDownLatch(1);
139 final TestListener testListener = new TestListener(latch);
140 final DOMNotification domNotification = mock(DOMNotification.class);
141 doReturn("test").when(domNotification).toString();
142 doReturn(Absolute.of(TestModel.TEST_QNAME)).when(domNotification).getType();
143 doReturn(TEST_CHILD).when(domNotification).getBody();
145 try (TestRouter testRouter = new TestRouter(1)) {
146 assertNotNull(testRouter.registerNotificationListener(testListener, Absolute.of(TestModel.TEST_QNAME)));
147 assertNotNull(testRouter.registerNotificationListener(testListener, Absolute.of(TestModel.TEST2_QNAME)));
149 assertNotEquals(DOMNotificationPublishService.REJECTED,
150 testRouter.offerNotification(domNotification, 3, TimeUnit.SECONDS));
151 assertTrue("Listener was not notified", latch.await(5, TimeUnit.SECONDS));
152 assertEquals("Received notifications", 1, testListener.getReceivedNotifications().size());
154 assertEquals(DOMNotificationPublishService.REJECTED,
155 testRouter.offerNotification(domNotification, 1, TimeUnit.SECONDS));
156 assertEquals("Received notifications", 1, testListener.getReceivedNotifications().size());
161 public void close() throws Exception {
162 final DOMNotificationRouter domNotificationRouter = DOMNotificationRouter.create(1024);
163 final ExecutorService executor = domNotificationRouter.executor();
164 final ExecutorService observer = domNotificationRouter.observer();
166 assertFalse(executor.isShutdown());
167 assertFalse(observer.isShutdown());
168 domNotificationRouter.close();
169 assertTrue(executor.isShutdown());
170 assertTrue(observer.isShutdown());
173 private static class TestListener implements DOMNotificationListener {
174 private final CountDownLatch latch;
175 private final List<DOMNotification> receivedNotifications = new ArrayList<>();
177 TestListener(final CountDownLatch latch) {
182 public void onNotification(final DOMNotification notification) {
183 receivedNotifications.add(notification);
187 public List<DOMNotification> getReceivedNotifications() {
188 return receivedNotifications;
192 private static class TestRouter extends DOMNotificationRouter {
194 private boolean triggerRejected = false;
196 TestRouter(final int queueDepth) {
201 ListenableFuture<? extends Object> publish(final DOMNotification notification,
202 final Collection<Reg<?>> subscribers) {
203 if (triggerRejected) {
207 triggerRejected = true;
208 return super.publish(notification, subscribers);
212 public ListenableFuture<? extends Object> putNotification(final DOMNotification notification)
213 throws InterruptedException {
215 return super.putNotification(notification);