Fix findbugs violations in netconf
[netconf.git] / netconf / netconf-ssh / src / main / java / org / opendaylight / netconf / ssh / SshProxyClientHandler.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
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
7  */
8
9 package org.opendaylight.netconf.ssh;
10
11 import io.netty.buffer.Unpooled;
12 import io.netty.channel.ChannelHandlerContext;
13 import io.netty.channel.ChannelInboundHandlerAdapter;
14 import java.nio.charset.StandardCharsets;
15 import org.apache.sshd.common.io.IoInputStream;
16 import org.apache.sshd.common.io.IoOutputStream;
17 import org.apache.sshd.server.ExitCallback;
18 import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader;
19 import org.opendaylight.netconf.nettyutil.handler.ssh.client.AsyncSshHandlerReader;
20 import org.opendaylight.netconf.nettyutil.handler.ssh.client.AsyncSshHandlerWriter;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
23
24 /**
25  * Netty handler that reads SSH from remote client and writes to delegate server
26  * and reads from delegate server and writes to remote client.
27  */
28 final class SshProxyClientHandler extends ChannelInboundHandlerAdapter {
29
30     private static final Logger LOG = LoggerFactory.getLogger(SshProxyClientHandler.class);
31
32     private final IoInputStream in;
33     private final IoOutputStream out;
34
35     private AsyncSshHandlerReader asyncSshHandlerReader;
36     private AsyncSshHandlerWriter asyncSshHandlerWriter;
37
38     private final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader;
39     private final ExitCallback callback;
40
41     SshProxyClientHandler(final IoInputStream in, final IoOutputStream out,
42                           final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader,
43                           final ExitCallback callback) {
44         this.in = in;
45         this.out = out;
46         this.netconfHelloMessageAdditionalHeader = netconfHelloMessageAdditionalHeader;
47         this.callback = callback;
48     }
49
50     @Override
51     public void channelActive(final ChannelHandlerContext ctx) throws Exception {
52         writeAdditionalHeader(ctx);
53
54         asyncSshHandlerWriter = new AsyncSshHandlerWriter(out);
55         asyncSshHandlerReader = new AsyncSshHandlerReader(() -> {
56             // Close both sessions (delegate server and remote client)
57             ctx.fireChannelInactive();
58             ctx.disconnect();
59             ctx.close();
60             asyncSshHandlerReader.close();
61             asyncSshHandlerWriter.close();
62         }, msg -> {
63             if (LOG.isTraceEnabled()) {
64                 LOG.trace("Forwarding message for client: {} on channel: {}, message: {}",
65                         netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel(),
66                         AsyncSshHandlerWriter.byteBufToString(msg));
67             }
68             // Just forward to delegate
69             ctx.writeAndFlush(msg);
70         }, "ssh" + netconfHelloMessageAdditionalHeader.getAddress(), in);
71
72
73         super.channelActive(ctx);
74     }
75
76     private void writeAdditionalHeader(final ChannelHandlerContext ctx) {
77         ctx.writeAndFlush(Unpooled.copiedBuffer(netconfHelloMessageAdditionalHeader.toFormattedString()
78                 .getBytes(StandardCharsets.UTF_8)));
79     }
80
81     @Override
82     public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
83         asyncSshHandlerWriter.write(ctx, msg, ctx.newPromise());
84     }
85
86     @Override
87     public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
88         LOG.debug("Internal connection to netconf server was dropped for client: {} on channel: ",
89                 netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel());
90         callback.onExit(1, "Internal connection to netconf server was dropped for client: "
91                 + netconfHelloMessageAdditionalHeader.getAddress() + " on channel: " + ctx.channel());
92         super.channelInactive(ctx);
93     }
94
95
96 }