2 * Copyright (c) 2018 Inocybe Technologies 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.controller.md.sal.dom.broker.impl;
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertFalse;
12 import static org.junit.Assert.assertNotNull;
13 import static org.junit.Assert.assertTrue;
15 import com.google.common.collect.ImmutableSet;
16 import com.google.common.util.concurrent.SettableFuture;
17 import com.google.common.util.concurrent.Uninterruptibles;
18 import java.time.Instant;
19 import java.util.Date;
21 import java.util.concurrent.ExecutionException;
22 import java.util.concurrent.TimeUnit;
23 import java.util.concurrent.TimeoutException;
24 import javax.annotation.Nullable;
25 import org.junit.BeforeClass;
26 import org.junit.Test;
27 import org.opendaylight.controller.md.sal.dom.api.DOMEvent;
28 import org.opendaylight.controller.md.sal.dom.api.DOMNotification;
29 import org.opendaylight.controller.md.sal.dom.api.DOMNotificationListener;
30 import org.opendaylight.controller.md.sal.dom.spi.DOMNotificationSubscriptionListener;
31 import org.opendaylight.controller.md.sal.dom.store.impl.TestModel;
32 import org.opendaylight.yangtools.concepts.ListenerRegistration;
33 import org.opendaylight.yangtools.yang.common.QName;
34 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier.NodeIdentifier;
35 import org.opendaylight.yangtools.yang.data.api.schema.ContainerNode;
36 import org.opendaylight.yangtools.yang.data.impl.schema.ImmutableNodes;
37 import org.opendaylight.yangtools.yang.data.impl.schema.builder.impl.ImmutableContainerNodeBuilder;
38 import org.opendaylight.yangtools.yang.model.api.Module;
39 import org.opendaylight.yangtools.yang.model.api.NotificationDefinition;
40 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
41 import org.opendaylight.yangtools.yang.model.api.SchemaPath;
44 * Unit tests for DOMNotificationRouter.
46 * @author Thomas Pantelis
48 public class DOMNotificationRouterTest {
49 private static final ContainerNode BODY = ImmutableContainerNodeBuilder.create().withNodeIdentifier(
50 new NodeIdentifier(QName.create(TestModel.TEST_QNAME.getModule(), "test-notification")))
51 .withChild(ImmutableNodes.leafNode(QName.create(TestModel.TEST_QNAME.getModule(), "value-leaf"), "foo"))
53 private static final Instant INSTANT = Instant.now();
55 private static SchemaPath notificationSchemaPath;
57 private final org.opendaylight.mdsal.dom.broker.DOMNotificationRouter mdsalRouter =
58 org.opendaylight.mdsal.dom.broker.DOMNotificationRouter.create(16);
59 private final DOMNotificationRouter legacyRouter =
60 DOMNotificationRouter.create(mdsalRouter, mdsalRouter, mdsalRouter);
61 private final TestLegacyDOMNotificationListener testLegacyListener = new TestLegacyDOMNotificationListener();
62 private final TestMdsalDOMNotificationListener testMdsalListener = new TestMdsalDOMNotificationListener();
65 public static void staticSetup() {
66 final SchemaContext schemaContext = TestModel.createTestContext();
68 Module testModule = schemaContext.findModule("odl-datastore-test", TestModel.TEST_QNAME.getRevision()).get();
69 NotificationDefinition notificationDefinition = null;
70 for (NotificationDefinition def: testModule.getNotifications()) {
71 if (def.getQName().getLocalName().equals("test-notification")) {
72 notificationDefinition = def;
77 assertNotNull("test-notification not found in " + testModule.getNotifications(), notificationDefinition);
78 notificationSchemaPath = notificationDefinition.getPath();
82 public void testLegacyListenerAndPublish() throws InterruptedException, ExecutionException, TimeoutException {
83 final ListenerRegistration<TestLegacyDOMNotificationListener> reg =
84 legacyRouter.registerNotificationListener(testLegacyListener, notificationSchemaPath);
86 legacyRouter.putNotification(new TestLegacyDOMNotification()).get(5, TimeUnit.SECONDS);
87 testLegacyListener.verifyReceived(notificationSchemaPath, BODY, null);
89 legacyRouter.offerNotification(new TestLegacyDOMNotification()).get(5, TimeUnit.SECONDS);
90 testLegacyListener.verifyReceived(notificationSchemaPath, BODY, null);
92 legacyRouter.offerNotification(new TestLegacyDOMNotification(), 100, TimeUnit.MILLISECONDS)
93 .get(5, TimeUnit.SECONDS);
94 testLegacyListener.verifyReceived(notificationSchemaPath, BODY, null);
96 legacyRouter.offerNotification(new TestLegacyDOMEvent()).get(5, TimeUnit.SECONDS);
97 testLegacyListener.verifyReceived(notificationSchemaPath, BODY, Date.from(INSTANT));
101 legacyRouter.offerNotification(new TestLegacyDOMNotification()).get(5, TimeUnit.SECONDS);
102 testLegacyListener.verifyNotReceived();
106 public void testLegacyListenerAndMdsalPublish()
107 throws InterruptedException, ExecutionException, TimeoutException {
108 legacyRouter.registerNotificationListener(testLegacyListener, notificationSchemaPath);
110 mdsalRouter.offerNotification(new TestMdsalDOMNotification()).get(5, TimeUnit.SECONDS);
111 testLegacyListener.verifyReceived(notificationSchemaPath, BODY, null);
113 mdsalRouter.offerNotification(new TestMdsalDOMEvent()).get(5, TimeUnit.SECONDS);
114 testLegacyListener.verifyReceived(notificationSchemaPath, BODY, Date.from(INSTANT));
118 public void testMdsalListenerAndLegacyPublish()
119 throws InterruptedException, ExecutionException, TimeoutException {
120 mdsalRouter.registerNotificationListener(testMdsalListener, notificationSchemaPath);
122 legacyRouter.offerNotification(new TestLegacyDOMNotification()).get(5, TimeUnit.SECONDS);
123 testMdsalListener.verifyReceived(notificationSchemaPath, BODY, null);
125 legacyRouter.offerNotification(new TestLegacyDOMEvent()).get(5, TimeUnit.SECONDS);
126 testMdsalListener.verifyReceived(notificationSchemaPath, BODY, INSTANT);
130 public void testRegisterSubscriptionListener() throws InterruptedException, ExecutionException, TimeoutException {
131 TestLegacyDOMNotificationSubscriptionListener listener = new TestLegacyDOMNotificationSubscriptionListener();
132 final ListenerRegistration<TestLegacyDOMNotificationSubscriptionListener> subscriptionReg =
133 legacyRouter.registerSubscriptionListener(listener);
135 listener.verifyReceived();
137 final ListenerRegistration<TestLegacyDOMNotificationListener> listenerReg =
138 legacyRouter.registerNotificationListener(testLegacyListener, notificationSchemaPath);
140 listener.verifyReceived(notificationSchemaPath);
144 listener.verifyReceived();
146 subscriptionReg.close();
148 legacyRouter.registerNotificationListener(testLegacyListener, notificationSchemaPath);
150 listener.verifyNotReceived();
153 private static class TestLegacyDOMNotificationListener implements DOMNotificationListener {
154 SettableFuture<DOMNotification> receivedNotification = SettableFuture.create();
157 public void onNotification(DOMNotification notification) {
158 receivedNotification.set(notification);
161 void verifyReceived(SchemaPath path, ContainerNode body, @Nullable Date eventTime)
162 throws InterruptedException, ExecutionException, TimeoutException {
163 final DOMNotification actual = receivedNotification.get(5, TimeUnit.SECONDS);
164 assertEquals(path, actual.getType());
165 assertEquals(body, actual.getBody());
167 if (eventTime != null) {
168 assertTrue("Expected DOMEvent", actual instanceof DOMEvent);
169 assertEquals(eventTime, ((DOMEvent)actual).getEventTime());
171 assertFalse("Unexpected DOMEvent", actual instanceof DOMEvent);
174 receivedNotification = SettableFuture.create();
177 void verifyNotReceived() {
178 Uninterruptibles.sleepUninterruptibly(200, TimeUnit.MILLISECONDS);
179 assertFalse("Unexpected notification", receivedNotification.isDone());
183 private static class TestMdsalDOMNotificationListener
184 implements org.opendaylight.mdsal.dom.api.DOMNotificationListener {
185 SettableFuture<org.opendaylight.mdsal.dom.api.DOMNotification> receivedNotification = SettableFuture.create();
188 public void onNotification(org.opendaylight.mdsal.dom.api.DOMNotification notification) {
189 receivedNotification.set(notification);
192 void verifyReceived(SchemaPath path, ContainerNode body, @Nullable Instant eventTime)
193 throws InterruptedException, ExecutionException, TimeoutException {
194 final org.opendaylight.mdsal.dom.api.DOMNotification actual =
195 receivedNotification.get(5, TimeUnit.SECONDS);
196 assertEquals(path, actual.getType());
197 assertEquals(body, actual.getBody());
199 if (eventTime != null) {
200 assertTrue("Expected DOMEvent", actual instanceof org.opendaylight.mdsal.dom.api.DOMEvent);
201 assertEquals(eventTime, ((org.opendaylight.mdsal.dom.api.DOMEvent)actual).getEventInstant());
203 assertFalse("Unexpected DOMEvent", actual instanceof org.opendaylight.mdsal.dom.api.DOMEvent);
206 receivedNotification = SettableFuture.create();
210 private static class TestLegacyDOMNotificationSubscriptionListener implements DOMNotificationSubscriptionListener {
211 SettableFuture<Set<SchemaPath>> receivedNotification = SettableFuture.create();
214 public void onSubscriptionChanged(Set<SchemaPath> currentTypes) {
215 receivedNotification.set(currentTypes);
218 void verifyReceived(SchemaPath... paths)
219 throws InterruptedException, ExecutionException, TimeoutException {
220 final Set<SchemaPath> actual = receivedNotification.get(5, TimeUnit.SECONDS);
221 assertEquals(ImmutableSet.copyOf(paths), actual);
222 receivedNotification = SettableFuture.create();
225 void verifyNotReceived() {
226 Uninterruptibles.sleepUninterruptibly(200, TimeUnit.MILLISECONDS);
227 assertFalse("Unexpected notification", receivedNotification.isDone());
231 private static class TestLegacyDOMNotification implements DOMNotification {
233 public SchemaPath getType() {
234 return notificationSchemaPath;
238 public ContainerNode getBody() {
243 private static class TestLegacyDOMEvent extends TestLegacyDOMNotification implements DOMEvent {
245 public Date getEventTime() {
246 return Date.from(INSTANT);
250 private static class TestMdsalDOMNotification implements org.opendaylight.mdsal.dom.api.DOMNotification {
252 public SchemaPath getType() {
253 return notificationSchemaPath;
257 public ContainerNode getBody() {
262 private static class TestMdsalDOMEvent extends TestMdsalDOMNotification
263 implements org.opendaylight.mdsal.dom.api.DOMEvent {
265 public Instant getEventInstant() {