X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fnetconf%2Fnetconf-netty-util%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fnetconf%2Fnettyutil%2Fhandler%2Fssh%2Fclient%2FAsyncSshHandler.java;h=064ae72bc7c512db762a45007a73e9aeebebbe45;hb=edcc020c8fda4b13f22a31d79c13feef0b53b0ee;hp=c8c912828279e72eab9ac12dba25e2a29e2c10d4;hpb=d145dc860316c87bc55e35e20b2ca0359df433f4;p=controller.git diff --git a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java index c8c9128282..064ae72bc7 100644 --- a/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java +++ b/opendaylight/netconf/netconf-netty-util/src/main/java/org/opendaylight/controller/netconf/nettyutil/handler/ssh/client/AsyncSshHandler.java @@ -101,7 +101,11 @@ public class AsyncSshHandler extends ChannelOutboundHandlerAdapter { if (future.isSuccess()) { handleSshAuthenticated(session, ctx); } else { - handleSshSetupFailure(ctx, future.getException()); + // Exception does not have to be set in the future, add simple exception in such case + final Throwable exception = future.getException() == null ? + new IllegalStateException("Authentication failed") : + future.getException(); + handleSshSetupFailure(ctx, exception); } } }); @@ -176,6 +180,7 @@ public class AsyncSshHandler extends ChannelOutboundHandlerAdapter { @Override public synchronized void connect(final ChannelHandlerContext ctx, final SocketAddress remoteAddress, final SocketAddress localAddress, final ChannelPromise promise) throws Exception { + LOG.debug("SSH session connecting on channel {}. promise: {} ", ctx.channel(), connectPromise); this.connectPromise = promise; startSsh(ctx, remoteAddress); } @@ -187,23 +192,21 @@ public class AsyncSshHandler extends ChannelOutboundHandlerAdapter { @Override public synchronized void disconnect(final ChannelHandlerContext ctx, final ChannelPromise promise) { - // Super disconnect is necessary in this case since we are using NioSocketChannel and it needs to cleanup its resources - // e.g. Socket that it tries to open in its constructor (https://bugs.opendaylight.org/show_bug.cgi?id=2430) - // TODO better solution would be to implement custom ChannelFactory + Channel that will use mina SSH lib internally: port this to custom channel implementation - try { - super.disconnect(ctx, ctx.newPromise()); - } catch (final Exception e) { - LOG.warn("Unable to cleanup all resources for channel: {}. Ignoring.", ctx.channel(), e); - } + LOG.trace("Closing SSH session on channel: {} with connect promise in state: {}", ctx.channel(), connectPromise); - if(sshReadAsyncListener != null) { - sshReadAsyncListener.close(); + // If we have already succeeded and the session was dropped after, we need to fire inactive to notify reconnect logic + if(connectPromise.isSuccess()) { + ctx.fireChannelInactive(); } if(sshWriteAsyncHandler != null) { sshWriteAsyncHandler.close(); } + if(sshReadAsyncListener != null) { + sshReadAsyncListener.close(); + } + if(session!= null && !session.isClosed() && !session.isClosing()) { session.close(false).addListener(new SshFutureListener() { @Override @@ -216,13 +219,17 @@ public class AsyncSshHandler extends ChannelOutboundHandlerAdapter { }); } - // If we have already succeeded and the session was dropped after, we need to fire inactive to notify reconnect logic - if(connectPromise.isSuccess()) { - ctx.fireChannelInactive(); + // Super disconnect is necessary in this case since we are using NioSocketChannel and it needs to cleanup its resources + // e.g. Socket that it tries to open in its constructor (https://bugs.opendaylight.org/show_bug.cgi?id=2430) + // TODO better solution would be to implement custom ChannelFactory + Channel that will use mina SSH lib internally: port this to custom channel implementation + try { + // Disconnect has to be closed after inactive channel event was fired, because it interferes with it + super.disconnect(ctx, ctx.newPromise()); + } catch (final Exception e) { + LOG.warn("Unable to cleanup all resources for channel: {}. Ignoring.", ctx.channel(), e); } channel = null; - promise.setSuccess(); LOG.debug("SSH session closed on channel: {}", ctx.channel()); }