Add unit tests for ListenerAdapter
[netconf.git] / restconf / restconf-nb-bierman02 / src / test / java / org / opendaylight / netconf / sal / streams / listeners / ListenerAdapterTest.java
1 /*
2  * Copyright (c) 2017 Red Hat, 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.netconf.sal.streams.listeners;
10
11 import static java.time.Instant.EPOCH;
12
13 import java.io.IOException;
14 import java.net.URISyntaxException;
15 import java.net.URL;
16 import java.nio.charset.StandardCharsets;
17 import java.nio.file.Files;
18 import java.nio.file.Paths;
19 import java.util.Optional;
20
21 import org.json.JSONObject;
22 import org.junit.Before;
23 import org.junit.Test;
24 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
25 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
26 import org.opendaylight.controller.md.sal.binding.test.AbstractConcurrentDataBrokerTest;
27 import org.opendaylight.controller.md.sal.common.api.data.AsyncDataBroker;
28 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
29 import org.opendaylight.controller.md.sal.dom.api.DOMDataBroker;
30 import org.opendaylight.netconf.sal.restconf.impl.ControllerContext;
31 import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.PatchCont;
32 import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.patch.cont.MyList1;
33 import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.patch.cont.MyList1Builder;
34 import org.opendaylight.yang.gen.v1.instance.identifier.patch.module.rev151121.patch.cont.MyList1Key;
35 import org.opendaylight.yang.gen.v1.urn.sal.restconf.event.subscription.rev140708.NotificationOutputTypeGrouping;
36 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
37 import org.opendaylight.yangtools.yang.data.api.YangInstanceIdentifier;
38 import org.opendaylight.yangtools.yang.model.api.SchemaContext;
39 import org.opendaylight.yangtools.yang.test.util.YangParserTestUtils;
40 import org.skyscreamer.jsonassert.JSONAssert;
41
42 public class ListenerAdapterTest extends AbstractConcurrentDataBrokerTest {
43
44     private static final String JSON_NOTIF_LEAVES_CREATE = "/listener-adapter-test/notif-leaves-create.json";
45     private static final String JSON_NOTIF_LEAVES_UPDATE =  "/listener-adapter-test/notif-leaves-update.json";
46     private static final String JSON_NOTIF_LEAVES_DEL =  "/listener-adapter-test/notif-leaves-del.json";
47     private static final String JSON_NOTIF_CREATE = "/listener-adapter-test/notif-create.json";
48     private static final String JSON_NOTIF_UPDATE = "/listener-adapter-test/notif-update.json";
49     private static final String JSON_NOTIF_DEL = "/listener-adapter-test/notif-del.json";
50
51     private static YangInstanceIdentifier PATCH_CONT_YIID =
52             YangInstanceIdentifier.create(new YangInstanceIdentifier.NodeIdentifier(PatchCont.QNAME));
53
54     private DataBroker dataBroker;
55     private DOMDataBroker domDataBroker;
56
57     @Before
58     public void setUp() throws Exception {
59         dataBroker = getDataBroker();
60         domDataBroker = getDomBroker();
61         SchemaContext sc = YangParserTestUtils.parseYangSource(
62                 "/instanceidentifier/yang/instance-identifier-patch-module.yang");
63         ControllerContext.getInstance().setGlobalSchema(sc);
64     }
65
66     class ListenerAdapterTester extends ListenerAdapter {
67
68         private String lastNotification = null;
69
70         ListenerAdapterTester(YangInstanceIdentifier path, String streamName,
71                               NotificationOutputTypeGrouping.NotificationOutputType outputType, boolean leafNodesOnly) {
72             super(path, streamName, outputType);
73             setQueryParams(EPOCH, Optional.empty(), Optional.empty(), leafNodesOnly);
74         }
75
76         @Override
77         protected void post(final Event event) {
78             this.lastNotification = event.getData();
79         }
80
81         public void assertGot(String json) throws Exception {
82             long start = System.currentTimeMillis();
83             while (true) {
84                 if (lastNotification != null) {
85                     break;
86                 }
87                 if (System.currentTimeMillis() - start > 1000) {
88                     throw new Exception("TIMED OUT waiting for notification with " + json);
89                 }
90                 Thread.currentThread().sleep(200);
91             }
92             JSONAssert.assertEquals(json, withFakeDate(lastNotification), false);
93             this.lastNotification = null;
94         }
95     }
96
97     static String withFakeDate(String in) {
98         JSONObject doc = new JSONObject(in);
99         JSONObject notification = doc.getJSONObject("notification");
100         if (notification == null) {
101             return in;
102         }
103         notification.put("eventTime", "someDate");
104         return doc.toString();
105     }
106
107     private String getNotifJson(String path) throws IOException, URISyntaxException {
108         URL url = getClass().getResource(path);
109         byte[] bytes = Files.readAllBytes(Paths.get(url.toURI()));
110         return withFakeDate(new String(bytes, StandardCharsets.UTF_8));
111     }
112
113     @Test
114     public void testJsonNotifsLeaves() throws Exception {
115
116         ListenerAdapterTester adapter = new ListenerAdapterTester(PATCH_CONT_YIID, "Casey",
117                                         NotificationOutputTypeGrouping.NotificationOutputType.JSON, true);
118         domDataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID, adapter,
119                                                         AsyncDataBroker.DataChangeScope.SUBTREE);
120
121         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
122         MyList1Builder builder = new MyList1Builder().setMyLeaf11("Jed").setName("Althea");
123         InstanceIdentifier<MyList1> iid = InstanceIdentifier.create(PatchCont.class)
124                 .child(MyList1.class, new MyList1Key("Althea"));
125         writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, builder.build(), true);
126         writeTransaction.submit();
127         adapter.assertGot(getNotifJson(JSON_NOTIF_LEAVES_CREATE));
128
129         writeTransaction = dataBroker.newWriteOnlyTransaction();
130         builder.setMyLeaf12("Bertha");
131         writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, iid, builder.build(), true);
132         writeTransaction.submit();
133         adapter.assertGot(getNotifJson(JSON_NOTIF_LEAVES_UPDATE));
134
135         writeTransaction = dataBroker.newWriteOnlyTransaction();
136         writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
137         writeTransaction.submit();
138         adapter.assertGot(getNotifJson(JSON_NOTIF_LEAVES_DEL));
139     }
140
141     @Test
142     public void testJsonNotifs() throws Exception {
143
144         ListenerAdapterTester adapter = new ListenerAdapterTester(PATCH_CONT_YIID, "Casey",
145                 NotificationOutputTypeGrouping.NotificationOutputType.JSON, false);
146         domDataBroker.registerDataChangeListener(LogicalDatastoreType.CONFIGURATION, PATCH_CONT_YIID, adapter,
147                 AsyncDataBroker.DataChangeScope.SUBTREE);
148
149         WriteTransaction writeTransaction = dataBroker.newWriteOnlyTransaction();
150         MyList1Builder builder = new MyList1Builder().setMyLeaf11("Jed").setName("Althea");
151         InstanceIdentifier<MyList1> iid = InstanceIdentifier.create(PatchCont.class)
152                 .child(MyList1.class, new MyList1Key("Althea"));
153         writeTransaction.put(LogicalDatastoreType.CONFIGURATION, iid, builder.build(), true);
154         writeTransaction.submit();
155         adapter.assertGot(getNotifJson(JSON_NOTIF_CREATE));
156
157         writeTransaction = dataBroker.newWriteOnlyTransaction();
158         builder.setMyLeaf12("Bertha");
159         writeTransaction.merge(LogicalDatastoreType.CONFIGURATION, iid, builder.build(), true);
160         writeTransaction.submit();
161         adapter.assertGot(getNotifJson(JSON_NOTIF_UPDATE));
162
163         writeTransaction = dataBroker.newWriteOnlyTransaction();
164         writeTransaction.delete(LogicalDatastoreType.CONFIGURATION, iid);
165         writeTransaction.submit();
166         adapter.assertGot(getNotifJson(JSON_NOTIF_DEL));
167     }
168 }