Clean up NotificationMessage
[netconf.git] / netconf / mdsal-netconf-notification / src / test / java / org / opendaylight / netconf / mdsal / notification / impl / NetconfNotificationManagerTest.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 package org.opendaylight.netconf.mdsal.notification.impl;
9
10 import static org.junit.Assert.assertEquals;
11 import static org.junit.Assert.assertThrows;
12 import static org.mockito.ArgumentMatchers.any;
13 import static org.mockito.ArgumentMatchers.eq;
14 import static org.mockito.Mockito.doNothing;
15 import static org.mockito.Mockito.mock;
16 import static org.mockito.Mockito.never;
17 import static org.mockito.Mockito.verify;
18 import static org.mockito.Mockito.verifyNoMoreInteractions;
19
20 import java.text.SimpleDateFormat;
21 import java.time.Instant;
22 import java.time.format.DateTimeParseException;
23 import java.util.Date;
24 import java.util.List;
25 import org.junit.Test;
26 import org.junit.runner.RunWith;
27 import org.mockito.junit.MockitoJUnitRunner;
28 import org.opendaylight.mdsal.binding.dom.codec.impl.di.DefaultBindingDOMCodecFactory;
29 import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
30 import org.opendaylight.netconf.api.messages.NotificationMessage;
31 import org.opendaylight.netconf.api.xml.XmlUtil;
32 import org.opendaylight.netconf.notifications.BaseNotificationPublisherRegistration;
33 import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
34 import org.opendaylight.netconf.notifications.NetconfNotificationListener;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.StreamBuilder;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
40 import org.opendaylight.yangtools.yang.parser.api.YangParserException;
41 import org.opendaylight.yangtools.yang.parser.impl.DefaultYangParserFactory;
42
43 @RunWith(MockitoJUnitRunner.class)
44 public class NetconfNotificationManagerTest {
45     public static final String RFC3339_DATE_FORMAT_WITH_MILLIS_BLUEPRINT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
46
47     @Test
48     public void testEventTime() throws Exception {
49         //Testing values with SimpleDateFormat
50         final var iterator = List.of(
51                 "2001-07-04T12:08:56.235-07:00",
52                 "2015-10-23T09:42:27.671+00:00",
53                 "1970-01-01T17:17:22.229+00:00",
54                 "1937-01-01T12:00:27.870+00:20",
55                 "2015-06-30T23:59:59.000+00:00",
56                 "1996-12-19T16:39:57.000-08:00",
57                 "2015-10-23T09:42:27.000+00:00",
58                 "2015-10-23T09:42:27.200+00:00",
59                 "1985-04-12T23:20:50.520+00:00",
60                 // Values with leap second
61                 "2001-07-04T23:59:59.235-07:00",
62                 "1990-12-31T23:59:59.000-08:00",
63                 "2015-10-23T23:59:59.671+00:00",
64                 "1970-01-01T23:59:59.229+00:00",
65                 "1937-01-01T23:59:59.870+00:20",
66                 "1990-12-31T23:59:59.000+00:00",
67                 "2015-10-23T23:59:59.200+00:00",
68                 "1985-04-12T23:59:59.520+00:00").iterator();
69
70         // Testing correct values
71         for (final String time : List.of(
72                 "2001-07-04T12:08:56.235-07:00",
73                 "2015-10-23T09:42:27.67175+00:00",
74                 "1970-01-01T17:17:22.229568+00:00",
75                 "1937-01-01T12:00:27.87+00:20",
76                 "2015-06-30T23:59:59Z",
77                 "1996-12-19T16:39:57-08:00",
78                 "2015-10-23T09:42:27Z",
79                 "2015-10-23T09:42:27.200001Z",
80                 "1985-04-12T23:20:50.52Z",
81                 // Values with leap second
82                 "2001-07-04T23:59:60.235-07:00",
83                 "1990-12-31T23:59:60-08:00",
84                 "2015-10-23T23:59:60.67175+00:00",
85                 "1970-01-01T23:59:60.229568+00:00",
86                 "1937-01-01T23:59:60.87+00:20",
87                 "1990-12-31T23:59:60Z",
88                 "2015-10-23T23:59:60.20001Z",
89                 "1985-04-12T23:59:60.52Z"
90         )) {
91             final var apply = NotificationMessage.RFC3339_DATE_PARSER.apply(time);
92             final var parse = new SimpleDateFormat(RFC3339_DATE_FORMAT_WITH_MILLIS_BLUEPRINT).parse(iterator.next());
93             assertEquals(parse, Date.from(apply));
94             // Testing that we're consistent from formatting to parsing.
95             final String dateString = NotificationMessage.RFC3339_DATE_FORMATTER.apply(apply);
96             final var date1 = NotificationMessage.RFC3339_DATE_PARSER.apply(dateString);
97             final String dateString1 = NotificationMessage.RFC3339_DATE_FORMATTER.apply(date1);
98             assertEquals(apply, date1);
99             assertEquals(dateString, dateString1);
100         }
101
102         // Testing that we're consistent from formatting to parsing.
103         final var date0 = Instant.ofEpochMilli(0);
104         final String dateString0 = NotificationMessage.RFC3339_DATE_FORMATTER.apply(date0);
105         final var date1 = NotificationMessage.RFC3339_DATE_PARSER.apply(dateString0);
106         final String dateString1 = NotificationMessage.RFC3339_DATE_FORMATTER.apply(date1);
107         assertEquals(date0, date1);
108         assertEquals(dateString0, dateString1);
109
110         // Testing wrong values
111         for (final String time : List.of(
112                 "0",
113                 "205-10-23T09:42:27.67175+00:00",
114                 "1970-01-01T17:60:22.229568+00:00",
115                 "1937-01-01T32:00:27.87+00:20",
116                 "2060-13-31T15:59:90-08:00",
117                 "1990-12-31T23:58:60Z")) {
118             assertThrows(DateTimeParseException.class, () -> NotificationMessage.RFC3339_DATE_PARSER.apply(time));
119         }
120     }
121
122     @Test
123     public void testNotificationListeners() throws Exception {
124         final NetconfNotificationManager netconfNotificationManager = createManager();
125         final BaseNotificationPublisherRegistration baseNotificationPublisherRegistration =
126                 netconfNotificationManager.registerBaseNotificationPublisher();
127
128         final NetconfCapabilityChangeBuilder capabilityChangedBuilder = new NetconfCapabilityChangeBuilder();
129
130         final NetconfNotificationListener listener = mock(NetconfNotificationListener.class);
131         doNothing().when(listener).onNotification(any(StreamNameType.class), any(NotificationMessage.class));
132
133         final NetconfCapabilityChange notification = capabilityChangedBuilder.build();
134
135         try (var reg = netconfNotificationManager.registerNotificationListener(
136                 NetconfNotificationManager.BASE_NETCONF_STREAM.getName(), listener)) {
137             baseNotificationPublisherRegistration.onCapabilityChanged(notification);
138
139             verify(listener).onNotification(any(StreamNameType.class), any(NotificationMessage.class));
140         }
141
142         baseNotificationPublisherRegistration.onCapabilityChanged(notification);
143         verifyNoMoreInteractions(listener);
144     }
145
146     @Test
147     public void testCustomNotificationListeners() throws Exception {
148         final NetconfNotificationManager netconfNotificationManager = createManager();
149
150         final StreamNameType testStreamName = new StreamNameType("TEST_STREAM");
151         final Stream testStream = new StreamBuilder().setName(testStreamName).build();
152
153         final NetconfNotificationListener listenerBase = mock(NetconfNotificationListener.class);
154         netconfNotificationManager.registerNotificationListener(
155             NetconfNotificationManager.BASE_NETCONF_STREAM.getName(), listenerBase);
156
157         final NetconfNotificationListener listener = mock(NetconfNotificationListener.class);
158         netconfNotificationManager.registerNotificationListener(testStream.getName(), listener);
159
160         doNothing().when(listener).onNotification(eq(testStreamName), any(NotificationMessage.class));
161
162         final NotificationMessage notification = new NotificationMessage(
163             XmlUtil.readXmlToDocument("<notification/>"));
164         netconfNotificationManager.onNotification(testStream.getName(), notification);
165
166         verify(listener).onNotification(eq(testStream.getName()), eq(notification));
167
168         netconfNotificationManager.close();
169         netconfNotificationManager.onNotification(testStream.getName(), notification);
170
171         verifyNoMoreInteractions(listener);
172         verify(listenerBase, never()).onNotification(eq(testStream.getName()), eq(notification));
173     }
174
175     @Test
176     public void testClose() throws Exception {
177         final NetconfNotificationManager netconfNotificationManager = createManager();
178
179         final BaseNotificationPublisherRegistration baseNotificationPublisherRegistration =
180                 netconfNotificationManager.registerBaseNotificationPublisher();
181
182         final NetconfNotificationListener listener = mock(NetconfNotificationListener.class);
183
184         netconfNotificationManager
185                 .registerNotificationListener(NetconfNotificationManager.BASE_NETCONF_STREAM.getName(), listener);
186
187         final NetconfNotificationCollector.NetconfNotificationStreamListener streamListener =
188                 mock(NetconfNotificationCollector.NetconfNotificationStreamListener.class);
189         doNothing().when(streamListener).onStreamUnregistered(any(StreamNameType.class));
190         doNothing().when(streamListener).onStreamRegistered(any(Stream.class));
191         netconfNotificationManager.registerStreamListener(streamListener);
192
193         verify(streamListener).onStreamRegistered(NetconfNotificationManager.BASE_NETCONF_STREAM);
194
195         netconfNotificationManager.close();
196
197         verify(streamListener).onStreamUnregistered(NetconfNotificationManager.BASE_NETCONF_STREAM.getName());
198
199         final var change = new NetconfCapabilityChangeBuilder().build();
200         assertThrows(IllegalStateException.class,
201             () -> baseNotificationPublisherRegistration.onCapabilityChanged(change));
202     }
203
204     @Test
205     public void testStreamListeners() throws Exception {
206         final NetconfNotificationManager netconfNotificationManager = createManager();
207
208         final NetconfNotificationCollector.NetconfNotificationStreamListener streamListener =
209                 mock(NetconfNotificationCollector.NetconfNotificationStreamListener.class);
210         doNothing().when(streamListener).onStreamRegistered(any(Stream.class));
211         doNothing().when(streamListener).onStreamUnregistered(any(StreamNameType.class));
212
213         netconfNotificationManager.registerStreamListener(streamListener);
214
215         final BaseNotificationPublisherRegistration baseNotificationPublisherRegistration =
216                 netconfNotificationManager.registerBaseNotificationPublisher();
217
218         verify(streamListener).onStreamRegistered(NetconfNotificationManager.BASE_NETCONF_STREAM);
219
220
221         baseNotificationPublisherRegistration.close();
222
223         verify(streamListener).onStreamUnregistered(NetconfNotificationManager.BASE_STREAM_NAME);
224     }
225
226     private static NetconfNotificationManager createManager() throws YangParserException {
227         return new NetconfNotificationManager(new DefaultYangParserFactory(),
228             new DefaultBindingRuntimeGenerator(), new DefaultBindingDOMCodecFactory());
229     }
230 }