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