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
9 package org.opendaylight.netconf.impl;
11 import static org.mockito.ArgumentMatchers.any;
12 import static org.mockito.ArgumentMatchers.eq;
13 import static org.mockito.Mockito.doNothing;
14 import static org.mockito.Mockito.verify;
16 import io.netty.channel.ChannelHandler;
17 import io.netty.channel.ChannelInboundHandlerAdapter;
18 import io.netty.channel.ChannelOutboundHandlerAdapter;
19 import io.netty.channel.embedded.EmbeddedChannel;
20 import org.junit.Assert;
21 import org.junit.Before;
22 import org.junit.Test;
23 import org.mockito.Mock;
24 import org.mockito.MockitoAnnotations;
25 import org.opendaylight.netconf.api.NetconfMessage;
26 import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
27 import org.opendaylight.netconf.api.xml.XmlUtil;
28 import org.opendaylight.netconf.nettyutil.AbstractChannelInitializer;
29 import org.opendaylight.netconf.nettyutil.handler.NetconfEXICodec;
30 import org.opendaylight.netconf.nettyutil.handler.NetconfEXIToMessageDecoder;
31 import org.opendaylight.netconf.nettyutil.handler.NetconfMessageToEXIEncoder;
32 import org.opendaylight.netconf.nettyutil.handler.NetconfMessageToXMLEncoder;
33 import org.opendaylight.netconf.nettyutil.handler.NetconfXMLToMessageDecoder;
34 import org.opendaylight.netconf.nettyutil.handler.exi.EXIParameters;
35 import org.opendaylight.netconf.notifications.NetconfNotification;
36 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.extension.rev131210.NetconfTcp;
37 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.NetconfSsh;
38 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.netconf.monitoring.rev101004.netconf.state.sessions.Session;
39 import org.w3c.dom.Document;
41 public class NetconfServerSessionTest {
43 private static final String HOST = "127.0.0.1";
44 private static final String PORT = "17830";
45 private static final String SSH_TRANSPORT = "ssh";
46 private static final String TCP_TRANSPORT = "tcp";
47 private static final String SESSION_ID = "1";
48 private static final String USER = "admin";
49 private NetconfServerSession session;
50 private EmbeddedChannel channel;
51 private NetconfMessage msg;
53 private NetconfServerSessionListener listener;
56 public void setUp() throws Exception {
57 MockitoAnnotations.initMocks(this);
58 final NetconfHelloMessageAdditionalHeader header =
59 new NetconfHelloMessageAdditionalHeader(USER, HOST, PORT, SSH_TRANSPORT, SESSION_ID);
60 channel = new EmbeddedChannel();
61 session = new NetconfServerSession(listener, channel, 1L, header);
62 doNothing().when(listener).onSessionUp(any());
63 msg = new NetconfMessage(XmlUtil.readXmlToDocument("<rpc-reply></rpc-reply>"));
67 public void testSessionUp() throws Exception {
69 verify(listener).onSessionUp(session);
73 public void testDelayedClose() throws Exception {
74 doNothing().when(listener).onSessionTerminated(eq(session), any());
75 session.delayedClose();
76 session.sendMessage(msg);
77 channel.runPendingTasks();
78 final Object o = channel.readOutbound();
79 Assert.assertEquals(msg, o);
80 verify(listener).onSessionTerminated(eq(session), any());
84 public void testSendMessage() throws Exception {
85 session.sendMessage(msg);
86 channel.runPendingTasks();
87 final Object o = channel.readOutbound();
88 Assert.assertEquals(msg, o);
92 public void testSendNotification() throws Exception {
93 doNothing().when(listener).onNotification(any(), any());
94 final Document msgDoc = XmlUtil.readXmlToDocument("<notification></notification>");
95 final NetconfNotification notif = new NetconfNotification(msgDoc);
96 session.sendMessage(notif);
97 channel.runPendingTasks();
98 final Object o = channel.readOutbound();
99 Assert.assertEquals(notif, o);
100 verify(listener).onNotification(session, notif);
104 public void testOnIncommingRpcSuccess() throws Exception {
106 final Session managementSession = this.session.toManagementSession();
107 this.session.onIncommingRpcSuccess();
108 final Session afterRpcSuccess = this.session.toManagementSession();
109 Assert.assertEquals(managementSession.getInRpcs().getValue().toJava() + 1,
110 afterRpcSuccess.getInRpcs().getValue().longValue());
114 public void testOnIncommingRpcFail() throws Exception {
116 final Session managementSession = this.session.toManagementSession();
117 this.session.onIncommingRpcFail();
118 final Session afterRpcSuccess = this.session.toManagementSession();
119 Assert.assertEquals(managementSession.getInBadRpcs().getValue().toJava() + 1,
120 afterRpcSuccess.getInBadRpcs().getValue().longValue());
124 public void testOnOutgoingRpcError() throws Exception {
126 final Session managementSession = this.session.toManagementSession();
127 this.session.onOutgoingRpcError();
128 final Session afterRpcSuccess = this.session.toManagementSession();
129 Assert.assertEquals(managementSession.getOutRpcErrors().getValue().toJava() + 1,
130 afterRpcSuccess.getOutRpcErrors().getValue().longValue());
134 public void testToManagementSession() throws Exception {
135 final NetconfHelloMessageAdditionalHeader header =
136 new NetconfHelloMessageAdditionalHeader(USER, HOST, PORT, TCP_TRANSPORT, SESSION_ID);
137 final EmbeddedChannel ch = new EmbeddedChannel();
138 final NetconfServerSession tcpSession = new NetconfServerSession(listener, ch, 1L, header);
139 tcpSession.sessionUp();
140 final Session managementSession = tcpSession.toManagementSession();
141 Assert.assertEquals(HOST, managementSession.getSourceHost().getIpAddress().getIpv4Address().getValue());
142 Assert.assertEquals(managementSession.getUsername(), USER);
143 Assert.assertEquals(managementSession.getSessionId().toString(), SESSION_ID);
144 Assert.assertEquals(managementSession.getTransport(), NetconfTcp.class);
147 @Test(expected = IllegalArgumentException.class)
148 public void testToManagementSessionUnknownTransport() throws Exception {
149 final NetconfHelloMessageAdditionalHeader header =
150 new NetconfHelloMessageAdditionalHeader(USER, HOST, PORT, "http", SESSION_ID);
151 final EmbeddedChannel ch = new EmbeddedChannel();
152 final NetconfServerSession tcpSession = new NetconfServerSession(listener, ch, 1L, header);
153 tcpSession.sessionUp();
154 tcpSession.toManagementSession();
159 public void testToManagementSessionIpv6() throws Exception {
160 final NetconfHelloMessageAdditionalHeader header =
161 new NetconfHelloMessageAdditionalHeader(USER, "::1", PORT, SSH_TRANSPORT, SESSION_ID);
162 final EmbeddedChannel ch = new EmbeddedChannel();
163 final NetconfServerSession tcpSession = new NetconfServerSession(listener, ch, 1L, header);
164 tcpSession.sessionUp();
165 final Session managementSession = tcpSession.toManagementSession();
166 Assert.assertEquals("::1", managementSession.getSourceHost().getIpAddress().getIpv6Address().getValue());
167 Assert.assertEquals(managementSession.getUsername(), USER);
168 Assert.assertEquals(managementSession.getSessionId().toString(), SESSION_ID);
169 Assert.assertEquals(managementSession.getTransport(), NetconfSsh.class);
173 public void testThisInstance() throws Exception {
174 Assert.assertEquals(session, session.thisInstance());
178 public void testAddExiHandlers() throws Exception {
179 channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER,
180 new NetconfXMLToMessageDecoder());
181 channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER,
182 new NetconfMessageToXMLEncoder());
183 final NetconfEXICodec codec = NetconfEXICodec.forParameters(EXIParameters.empty());
184 session.addExiHandlers(NetconfEXIToMessageDecoder.create(codec), NetconfMessageToEXIEncoder.create(codec));
188 public void testStopExiCommunication() throws Exception {
189 channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER,
190 new ChannelInboundHandlerAdapter());
191 channel.pipeline().addLast(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER,
192 new ChannelOutboundHandlerAdapter());
193 session.stopExiCommunication();
194 //handler is replaced only after next send message call
195 final ChannelHandler exiEncoder = channel.pipeline().get(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER);
196 Assert.assertTrue(ChannelOutboundHandlerAdapter.class.equals(exiEncoder.getClass()));
197 session.sendMessage(msg);
198 channel.runPendingTasks();
199 final ChannelHandler decoder = channel.pipeline().get(AbstractChannelInitializer.NETCONF_MESSAGE_DECODER);
200 Assert.assertTrue(NetconfXMLToMessageDecoder.class.equals(decoder.getClass()));
201 final ChannelHandler encoder = channel.pipeline().get(AbstractChannelInitializer.NETCONF_MESSAGE_ENCODER);
202 Assert.assertTrue(NetconfMessageToXMLEncoder.class.equals(encoder.getClass()));