2 * Copyright (c) 2013 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.controller.netconf.it;
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertFalse;
13 import static org.junit.Assert.assertTrue;
14 import static org.mockito.Matchers.anyString;
15 import static org.mockito.Mockito.doReturn;
16 import static org.mockito.Mockito.mock;
18 import com.google.common.collect.Lists;
19 import io.netty.channel.local.LocalAddress;
20 import io.netty.util.concurrent.Future;
21 import io.netty.util.concurrent.GenericFutureListener;
22 import io.netty.util.concurrent.GlobalEventExecutor;
23 import java.io.IOException;
24 import java.net.InetSocketAddress;
25 import java.util.List;
26 import java.util.concurrent.atomic.AtomicInteger;
27 import org.junit.After;
28 import org.junit.Before;
29 import org.junit.Test;
30 import org.opendaylight.controller.netconf.api.NetconfMessage;
31 import org.opendaylight.controller.netconf.auth.AuthProvider;
32 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
33 import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
34 import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
35 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
36 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
37 import org.opendaylight.controller.netconf.client.TestingNetconfClient;
38 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
39 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
40 import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
41 import org.opendaylight.controller.netconf.ssh.authentication.PEMGenerator;
42 import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
43 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
44 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
45 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
47 public class NetconfITSecureTest extends AbstractNetconfConfigTest {
49 public static final int PORT = 12024;
50 private static final InetSocketAddress TLS_ADDRESS = new InetSocketAddress("127.0.0.1", PORT);
52 public static final String USERNAME = "user";
53 public static final String PASSWORD = "pwd";
55 private NetconfSSHServer sshServer;
58 public void setUp() throws Exception {
59 final char[] pem = PEMGenerator.generate().toCharArray();
60 sshServer = NetconfSSHServer.start(TLS_ADDRESS.getPort(), NetconfConfigUtil.getNetconfLocalAddress(), getNettyThreadgroup(), pem);
61 sshServer.setAuthProvider(getAuthProvider());
65 public void tearDown() throws Exception {
71 public void testSecure() throws Exception {
72 final NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
73 try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration())) {
74 NetconfMessage response = netconfClient.sendMessage(getGetConfig());
75 assertFalse("Unexpected error message " + XmlUtil.toString(response.getDocument()),
76 NetconfMessageUtil.isErrorMessage(response));
78 final NetconfMessage gs = new NetconfMessage(XmlUtil.readXmlToDocument("<rpc message-id=\"2\"\n" +
79 " xmlns=\"urn:ietf:params:xml:ns:netconf:base:1.0\">\n" +
80 " <get-schema xmlns=\"urn:ietf:params:xml:ns:yang:ietf-netconf-monitoring\">\n" +
81 " <identifier>config</identifier>\n" +
85 response = netconfClient.sendMessage(gs);
86 assertFalse("Unexpected error message " + XmlUtil.toString(response.getDocument()),
87 NetconfMessageUtil.isErrorMessage(response));
92 * Test all requests are handled properly and no mismatch occurs in listener
94 @Test(timeout = 3*60*1000)
95 public void testSecureStress() throws Exception {
96 final NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
97 try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration())) {
99 final AtomicInteger responseCounter = new AtomicInteger(0);
100 final List<Future<?>> futures = Lists.newArrayList();
102 final int requests = 1000;
103 for (int i = 0; i < requests; i++) {
104 final Future<NetconfMessage> netconfMessageFuture = netconfClient.sendRequest(getGetConfig());
105 futures.add(netconfMessageFuture);
106 netconfMessageFuture.addListener(new GenericFutureListener<Future<? super NetconfMessage>>() {
108 public void operationComplete(final Future<? super NetconfMessage> future) throws Exception {
109 assertTrue("Request unsuccessful " + future.cause(), future.isSuccess());
110 responseCounter.incrementAndGet();
115 for (final Future<?> future : futures) {
119 // Give future listeners some time to finish counter incrementation
122 assertEquals(requests, responseCounter.get());
126 public NetconfClientConfiguration getClientConfiguration() throws IOException {
127 final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
128 b.withAddress(TLS_ADDRESS);
129 b.withSessionListener(new SimpleNetconfClientSessionListener());
130 b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000));
131 b.withProtocol(NetconfClientConfiguration.NetconfClientProtocol.SSH);
132 b.withConnectionTimeoutMillis(5000);
133 b.withAuthHandler(getAuthHandler());
137 public AuthProvider getAuthProvider() throws Exception {
138 final AuthProvider mockAuth = mock(AuthProvider.class);
139 doReturn("mockedAuth").when(mockAuth).toString();
140 doReturn(true).when(mockAuth).authenticated(anyString(), anyString());
144 public AuthenticationHandler getAuthHandler() throws IOException {
145 return new LoginPassword(USERNAME, PASSWORD);
149 protected LocalAddress getTcpServerAddress() {
150 return NetconfConfigUtil.getNetconfLocalAddress();