Bug 1239 - Clean up and refactor netconf-ssh client
[controller.git] / opendaylight / netconf / netconf-netty-util / src / main / java / org / opendaylight / controller / netconf / nettyutil / handler / ssh / client / SshClientAdapter.java
index 87056db06c23aef8de11c2fe80d919fffbade208..1a2eb3f1ab43d188179351341264c0e46bc52350 100644 (file)
@@ -8,25 +8,32 @@
 
 package org.opendaylight.controller.netconf.nettyutil.handler.ssh.client;
 
+import static com.google.common.base.Preconditions.checkArgument;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
 import io.netty.buffer.ByteBuf;
 import io.netty.buffer.Unpooled;
+import io.netty.channel.ChannelFuture;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.ChannelPromise;
-
 import java.io.IOException;
 import java.io.InputStream;
 import java.io.OutputStream;
 import java.util.LinkedList;
 import java.util.Queue;
 import java.util.concurrent.atomic.AtomicBoolean;
-import org.opendaylight.controller.netconf.nettyutil.handler.ssh.virtualsocket.VirtualSocketException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 
 /**
  * Worker thread class. Handles all downstream and upstream events in SSH Netty
  * pipeline.
  */
-public class SshClientAdapter implements Runnable {
+class SshClientAdapter implements Runnable {
+    private static final Logger logger = LoggerFactory.getLogger(SshClientAdapter.class);
+
     private static final int BUFFER_SIZE = 1024;
 
     private final SshClient sshClient;
@@ -48,6 +55,7 @@ public class SshClientAdapter implements Runnable {
         this.invoker = invoker;
     }
 
+    // TODO: refactor
     public void run() {
         try {
             SshSession session = sshClient.openSession();
@@ -77,12 +85,8 @@ public class SshClientAdapter implements Runnable {
                 byteBuf.writeBytes(tranBuff);
                 ctx.fireChannelRead(byteBuf);
             }
-
-        } catch (VirtualSocketException e) {
-            // Netty closed connection prematurely.
-            // Just pass and move on.
         } catch (Exception e) {
-            throw new IllegalStateException(e);
+            logger.error("Unexpected exception", e);
         } finally {
             sshClient.close();
 
@@ -107,6 +111,7 @@ public class SshClientAdapter implements Runnable {
 
     private void writeImpl(ByteBuf message) throws IOException {
         message.getBytes(0, stdIn, message.readableBytes());
+        message.release();
         stdIn.flush();
     }
 
@@ -117,12 +122,23 @@ public class SshClientAdapter implements Runnable {
         }
     }
 
-    public void start(ChannelHandlerContext ctx) {
-        if (this.ctx != null) {
-            // context is already associated.
-            return;
+    public Thread start(ChannelHandlerContext ctx, ChannelFuture channelFuture) {
+        checkArgument(channelFuture.isSuccess());
+        checkNotNull(ctx.channel().remoteAddress());
+        synchronized (this) {
+            checkState(this.ctx == null);
+            this.ctx = ctx;
         }
-        this.ctx = ctx;
-        new Thread(this).start();
+        String threadName = toString();
+        Thread thread = new Thread(this, threadName);
+        thread.start();
+        return thread;
+    }
+
+    @Override
+    public String toString() {
+        return "SshClientAdapter{" +
+                "sshClient=" + sshClient +
+                '}';
     }
 }