2 * Copyright (c) 2017 Red Hat, 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.restconf.nb.rfc8040.streams.listeners;
10 import static org.junit.Assert.assertTrue;
11 import static org.junit.Assert.fail;
13 import com.google.common.util.concurrent.Uninterruptibles;
14 import java.io.IOException;
15 import java.net.URISyntaxException;
16 import java.nio.file.Files;
17 import java.nio.file.Paths;
18 import java.util.concurrent.CountDownLatch;
19 import java.util.concurrent.TimeUnit;
20 import org.json.JSONException;
21 import org.json.JSONObject;
22 import org.junit.AfterClass;
23 import org.junit.Before;
24 import org.junit.BeforeClass;
25 import org.junit.Test;
26 import org.opendaylight.mdsal.binding.api.DataBroker;
27 import org.opendaylight.mdsal.binding.api.WriteTransaction;
28 import org.opendaylight.mdsal.binding.dom.adapter.test.AbstractConcurrentDataBrokerTest;
29 import org.opendaylight.mdsal.common.api.LogicalDatastoreType;
30 import org.opendaylight.mdsal.dom.api.DOMDataBroker;
31 import org.opendaylight.mdsal.dom.api.DOMDataTreeChangeService;
32 import org.opendaylight.mdsal.dom.api.DOMDataTreeIdentifier;
33 import org.opendaylight.restconf.api.query.ChangedLeafNodesOnlyParam;
34 import org.opendaylight.restconf.api.query.LeafNodesOnlyParam;
35 import org.opendaylight.restconf.api.query.SkipNotificationDataParam;
36 import org.opendaylight.restconf.api.query.StartTimeParam;
37 import org.opendaylight.restconf.nb.rfc8040.NotificationQueryParams;
38 import org.opendaylight.restconf.nb.rfc8040.databind.DatabindContext;
39 import org.opendaylight.restconf.nb.rfc8040.databind.DatabindProvider;
40 import org.opendaylight.yang.gen.v1.augment.instance.identifier.patch.module.rev220218.PatchCont1Builder;
41 import org.opendaylight.yang.gen.v1.augment.instance.identifier.patch.module.rev220218.patch.cont.patch.choice1.PatchCase1Builder;
42 import org.opendaylight.yang.gen.v1.augment.instance.identifier.patch.module.rev220218.patch.cont.patch.choice2.PatchCase11Builder;
43 import org.opendaylight.yang.gen.v1.augment.instance.identifier.patch.module.rev220218.patch.cont.patch.choice2.patch.case11.patch.sub.choice11.PatchSubCase11Builder;
44 import org.opendaylight.yang.gen.v1.augment.instance.identifier.patch.module.rev220218.patch.cont.patch.choice2.patch.case11.patch.sub.choice11.patch.sub.case11.patch.sub.sub.choice11.PatchSubSubCase11Builder;
45 import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.PatchCont;
46 import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.PatchContBuilder;
47 import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.patch.cont.MyList1;
48 import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.patch.cont.MyList1Builder;
49 import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.patch.cont.MyList1Key;
50 import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping.NotificationOutputType;
51 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
52 import org.opendaylight.yangtools.yang.binding.util.BindingMap;
53 import org.opendaylight.yangtools.yang.common.QName;
54 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
55 import org.opendaylight.yangtools.yang.model.api.EffectiveModelContext;
56 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
57 import org.skyscreamer.jsonassert.JSONAssert;
58 import org.slf4j.Logger;
59 import org.slf4j.LoggerFactory;
60 import org.xmlunit.assertj.XmlAssert;
62 public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
63 private static final Logger LOG = LoggerFactory.getLogger(ListenerAdapterTest.class);
65 private static final String JSON_NOTIF_LEAVES_CREATE = "/listener-adapter-test/notif-leaves-create.json";
66 private static final String JSON_NOTIF_LEAVES_UPDATE = "/listener-adapter-test/notif-leaves-update.json";
67 private static final String JSON_NOTIF_LEAVES_DELETE = "/listener-adapter-test/notif-leaves-delete.json";
68 private static final String JSON_NOTIF_CHANGED_LEAVES_CREATE =
69 "/listener-adapter-test/notif-changed-leaves-create.json";
70 private static final String JSON_NOTIF_CHANGED_LEAVES_UPDATE =
71 "/listener-adapter-test/notif-changed-leaves-update.json";
72 private static final String JSON_NOTIF_CHANGED_LEAVES_DELETE =
73 "/listener-adapter-test/notif-changed-leaves-delete.json";
75 private static final String XML_NOTIF_LEAVES_CREATE = "/listener-adapter-test/notif-leaves-create.xml";
76 private static final String XML_NOTIF_LEAVES_UPDATE = "/listener-adapter-test/notif-leaves-update.xml";
77 private static final String XML_NOTIF_LEAVES_DELETE = "/listener-adapter-test/notif-leaves-delete.xml";
78 private static final String XML_NOTIF_CHANGED_LEAVES_CREATE =
79 "/listener-adapter-test/notif-changed-leaves-create.xml";
80 private static final String XML_NOTIF_CHANGED_LEAVES_UPDATE =
81 "/listener-adapter-test/notif-changed-leaves-update.xml";
82 private static final String XML_NOTIF_CHANGED_LEAVES_DELETE =
83 "/listener-adapter-test/notif-changed-leaves-delete.xml";
85 private static final String JSON_NOTIF_CONT_CREATE = "/listener-adapter-test/notif-cont-create.json";
86 private static final String JSON_NOTIF_CONT_UPDATE = "/listener-adapter-test/notif-cont-update.json";
87 private static final String JSON_NOTIF_CONT_DELETE = "/listener-adapter-test/notif-cont-delete.json";
88 private static final String JSON_NOTIF_LIST_CREATE = "/listener-adapter-test/notif-list-create.json";
89 private static final String JSON_NOTIF_LIST_UPDATE = "/listener-adapter-test/notif-list-update.json";
90 private static final String JSON_NOTIF_LIST_DELETE = "/listener-adapter-test/notif-list-delete.json";
91 private static final String JSON_NOTIF_WITHOUT_DATA_CONT_CREATE =
92 "/listener-adapter-test/notif-without-data-cont-create.json";
93 private static final String JSON_NOTIF_WITHOUT_DATA_CONT_UPDATE =
94 "/listener-adapter-test/notif-without-data-cont-update.json";
95 private static final String JSON_NOTIF_WITHOUT_DATA_CONT_DELETE =
96 "/listener-adapter-test/notif-without-data-cont-delete.json";
97 private static final String JSON_NOTIF_WITHOUT_DATA_LIST_CREATE =
98 "/listener-adapter-test/notif-without-data-list-create.json";
99 private static final String JSON_NOTIF_WITHOUT_DATA_LIST_UPDATE =
100 "/listener-adapter-test/notif-without-data-list-update.json";
101 private static final String JSON_NOTIF_WITHOUT_DATA_LIST_DELETE =
102 "/listener-adapter-test/notif-without-data-list-delete.json";
104 private static final String XML_NOTIF_CONT_CREATE = "/listener-adapter-test/notif-cont-create.xml";
105 private static final String XML_NOTIF_CONT_UPDATE = "/listener-adapter-test/notif-cont-update.xml";
106 private static final String XML_NOTIF_CONT_DELETE = "/listener-adapter-test/notif-cont-delete.xml";
107 private static final String XML_NOTIF_LIST_CREATE = "/listener-adapter-test/notif-list-create.xml";
108 private static final String XML_NOTIF_LIST_UPDATE = "/listener-adapter-test/notif-list-update.xml";
109 private static final String XML_NOTIF_LIST_DELETE = "/listener-adapter-test/notif-list-delete.xml";
110 private static final String XML_NOTIF_WITHOUT_DATA_CONT_CREATE =
111 "/listener-adapter-test/notif-without-data-cont-create.xml";
112 private static final String XML_NOTIF_WITHOUT_DATA_CONT_UPDATE =
113 "/listener-adapter-test/notif-without-data-cont-update.xml";
114 private static final String XML_NOTIF_WITHOUT_DATA_CONT_DELETE =
115 "/listener-adapter-test/notif-without-data-cont-delete.xml";
116 private static final String XML_NOTIF_WITHOUT_DATA_LIST_CREATE =
117 "/listener-adapter-test/notif-without-data-list-create.xml";
118 private static final String XML_NOTIF_WITHOUT_DATA_LIST_UPDATE =
119 "/listener-adapter-test/notif-without-data-list-update.xml";
120 private static final String XML_NOTIF_WITHOUT_DATA_LIST_DELETE =
121 "/listener-adapter-test/notif-without-data-list-delete.xml";
123 private static final YangInstanceIdentifier PATCH_CONT_YIID = YangInstanceIdentifier.of(PatchCont.QNAME);
125 private static final YangInstanceIdentifier MY_LIST1_YIID = YangInstanceIdentifier.builder()
126 .node(PatchCont.QNAME)
128 .nodeWithKey(MyList1.QNAME, QName.create(PatchCont.QNAME.getModule(), "name"), "Althea")
131 private static EffectiveModelContext SCHEMA_CONTEXT;
133 private DataBroker dataBroker;
134 private DOMDataBroker domDataBroker;
135 private DatabindProvider databindProvider;
138 public static void beforeClass() {
139 SCHEMA_CONTEXT = YangParserTestUtils.parseYangResourceDirectory("/instanceidentifier/yang");
143 public static void afterClass() {
144 SCHEMA_CONTEXT = null;
148 public void setUp() throws Exception {
149 dataBroker = getDataBroker();
150 domDataBroker = getDomBroker();
151 databindProvider = () -> DatabindContext.ofModel(SCHEMA_CONTEXT);
154 class ListenerAdapterTester extends ListenerAdapter {
156 private volatile String lastNotification;
157 private CountDownLatch notificationLatch = new CountDownLatch(1);
159 ListenerAdapterTester(final YangInstanceIdentifier path, final String streamName,
160 final NotificationOutputType outputType,
161 final boolean leafNodesOnly, final boolean skipNotificationData) {
162 super(path, streamName, outputType);
163 setQueryParams(NotificationQueryParams.of(StartTimeParam.forUriValue("1970-01-01T00:00:00Z"), null, null,
164 LeafNodesOnlyParam.of(leafNodesOnly), SkipNotificationDataParam.of(skipNotificationData), null));
167 ListenerAdapterTester(final YangInstanceIdentifier path, final String streamName,
168 final NotificationOutputType outputType,
169 final boolean changedLeafNodesOnly) {
170 super(path, streamName, outputType);
171 setQueryParams(NotificationQueryParams.of(StartTimeParam.forUriValue("1970-01-01T00:00:00Z"), null, null,
172 null, null, ChangedLeafNodesOnlyParam.of(changedLeafNodesOnly)));
176 protected void post(final String data) {
177 lastNotification = data;
178 notificationLatch.countDown();
181 public void assertGot(final String json) throws JSONException {
182 // FIXME: use awaitility
183 if (!Uninterruptibles.awaitUninterruptibly(notificationLatch, 500, TimeUnit.SECONDS)) {
184 fail("Timed out waiting for notification for: " + json);
187 LOG.info("lastNotification: {}", lastNotification);
188 final String withFakeDate = withFakeDate(lastNotification);
189 LOG.info("Comparing: \n{}\n{}", json, withFakeDate);
191 JSONAssert.assertEquals(json, withFakeDate, false);
192 lastNotification = null;
193 notificationLatch = new CountDownLatch(1);
196 public void assertXmlSimilar(final String xml) {
197 awaitUntilNotification(xml);
199 LOG.info("lastNotification: {}", lastNotification);
200 final String withFakeDate = withFakeXmlDate(lastNotification);
201 LOG.info("Comparing: \n{}\n{}", xml, withFakeDate);
203 XmlAssert.assertThat(xml).and(withFakeDate).ignoreWhitespace().ignoreChildNodesOrder().areSimilar();
204 lastNotification = null;
205 notificationLatch = new CountDownLatch(1);
208 public String awaitUntilNotification(final String xml) {
209 // FIXME: use awaitility
210 if (!Uninterruptibles.awaitUninterruptibly(notificationLatch, 500, TimeUnit.SECONDS)) {
211 fail("Timed out waiting for notification for: " + xml);
213 return lastNotification;
216 public void resetLatch() {
217 notificationLatch = new CountDownLatch(1);
222 public void testJsonNotifsLeaves() throws Exception {
223 ListenerAdapterTester adapter = new ListenerAdapterTester(PATCH_CONT_YIID, "Casey", NotificationOutputType.JSON,
225 adapter.setCloseVars(domDataBroker, databindProvider);
227 final DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
228 .getInstance(DOMDataTreeChangeService.class);
229 final DOMDataTreeIdentifier root =
230 new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
231 changeService.registerDataTreeChangeListener(root, adapter);
233 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
234 final InstanceIdentifier<PatchCont> iid = InstanceIdentifier.create(PatchCont.class);
235 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
236 .addAugmentation(new PatchCont1Builder()
237 .setPatchChoice1(new PatchCase1Builder().setCaseLeaf1("ChoiceLeaf").build())
238 .setLeaf1("AugmentLeaf")
240 .setMyList1(BindingMap.of(new MyList1Builder().setMyLeaf11("Jed").setName("Althea").build()))
242 writeTransaction.commit();
243 adapter.assertGot(getNotifJson(JSON_NOTIF_LEAVES_CREATE));
245 writeTransaction = dataBroker.newWriteOnlyTransaction();
246 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
247 .addAugmentation(new PatchCont1Builder()
248 .setPatchChoice1(new PatchCase1Builder().setCaseLeaf1("ChoiceUpdate").build())
249 .setLeaf1("AugmentLeaf")
251 .setMyList1(BindingMap.of(new MyList1Builder().setMyLeaf12("Bertha").setName("Althea").build()))
253 writeTransaction.commit();
254 adapter.assertGot(getNotifJson(JSON_NOTIF_LEAVES_UPDATE));
256 writeTransaction = dataBroker.newWriteOnlyTransaction();
257 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
258 writeTransaction.commit();
259 adapter.assertGot(getNotifJson(JSON_NOTIF_LEAVES_DELETE));
263 public void testJsonNotifsChangedLeaves() throws Exception {
264 ListenerAdapterTester adapter = new ListenerAdapterTester(PATCH_CONT_YIID, "Casey", NotificationOutputType.JSON,
266 adapter.setCloseVars(domDataBroker, databindProvider);
268 final DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
269 .getInstance(DOMDataTreeChangeService.class);
270 final DOMDataTreeIdentifier root =
271 new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
272 changeService.registerDataTreeChangeListener(root, adapter);
274 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
275 final InstanceIdentifier<PatchCont> iid = InstanceIdentifier.create(PatchCont.class);
276 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
277 .addAugmentation(new PatchCont1Builder()
278 .setPatchChoice2(new PatchCase11Builder()
279 .setPatchSubChoice11(new PatchSubCase11Builder()
280 .setPatchSubSubChoice11(new PatchSubSubCase11Builder().setCaseLeaf11("ChoiceLeaf").build())
283 .setLeaf1("AugmentLeaf")
285 .setMyList1(BindingMap.of(new MyList1Builder().setMyLeaf11("Jed").setName("Althea").build()))
287 writeTransaction.commit();
288 adapter.assertGot(getNotifJson(JSON_NOTIF_CHANGED_LEAVES_CREATE));
290 writeTransaction = dataBroker.newWriteOnlyTransaction();
291 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
292 .addAugmentation(new PatchCont1Builder()
293 .setPatchChoice2(new PatchCase11Builder()
294 .setPatchSubChoice11(new PatchSubCase11Builder()
295 .setPatchSubSubChoice11(new PatchSubSubCase11Builder().setCaseLeaf11("ChoiceUpdate").build())
298 .setLeaf1("AugmentLeaf")
300 .setMyList1(BindingMap.of(new MyList1Builder().setMyLeaf12("Bertha").setName("Althea").build()))
302 writeTransaction.commit();
303 adapter.assertGot(getNotifJson(JSON_NOTIF_CHANGED_LEAVES_UPDATE));
305 writeTransaction = dataBroker.newWriteOnlyTransaction();
306 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
307 writeTransaction.commit();
308 adapter.assertGot(getNotifJson(JSON_NOTIF_CHANGED_LEAVES_DELETE));
312 public void testXmlLeavesOnly() throws Exception {
313 ListenerAdapterTester adapter = new ListenerAdapterTester(PATCH_CONT_YIID, "Casey", NotificationOutputType.XML,
315 adapter.setCloseVars(domDataBroker, databindProvider);
317 DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
318 .getInstance(DOMDataTreeChangeService.class);
319 DOMDataTreeIdentifier root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
320 changeService.registerDataTreeChangeListener(root, adapter);
321 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
322 final InstanceIdentifier<PatchCont> iid = InstanceIdentifier.create(PatchCont.class);
323 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
324 .addAugmentation(new PatchCont1Builder()
325 .setPatchChoice1(new PatchCase1Builder().setCaseLeaf1("ChoiceLeaf").build())
326 .setLeaf1("AugmentLeaf")
328 .setMyList1(BindingMap.of(new MyList1Builder().setMyLeaf11("Jed").setName("Althea").build()))
330 writeTransaction.commit();
331 adapter.assertXmlSimilar(getResultXml(XML_NOTIF_LEAVES_CREATE));
333 writeTransaction = dataBroker.newWriteOnlyTransaction();
334 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
335 .addAugmentation(new PatchCont1Builder()
336 .setPatchChoice1(new PatchCase1Builder().setCaseLeaf1("ChoiceUpdate").build())
337 .setLeaf1("AugmentLeaf")
339 .setMyList1(BindingMap.of(new MyList1Builder().setMyLeaf12("Bertha").setName("Althea").build()))
341 writeTransaction.commit();
342 adapter.assertXmlSimilar(getResultXml(XML_NOTIF_LEAVES_UPDATE));
344 writeTransaction = dataBroker.newWriteOnlyTransaction();
345 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
346 writeTransaction.commit();
348 // xmlunit cannot compare deeper children it seems out of the box so just check the iid encoding
349 final String notification = adapter.awaitUntilNotification("");
350 assertTrue(notification.contains("instance-identifier-patch-module:my-leaf12"));
351 assertTrue(notification.contains("instance-identifier-patch-module:my-leaf11"));
352 assertTrue(notification.contains("instance-identifier-patch-module:name"));
353 assertTrue(notification.contains("augment-instance-identifier-patch-module:case-leaf1"));
354 assertTrue(notification.contains("augment-instance-identifier-patch-module:leaf1"));
358 public void testXmlChangedLeavesOnly() throws Exception {
359 ListenerAdapterTester adapter = new ListenerAdapterTester(PATCH_CONT_YIID, "Casey", NotificationOutputType.XML,
361 adapter.setCloseVars(domDataBroker, databindProvider);
363 DOMDataTreeChangeService changeService = domDataBroker.getExtensions()
364 .getInstance(DOMDataTreeChangeService.class);
365 DOMDataTreeIdentifier root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID);
366 changeService.registerDataTreeChangeListener(root, adapter);
367 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
368 final InstanceIdentifier<PatchCont> iid = InstanceIdentifier.create(PatchCont.class);
369 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
370 .addAugmentation(new PatchCont1Builder()
371 .setPatchChoice2(new PatchCase11Builder()
372 .setPatchSubChoice11(new PatchSubCase11Builder()
373 .setPatchSubSubChoice11(new PatchSubSubCase11Builder().setCaseLeaf11("ChoiceLeaf").build())
376 .setLeaf1("AugmentLeaf")
378 .setMyList1(BindingMap.of(new MyList1Builder().setMyLeaf11("Jed").setName("Althea").build()))
380 writeTransaction.commit();
381 adapter.assertXmlSimilar(getResultXml(XML_NOTIF_CHANGED_LEAVES_CREATE));
383 writeTransaction = dataBroker.newWriteOnlyTransaction();
384 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, iid, new PatchContBuilder()
385 .addAugmentation(new PatchCont1Builder()
386 .setPatchChoice2(new PatchCase11Builder()
387 .setPatchSubChoice11(new PatchSubCase11Builder()
388 .setPatchSubSubChoice11(new PatchSubSubCase11Builder().setCaseLeaf11("ChoiceUpdate").build())
391 .setLeaf1("AugmentLeaf")
393 .setMyList1(BindingMap.of(new MyList1Builder().setMyLeaf12("Bertha").setName("Althea").build()))
395 writeTransaction.commit();
396 adapter.assertXmlSimilar(getResultXml(XML_NOTIF_CHANGED_LEAVES_UPDATE));
398 writeTransaction = dataBroker.newWriteOnlyTransaction();
399 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
400 writeTransaction.commit();
401 // xmlunit cannot compare deeper children it seems out of the box so just check the iid encoding
402 final String notification = adapter.awaitUntilNotification("");
404 assertTrue(notification.contains("instance-identifier-patch-module:my-leaf11"));
405 assertTrue(notification.contains("instance-identifier-patch-module:my-leaf12"));
406 assertTrue(notification.contains("instance-identifier-patch-module:name"));
407 assertTrue(notification.contains("augment-instance-identifier-patch-module:case-leaf11"));
408 assertTrue(notification.contains("augment-instance-identifier-patch-module:patch-choice2"));
409 assertTrue(notification.contains("augment-instance-identifier-patch-module:patch-sub-choice11"));
410 assertTrue(notification.contains("augment-instance-identifier-patch-module:patch-sub-sub-choice11"));
411 assertTrue(notification.contains("augment-instance-identifier-patch-module:leaf1"));
415 public void testJsonContNotifications() throws Exception {
416 jsonNotifications(PATCH_CONT_YIID, false, JSON_NOTIF_CONT_CREATE,
417 JSON_NOTIF_CONT_UPDATE, JSON_NOTIF_CONT_DELETE);
421 public void testJsonListNotifications() throws Exception {
422 jsonNotifications(MY_LIST1_YIID, false, JSON_NOTIF_LIST_CREATE,
423 JSON_NOTIF_LIST_UPDATE, JSON_NOTIF_LIST_DELETE);
427 public void testJsonContNotificationsWithoutData() throws Exception {
428 jsonNotifications(PATCH_CONT_YIID, true, JSON_NOTIF_WITHOUT_DATA_CONT_CREATE,
429 JSON_NOTIF_WITHOUT_DATA_CONT_UPDATE, JSON_NOTIF_WITHOUT_DATA_CONT_DELETE);
433 public void testJsonListNotificationsWithoutData() throws Exception {
434 jsonNotifications(MY_LIST1_YIID, true, JSON_NOTIF_WITHOUT_DATA_LIST_CREATE,
435 JSON_NOTIF_WITHOUT_DATA_LIST_UPDATE, JSON_NOTIF_WITHOUT_DATA_LIST_DELETE);
439 public void testXmlContNotifications() throws Exception {
440 xmlNotifications(PATCH_CONT_YIID, false, XML_NOTIF_CONT_CREATE,
441 XML_NOTIF_CONT_UPDATE, XML_NOTIF_CONT_DELETE);
445 public void testXmlListNotifications() throws Exception {
446 xmlNotifications(MY_LIST1_YIID, false, XML_NOTIF_LIST_CREATE,
447 XML_NOTIF_LIST_UPDATE, XML_NOTIF_LIST_DELETE);
451 public void testXmlContNotificationsWithoutData() throws Exception {
452 xmlNotifications(PATCH_CONT_YIID, true, XML_NOTIF_WITHOUT_DATA_CONT_CREATE,
453 XML_NOTIF_WITHOUT_DATA_CONT_UPDATE, XML_NOTIF_WITHOUT_DATA_CONT_DELETE);
457 public void testXmlListNotificationsWithoutData() throws Exception {
458 xmlNotifications(MY_LIST1_YIID, true, XML_NOTIF_WITHOUT_DATA_LIST_CREATE,
459 XML_NOTIF_WITHOUT_DATA_LIST_UPDATE, XML_NOTIF_WITHOUT_DATA_LIST_DELETE);
462 static String withFakeDate(final String in) throws JSONException {
463 final JSONObject doc = new JSONObject(in);
464 final JSONObject notification =
465 doc.getJSONObject("urn-ietf-params-xml-ns-netconf-notification-1.0:notification");
466 if (notification == null) {
469 notification.put("event-time", "someDate");
470 return doc.toString();
473 static String withFakeXmlDate(final String in) {
474 return in.replaceAll("<eventTime>.*</eventTime>", "<eventTime>someDate</eventTime>");
477 private String getNotifJson(final String path) throws IOException, URISyntaxException, JSONException {
478 return withFakeDate(Files.readString(Paths.get(getClass().getResource(path).toURI())));
481 private String getResultXml(final String path) throws IOException, URISyntaxException, JSONException {
482 return withFakeXmlDate(Files.readString(Paths.get(getClass().getResource(path).toURI())));
485 private void jsonNotifications(final YangInstanceIdentifier pathYiid, final boolean skipData,
486 final String jsonNotifCreate, final String jsonNotifUpdate, final String jsonNotifDelete) throws Exception {
487 final var adapter = new ListenerAdapterTester(pathYiid, "Casey",
488 NotificationOutputType.JSON, false, skipData);
489 adapter.setCloseVars(domDataBroker, databindProvider);
491 final var changeService = domDataBroker.getExtensions()
492 .getInstance(DOMDataTreeChangeService.class);
493 final var root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, pathYiid);
494 changeService.registerDataTreeChangeListener(root, adapter);
496 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
497 MyList1Builder builder = new MyList1Builder().setMyLeaf11("Jed").setName("Althea");
498 final var iid = InstanceIdentifier.create(PatchCont.class)
499 .child(MyList1.class, new MyList1Key("Althea"));
500 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, builder.build());
501 writeTransaction.commit();
502 adapter.assertGot(getNotifJson(jsonNotifCreate));
504 writeTransaction = dataBroker.newWriteOnlyTransaction();
505 builder = new MyList1Builder().withKey(new MyList1Key("Althea")).setMyLeaf12("Bertha");
506 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, iid, builder.build());
507 writeTransaction.commit();
508 adapter.assertGot(getNotifJson(jsonNotifUpdate));
510 writeTransaction = dataBroker.newWriteOnlyTransaction();
511 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
512 writeTransaction.commit();
513 adapter.assertGot(getNotifJson(jsonNotifDelete));
516 private void xmlNotifications(final YangInstanceIdentifier pathYiid, final boolean skipData,
517 final String xmlNotifCreate, final String xmlNotifUpdate, final String xmlNotifDelete) throws Exception {
518 final var adapter = new ListenerAdapterTester(pathYiid, "Casey", NotificationOutputType.XML,
520 adapter.setCloseVars(domDataBroker, databindProvider);
522 final var changeService = domDataBroker.getExtensions()
523 .getInstance(DOMDataTreeChangeService.class);
524 final var root = new DOMDataTreeIdentifier(LogicalDatastoreType.CONFIGURATION, pathYiid);
525 changeService.registerDataTreeChangeListener(root, adapter);
527 WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
528 MyList1Builder builder = new MyList1Builder().setMyLeaf11("Jed").setName("Althea");
529 final var iid = InstanceIdentifier.create(PatchCont.class)
530 .child(MyList1.class, new MyList1Key("Althea"));
531 writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, builder.build());
532 writeTransaction.commit();
533 adapter.assertXmlSimilar(getResultXml(xmlNotifCreate));
535 writeTransaction = dataBroker.newWriteOnlyTransaction();
536 builder = new MyList1Builder().withKey(new MyList1Key("Althea")).setMyLeaf12("Bertha");
537 writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, iid, builder.build());
538 writeTransaction.commit();
539 adapter.assertXmlSimilar(getResultXml(xmlNotifUpdate));
541 writeTransaction = dataBroker.newWriteOnlyTransaction();
542 writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
543 writeTransaction.commit();
544 adapter.assertXmlSimilar(getResultXml(xmlNotifDelete));