Merge "BUG 1839 - HTTP delete of non existing data"
[controller.git] / opendaylight / netconf / netconf-ssh / src / main / java / org / opendaylight / controller / 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.controller.netconf.ssh;
10
11 import io.netty.buffer.ByteBuf;
12 import io.netty.buffer.Unpooled;
13 import io.netty.channel.ChannelHandlerContext;
14 import io.netty.channel.ChannelInboundHandlerAdapter;
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.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandlerReader;
19 import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandlerWriter;
20 import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
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 and reads from delegate server and writes to remote client
26  */
27 final class SshProxyClientHandler extends ChannelInboundHandlerAdapter {
28
29     private static final Logger logger = LoggerFactory.getLogger(SshProxyClientHandler.class);
30
31     private final IoInputStream in;
32     private final IoOutputStream out;
33
34     private AsyncSshHandlerReader asyncSshHandlerReader;
35     private AsyncSshHandlerWriter asyncSshHandlerWriter;
36
37     private final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader;
38     private final ExitCallback callback;
39
40     public SshProxyClientHandler(final IoInputStream in, final IoOutputStream out,
41                                  final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader,
42                                  final ExitCallback callback) {
43         this.in = in;
44         this.out = out;
45         this.netconfHelloMessageAdditionalHeader = netconfHelloMessageAdditionalHeader;
46         this.callback = callback;
47     }
48
49     @Override
50     public void channelActive(final ChannelHandlerContext ctx) throws Exception {
51         writeAdditionalHeader(ctx);
52
53         asyncSshHandlerWriter = new AsyncSshHandlerWriter(out);
54         asyncSshHandlerReader = new AsyncSshHandlerReader(new AutoCloseable() {
55             @Override
56             public void close() throws Exception {
57                 // Close both sessions (delegate server and remote client)
58                 ctx.fireChannelInactive();
59                 ctx.disconnect();
60                 ctx.close();
61                 asyncSshHandlerReader.close();
62                 asyncSshHandlerWriter.close();
63             }
64         }, new AsyncSshHandlerReader.ReadMsgHandler() {
65             @Override
66             public void onMessageRead(final ByteBuf msg) {
67                 if(logger.isTraceEnabled()) {
68                     logger.trace("Forwarding message for client: {} on channel: {}, message: {}",
69                             netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel(), AsyncSshHandlerWriter.byteBufToString(msg));
70                 }
71                 // Just forward to delegate
72                 ctx.writeAndFlush(msg);
73             }
74         }, "ssh" + netconfHelloMessageAdditionalHeader.getAddress(), in);
75
76
77         super.channelActive(ctx);
78     }
79
80     private void writeAdditionalHeader(final ChannelHandlerContext ctx) {
81         ctx.writeAndFlush(Unpooled.copiedBuffer(netconfHelloMessageAdditionalHeader.toFormattedString().getBytes()));
82     }
83
84     @Override
85     public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
86        asyncSshHandlerWriter.write(ctx, msg, ctx.newPromise());
87     }
88
89     @Override
90     public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
91         logger.debug("Internal connection to netconf server was dropped for client: {} on channel: ",
92                 netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel());
93         callback.onExit(1, "Internal connection to netconf server was dropped for client: " +
94                 netconfHelloMessageAdditionalHeader.getAddress() + " on channel: " + ctx.channel());
95         super.channelInactive(ctx);
96     }
97
98
99 }