org.opendaylight.controller.netconf.ssh.SshProxyClientHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.opendaylight.controller.netconf.ssh.SshProxyClientHandler.java

Source

/*
 * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
 *
 * This program and the accompanying materials are made available under the
 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
 * and is available at http://www.eclipse.org/legal/epl-v10.html
 */

package org.opendaylight.controller.netconf.ssh;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.apache.sshd.common.io.IoInputStream;
import org.apache.sshd.common.io.IoOutputStream;
import org.apache.sshd.server.ExitCallback;
import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandlerReader;
import org.opendaylight.controller.netconf.nettyutil.handler.ssh.client.AsyncSshHandlerWriter;
import org.opendaylight.controller.netconf.util.messages.NetconfHelloMessageAdditionalHeader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Netty handler that reads SSH from remote client and writes to delegate server and reads from delegate server and writes to remote client
 */
final class SshProxyClientHandler extends ChannelInboundHandlerAdapter {

    private static final Logger LOG = LoggerFactory.getLogger(SshProxyClientHandler.class);

    private final IoInputStream in;
    private final IoOutputStream out;

    private AsyncSshHandlerReader asyncSshHandlerReader;
    private AsyncSshHandlerWriter asyncSshHandlerWriter;

    private final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader;
    private final ExitCallback callback;

    public SshProxyClientHandler(final IoInputStream in, final IoOutputStream out,
            final NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader,
            final ExitCallback callback) {
        this.in = in;
        this.out = out;
        this.netconfHelloMessageAdditionalHeader = netconfHelloMessageAdditionalHeader;
        this.callback = callback;
    }

    @Override
    public void channelActive(final ChannelHandlerContext ctx) throws Exception {
        writeAdditionalHeader(ctx);

        asyncSshHandlerWriter = new AsyncSshHandlerWriter(out);
        asyncSshHandlerReader = new AsyncSshHandlerReader(new AutoCloseable() {
            @Override
            public void close() throws Exception {
                // Close both sessions (delegate server and remote client)
                ctx.fireChannelInactive();
                ctx.disconnect();
                ctx.close();
                asyncSshHandlerReader.close();
                asyncSshHandlerWriter.close();
            }
        }, new AsyncSshHandlerReader.ReadMsgHandler() {
            @Override
            public void onMessageRead(final ByteBuf msg) {
                if (LOG.isTraceEnabled()) {
                    LOG.trace("Forwarding message for client: {} on channel: {}, message: {}",
                            netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel(),
                            AsyncSshHandlerWriter.byteBufToString(msg));
                }
                // Just forward to delegate
                ctx.writeAndFlush(msg);
            }
        }, "ssh" + netconfHelloMessageAdditionalHeader.getAddress(), in);

        super.channelActive(ctx);
    }

    private void writeAdditionalHeader(final ChannelHandlerContext ctx) {
        ctx.writeAndFlush(
                Unpooled.copiedBuffer(netconfHelloMessageAdditionalHeader.toFormattedString().getBytes()));
    }

    @Override
    public void channelRead(final ChannelHandlerContext ctx, final Object msg) throws Exception {
        asyncSshHandlerWriter.write(ctx, msg, ctx.newPromise());
    }

    @Override
    public void channelInactive(final ChannelHandlerContext ctx) throws Exception {
        LOG.debug("Internal connection to netconf server was dropped for client: {} on channel: ",
                netconfHelloMessageAdditionalHeader.getAddress(), ctx.channel());
        callback.onExit(1, "Internal connection to netconf server was dropped for client: "
                + netconfHelloMessageAdditionalHeader.getAddress() + " on channel: " + ctx.channel());
        super.channelInactive(ctx);
    }

}