2 * Copyright (c) 2015 Cisco Systems, 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.netconf.mdsal.notification.impl;
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.Mockito.doNothing;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.verify;
16 import static org.mockito.Mockito.verifyNoMoreInteractions;
18 import com.google.common.collect.Lists;
19 import java.text.SimpleDateFormat;
20 import java.time.Instant;
21 import java.time.format.DateTimeParseException;
22 import java.util.ArrayList;
23 import java.util.Date;
24 import java.util.Iterator;
25 import org.junit.Assert;
26 import org.junit.Test;
27 import org.junit.runner.RunWith;
28 import org.mockito.Mock;
29 import org.mockito.junit.MockitoJUnitRunner;
30 import org.opendaylight.mdsal.binding.dom.codec.impl.DefaultBindingDOMCodecFactory;
31 import org.opendaylight.mdsal.binding.generator.impl.DefaultBindingRuntimeGenerator;
32 import org.opendaylight.netconf.mdsal.notification.impl.ops.NotificationsTransformUtil;
33 import org.opendaylight.netconf.notifications.BaseNotificationPublisherRegistration;
34 import org.opendaylight.netconf.notifications.NetconfNotification;
35 import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
36 import org.opendaylight.netconf.notifications.NetconfNotificationListener;
37 import org.opendaylight.netconf.notifications.NetconfNotificationRegistry;
38 import org.opendaylight.netconf.notifications.NotificationListenerRegistration;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netconf.notification._1._0.rev080714.StreamNameType;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.netmod.notification.rev080714.netconf.streams.Stream;
41 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChange;
42 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfCapabilityChangeBuilder;
43 import org.opendaylight.yangtools.yang.parser.impl.YangParserFactoryImpl;
45 @RunWith(MockitoJUnitRunner.class)
46 public class NetconfNotificationManagerTest {
48 public static final String RFC3339_DATE_FORMAT_WITH_MILLIS_BLUEPRINT = "yyyy-MM-dd'T'HH:mm:ss.SSSXXX";
50 private NetconfNotificationRegistry notificationRegistry;
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();
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"
98 final Date apply = NetconfNotification.RFC3339_DATE_PARSER.apply(time);
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);
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);
122 // Testing wrong values
123 for (final String time : Lists.newArrayList(
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"
132 NetconfNotification.RFC3339_DATE_PARSER.apply(time);
133 } catch (final DateTimeParseException e) {
136 fail("Should have thrown an exception; value= " + time);
141 public void testNotificationListeners() throws Exception {
142 final NetconfNotificationManager netconfNotificationManager = createManager();
143 final BaseNotificationPublisherRegistration baseNotificationPublisherRegistration =
144 netconfNotificationManager.registerBaseNotificationPublisher();
146 final NetconfCapabilityChangeBuilder capabilityChangedBuilder = new NetconfCapabilityChangeBuilder();
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);
155 verify(listener).onNotification(any(StreamNameType.class), any(NetconfNotification.class));
157 notificationListenerRegistration.close();
159 baseNotificationPublisherRegistration.onCapabilityChanged(notification);
160 verifyNoMoreInteractions(listener);
164 public void testClose() throws Exception {
165 final NetconfNotificationManager netconfNotificationManager = createManager();
167 final BaseNotificationPublisherRegistration baseNotificationPublisherRegistration =
168 netconfNotificationManager.registerBaseNotificationPublisher();
170 final NetconfNotificationListener listener = mock(NetconfNotificationListener.class);
172 netconfNotificationManager
173 .registerNotificationListener(NetconfNotificationManager.BASE_NETCONF_STREAM.getName(), listener);
175 final NetconfNotificationCollector.NetconfNotificationStreamListener streamListener =
176 mock(NetconfNotificationCollector.NetconfNotificationStreamListener.class);
177 doNothing().when(streamListener).onStreamUnregistered(any(StreamNameType.class));
178 doNothing().when(streamListener).onStreamRegistered(any(Stream.class));
179 netconfNotificationManager.registerStreamListener(streamListener);
181 verify(streamListener).onStreamRegistered(NetconfNotificationManager.BASE_NETCONF_STREAM);
183 netconfNotificationManager.close();
185 verify(streamListener).onStreamUnregistered(NetconfNotificationManager.BASE_NETCONF_STREAM.getName());
188 baseNotificationPublisherRegistration.onCapabilityChanged(new NetconfCapabilityChangeBuilder().build());
189 } catch (final IllegalStateException e) {
190 // Exception should be thrown after manager is closed
194 fail("Publishing into a closed manager should fail");
198 public void testStreamListeners() throws Exception {
199 final NetconfNotificationManager netconfNotificationManager = createManager();
201 final NetconfNotificationCollector.NetconfNotificationStreamListener streamListener =
202 mock(NetconfNotificationCollector.NetconfNotificationStreamListener.class);
203 doNothing().when(streamListener).onStreamRegistered(any(Stream.class));
204 doNothing().when(streamListener).onStreamUnregistered(any(StreamNameType.class));
206 netconfNotificationManager.registerStreamListener(streamListener);
208 final BaseNotificationPublisherRegistration baseNotificationPublisherRegistration =
209 netconfNotificationManager.registerBaseNotificationPublisher();
211 verify(streamListener).onStreamRegistered(NetconfNotificationManager.BASE_NETCONF_STREAM);
214 baseNotificationPublisherRegistration.close();
216 verify(streamListener).onStreamUnregistered(NetconfNotificationManager.BASE_STREAM_NAME);
219 private static NetconfNotificationManager createManager() {
220 return new NetconfNotificationManager(new NotificationsTransformUtil(new YangParserFactoryImpl(),
221 new DefaultBindingRuntimeGenerator(), new DefaultBindingDOMCodecFactory()));