/* * 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.netconf.ssh; import com.google.common.base.Preconditions; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; import io.netty.channel.ChannelFuture; import io.netty.channel.ChannelInitializer; import io.netty.channel.EventLoopGroup; import io.netty.channel.local.LocalAddress; import io.netty.channel.local.LocalChannel; import java.io.InputStream; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.SocketAddress; import org.apache.sshd.common.NamedFactory; import org.apache.sshd.common.io.IoInputStream; import org.apache.sshd.common.io.IoOutputStream; import org.apache.sshd.server.Environment; import org.apache.sshd.server.ExitCallback; import org.apache.sshd.server.SessionAware; import org.apache.sshd.server.command.AsyncCommand; import org.apache.sshd.server.command.Command; import org.apache.sshd.server.session.ServerSession; import org.opendaylight.netconf.api.messages.NetconfHelloMessageAdditionalHeader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * This command handles all netconf related rpc and forwards to delegate server. * Uses netty to make a local connection to delegate server. * *
* Command is Apache Mina SSH terminology for objects handling ssh data.
*/
public class RemoteNetconfCommand implements AsyncCommand, SessionAware {
private static final Logger LOG = LoggerFactory.getLogger(RemoteNetconfCommand.class);
private final EventLoopGroup clientEventGroup;
private final LocalAddress localAddress;
private IoInputStream in;
private IoOutputStream out;
private ExitCallback callback;
private NetconfHelloMessageAdditionalHeader netconfHelloMessageAdditionalHeader;
private Channel clientChannel;
private ChannelFuture clientChannelFuture;
public RemoteNetconfCommand(final EventLoopGroup clientEventGroup, final LocalAddress localAddress) {
this.clientEventGroup = clientEventGroup;
this.localAddress = localAddress;
}
@Override
@SuppressWarnings("checkstyle:hiddenField")
public void setIoInputStream(final IoInputStream in) {
this.in = in;
}
@Override
@SuppressWarnings("checkstyle:hiddenField")
public void setIoOutputStream(final IoOutputStream out) {
this.out = out;
}
@Override
public void setIoErrorStream(final IoOutputStream err) {
// TODO do we want to use error stream in some way ?
}
@Override
@SuppressWarnings("checkstyle:hiddenField")
public void setInputStream(final InputStream in) {
throw new UnsupportedOperationException("Synchronous IO is unsupported");
}
@Override
@SuppressWarnings("checkstyle:hiddenField")
public void setOutputStream(final OutputStream out) {
throw new UnsupportedOperationException("Synchronous IO is unsupported");
}
@Override
public void setErrorStream(final OutputStream err) {
throw new UnsupportedOperationException("Synchronous IO is unsupported");
}
@Override
@SuppressWarnings("checkstyle:hiddenField")
public void setExitCallback(final ExitCallback callback) {
this.callback = callback;
}
@Override
public void start(final Environment env) {
LOG.trace("Establishing internal connection to netconf server for client: {}", getClientAddress());
final Bootstrap clientBootstrap = new Bootstrap();
clientBootstrap.group(clientEventGroup).channel(LocalChannel.class);
clientBootstrap.handler(new ChannelInitializer