2 * Copyright (c) 2016 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.server.events.mdsal;
10 import static org.junit.Assert.assertEquals;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.Mockito.doNothing;
13 import static org.mockito.Mockito.doReturn;
14 import static org.mockito.Mockito.mock;
15 import static org.mockito.Mockito.never;
16 import static org.mockito.Mockito.verify;
18 import java.util.List;
19 import org.junit.Before;
20 import org.junit.Test;
21 import org.junit.runner.RunWith;
22 import org.mockito.ArgumentCaptor;
23 import org.mockito.Mock;
24 import org.mockito.junit.MockitoJUnitRunner;
25 import org.opendaylight.mdsal.binding.api.DataBroker;
26 import org.opendaylight.mdsal.binding.api.DataObjectModification;
27 import org.opendaylight.mdsal.binding.api.DataObjectModification.ModificationType;
28 import org.opendaylight.mdsal.binding.api.DataTreeChangeListener;
29 import org.opendaylight.mdsal.binding.api.DataTreeIdentifier;
30 import org.opendaylight.mdsal.binding.api.DataTreeModification;
31 import org.opendaylight.netconf.notifications.BaseNotificationPublisherRegistration;
32 import org.opendaylight.netconf.notifications.NetconfNotificationCollector;
33 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Host;
34 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress;
35 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.SessionBuilder;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfSessionEnd;
39 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.notifications.rev120206.NetconfSessionStart;
40 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.ZeroBasedCounter32;
41 import org.opendaylight.yangtools.concepts.ListenerRegistration;
42 import org.opendaylight.yangtools.yang.common.Uint32;
43 import org.slf4j.Logger;
44 import org.slf4j.LoggerFactory;
46 @RunWith(MockitoJUnitRunner.StrictStubs.class)
47 public class SessionNotificationProducerTest {
48 private static final Logger LOG = LoggerFactory.getLogger(SessionNotificationProducerTest.class);
51 private BaseNotificationPublisherRegistration registration;
53 private ListenerRegistration<?> listenerRegistration;
55 private NetconfNotificationCollector netconfNotificationCollector;
57 private DataBroker dataBroker;
59 private SessionNotificationProducer publisher;
63 doReturn(listenerRegistration).when(dataBroker).registerDataTreeChangeListener(any(DataTreeIdentifier.class),
64 any(DataTreeChangeListener.class));
65 doNothing().when(registration).onSessionStarted(any());
66 doNothing().when(registration).onSessionEnded(any());
68 doReturn(registration).when(netconfNotificationCollector).registerBaseNotificationPublisher();
70 publisher = new SessionNotificationProducer(netconfNotificationCollector, dataBroker);
74 public void testOnDataChangedSessionCreated() throws Exception {
75 final Session session = createSession(Uint32.ONE);
76 final DataTreeModification<Session> treeChange = getTreeModification(session, ModificationType.WRITE);
77 publisher.onDataTreeChanged(List.of(treeChange));
78 ArgumentCaptor<NetconfSessionStart> captor = ArgumentCaptor.forClass(NetconfSessionStart.class);
79 verify(registration).onSessionStarted(captor.capture());
80 final NetconfSessionStart value = captor.getValue();
81 assertEquals(session.getSessionId(), value.getSessionId().getValue());
82 assertEquals(session.getSourceHost().getIpAddress(), value.getSourceHost());
83 assertEquals(session.getUsername(), value.getUsername());
87 public void testOnDataChangedSessionUpdated() throws Exception {
88 final DataTreeModification<Session> treeChange = mock(DataTreeModification.class);
89 final DataObjectModification<Session> changeObject = mock(DataObjectModification.class);
90 final Session sessionBefore = createSessionWithInRpcCount(Uint32.ONE, Uint32.ZERO);
91 final Session sessionAfter = createSessionWithInRpcCount(Uint32.ONE, Uint32.ONE);
92 doReturn(sessionBefore).when(changeObject).getDataBefore();
93 doReturn(sessionAfter).when(changeObject).getDataAfter();
94 doReturn(ModificationType.WRITE).when(changeObject).getModificationType();
95 doReturn(changeObject).when(treeChange).getRootNode();
96 publisher.onDataTreeChanged(List.of(treeChange));
97 //session didn't start, only stats changed. No notification should be produced
98 verify(registration, never()).onSessionStarted(any());
99 verify(registration, never()).onSessionEnded(any());
103 public void testOnDataChangedSessionDeleted() throws Exception {
104 final Session session = createSession(Uint32.ONE);
105 final DataTreeModification<Session> data = getTreeModification(session, ModificationType.DELETE);
106 publisher.onDataTreeChanged(List.of(data));
107 ArgumentCaptor<NetconfSessionEnd> captor = ArgumentCaptor.forClass(NetconfSessionEnd.class);
108 verify(registration).onSessionEnded(captor.capture());
109 final NetconfSessionEnd value = captor.getValue();
110 assertEquals(session.getSessionId(), value.getSessionId().getValue());
111 assertEquals(session.getSourceHost().getIpAddress(), value.getSourceHost());
112 assertEquals(session.getUsername(), value.getUsername());
115 private static Session createSession(final Uint32 id) {
116 return createSessionWithInRpcCount(id, Uint32.ZERO);
119 private static Session createSessionWithInRpcCount(final Uint32 id, final Uint32 inRpc) {
120 return new SessionBuilder()
122 .setSourceHost(new Host(new IpAddress(new Ipv4Address("0.0.0.0"))))
124 .setInRpcs(new ZeroBasedCounter32(inRpc))
128 @SuppressWarnings("unchecked")
129 private static DataTreeModification<Session> getTreeModification(final Session session,
130 final ModificationType type) {
131 final DataTreeModification<Session> treeChange = mock(DataTreeModification.class);
132 final DataObjectModification<Session> changeObject = mock(DataObjectModification.class);
135 doReturn(null).when(changeObject).getDataBefore();
136 doReturn(session).when(changeObject).getDataAfter();
139 doReturn(session).when(changeObject).getDataBefore();
142 LOG.debug("Received intentionally unhandled type: {}.", type);
144 doReturn(type).when(changeObject).getModificationType();
145 doReturn(changeObject).when(treeChange).getRootNode();