Merge "Startup archetype: remove 'Impl' from config subsystem Module name."
[controller.git] / opendaylight / netconf / netconf-it / src / test / java / org / opendaylight / controller / netconf / it / NetconfITSecureTest.java
index bc8efbe91535573cc18bcd00d97e43dcf91abc2f..029aefff6e3016cfde27022de2cc9c4c6e76e449 100644 (file)
@@ -21,39 +21,45 @@ import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
+import io.netty.channel.EventLoopGroup;
 import io.netty.channel.local.LocalAddress;
+import io.netty.channel.nio.NioEventLoopGroup;
 import io.netty.util.concurrent.GlobalEventExecutor;
 import java.io.IOException;
 import java.net.InetSocketAddress;
+import java.nio.file.Files;
 import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.ScheduledExecutorService;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 import java.util.concurrent.atomic.AtomicInteger;
+import org.apache.sshd.server.PasswordAuthenticator;
+import org.apache.sshd.server.keyprovider.PEMGeneratorHostKeyProvider;
+import org.apache.sshd.server.session.ServerSession;
 import org.junit.After;
 import org.junit.Before;
 import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
 import org.opendaylight.controller.netconf.api.NetconfMessage;
 import org.opendaylight.controller.netconf.auth.AuthProvider;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcher;
 import org.opendaylight.controller.netconf.client.NetconfClientDispatcherImpl;
 import org.opendaylight.controller.netconf.client.NetconfClientSessionListener;
 import org.opendaylight.controller.netconf.client.SimpleNetconfClientSessionListener;
+import org.opendaylight.controller.netconf.client.TestingNetconfClient;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfiguration;
 import org.opendaylight.controller.netconf.client.conf.NetconfClientConfigurationBuilder;
-import org.opendaylight.controller.netconf.client.TestingNetconfClient;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.AuthenticationHandler;
 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.authentication.LoginPassword;
-import org.opendaylight.controller.netconf.ssh.NetconfSSHServer;
-import org.opendaylight.controller.netconf.ssh.authentication.PEMGenerator;
+import org.opendaylight.controller.netconf.ssh.SshProxyServer;
+import org.opendaylight.controller.netconf.ssh.SshProxyServerConfigurationBuilder;
 import org.opendaylight.controller.netconf.util.messages.NetconfMessageUtil;
 import org.opendaylight.controller.netconf.util.osgi.NetconfConfigUtil;
 import org.opendaylight.controller.netconf.util.xml.XmlUtil;
 import org.opendaylight.controller.sal.connect.api.RemoteDevice;
-import org.opendaylight.controller.sal.connect.api.RemoteDeviceCommunicator;
 import org.opendaylight.controller.sal.connect.netconf.listener.NetconfDeviceCommunicator;
-import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionCapabilities;
+import org.opendaylight.controller.sal.connect.netconf.listener.NetconfSessionPreferences;
 import org.opendaylight.controller.sal.connect.util.RemoteDeviceId;
 import org.opendaylight.protocol.framework.NeverReconnectStrategy;
 import org.opendaylight.yangtools.yang.common.QName;
@@ -68,25 +74,46 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
     public static final String USERNAME = "user";
     public static final String PASSWORD = "pwd";
 
-    private NetconfSSHServer sshServer;
+    private SshProxyServer sshProxyServer;
+
+    private ExecutorService nioExec;
+    private EventLoopGroup clientGroup;
+    private ScheduledExecutorService minaTimerEx;
 
     @Before
     public void setUp() throws Exception {
-        final char[] pem = PEMGenerator.generate().toCharArray();
-        sshServer = NetconfSSHServer.start(TLS_ADDRESS.getPort(), NetconfConfigUtil.getNetconfLocalAddress(), getNettyThreadgroup(), pem);
-        sshServer.setAuthProvider(getAuthProvider());
+        nioExec = Executors.newFixedThreadPool(1);
+        clientGroup = new NioEventLoopGroup();
+        minaTimerEx = Executors.newScheduledThreadPool(1);
+        sshProxyServer = new SshProxyServer(minaTimerEx, clientGroup, nioExec);
+        sshProxyServer.bind(
+                new SshProxyServerConfigurationBuilder()
+                        .setBindingAddress(TLS_ADDRESS)
+                        .setLocalAddress(NetconfConfigUtil.getNetconfLocalAddress())
+                        .setAuthenticator(new PasswordAuthenticator() {
+                            @Override
+                            public boolean authenticate(final String username, final String password, final ServerSession session) {
+                                return true;
+                            }
+                        }
+                    )
+                        .setKeyPairProvider(new PEMGeneratorHostKeyProvider(Files.createTempFile("prefix", "suffix").toAbsolutePath().toString()))
+                        .setIdleTimeout(Integer.MAX_VALUE)
+                        .createSshProxyServerConfiguration());
     }
 
     @After
     public void tearDown() throws Exception {
-        sshServer.close();
-        sshServer.join();
+        sshProxyServer.close();
+        clientGroup.shutdownGracefully();
+        minaTimerEx.shutdownNow();
+        nioExec.shutdownNow();
     }
 
-    @Test
+    @Test(timeout = 2*60*1000)
     public void testSecure() throws Exception {
         final NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
-        try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration(new SimpleNetconfClientSessionListener()))) {
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration(new SimpleNetconfClientSessionListener(), TLS_ADDRESS))) {
             NetconfMessage response = netconfClient.sendMessage(getGetConfig());
             assertFalse("Unexpected error message " + XmlUtil.toString(response.getDocument()),
                     NetconfMessageUtil.isErrorMessage(response));
@@ -107,13 +134,13 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
     /**
      * Test all requests are handled properly and no mismatch occurs in listener
      */
-    @Test(timeout = 5*60*1000)
+    @Test(timeout = 6*60*1000)
     public void testSecureStress() throws Exception {
-        final int requests = 10000;
+        final int requests = 4000;
 
         final NetconfClientDispatcher dispatch = new NetconfClientDispatcherImpl(getNettyThreadgroup(), getNettyThreadgroup(), getHashedWheelTimer());
         final NetconfDeviceCommunicator sessionListener = getSessionListener();
-        try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration(sessionListener))) {
+        try (TestingNetconfClient netconfClient = new TestingNetconfClient("testing-ssh-client", dispatch, getClientConfiguration(sessionListener, TLS_ADDRESS))) {
 
             final AtomicInteger responseCounter = new AtomicInteger(0);
             final List<ListenableFuture<RpcResult<NetconfMessage>>> futures = Lists.newArrayList();
@@ -152,15 +179,15 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
         }
     }
 
-    private NetconfMessage changeMessageId(final NetconfMessage getConfig, final int i) throws IOException, SAXException {
+    public static NetconfMessage changeMessageId(final NetconfMessage getConfig, final int i) throws IOException, SAXException {
         String s = XmlUtil.toString(getConfig.getDocument(), false);
         s = s.replace("101", Integer.toString(i));
         return new NetconfMessage(XmlUtil.readXmlToDocument(s));
     }
 
-    public NetconfClientConfiguration getClientConfiguration(final NetconfClientSessionListener sessionListener) throws IOException {
+    static NetconfClientConfiguration getClientConfiguration(final NetconfClientSessionListener sessionListener,final InetSocketAddress tlsAddress) throws IOException {
         final NetconfClientConfigurationBuilder b = NetconfClientConfigurationBuilder.create();
-        b.withAddress(TLS_ADDRESS);
+        b.withAddress(tlsAddress);
         // Using session listener from sal-netconf-connector since stress test cannot be performed with simple listener
         b.withSessionListener(sessionListener);
         b.withReconnectStrategy(new NeverReconnectStrategy(GlobalEventExecutor.INSTANCE, 5000));
@@ -170,12 +197,9 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
         return b.build();
     }
 
-    @Mock
-    private RemoteDevice<NetconfSessionCapabilities, NetconfMessage> mockedRemoteDevice;
-
-    private NetconfDeviceCommunicator getSessionListener() {
-        MockitoAnnotations.initMocks(this);
-        doNothing().when(mockedRemoteDevice).onRemoteSessionUp(any(NetconfSessionCapabilities.class), any(RemoteDeviceCommunicator.class));
+    static NetconfDeviceCommunicator getSessionListener() {
+        RemoteDevice<NetconfSessionPreferences, NetconfMessage, NetconfDeviceCommunicator> mockedRemoteDevice = mock(RemoteDevice.class);
+        doNothing().when(mockedRemoteDevice).onRemoteSessionUp(any(NetconfSessionPreferences.class), any(NetconfDeviceCommunicator.class));
         doNothing().when(mockedRemoteDevice).onRemoteSessionDown();
         return new NetconfDeviceCommunicator(new RemoteDeviceId("secure-test"), mockedRemoteDevice);
     }
@@ -187,7 +211,7 @@ public class NetconfITSecureTest extends AbstractNetconfConfigTest {
         return mockAuth;
     }
 
-    public AuthenticationHandler getAuthHandler() throws IOException {
+    public static AuthenticationHandler getAuthHandler() throws IOException {
         return new LoginPassword(USERNAME, PASSWORD);
     }