2 * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.
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
9 package org.opendaylight.controller.netconf.tcp.netty;
11 import static com.google.common.base.Preconditions.checkState;
13 import io.netty.bootstrap.Bootstrap;
14 import io.netty.channel.Channel;
15 import io.netty.channel.ChannelFuture;
16 import io.netty.channel.ChannelHandlerContext;
17 import io.netty.channel.ChannelInboundHandlerAdapter;
18 import io.netty.channel.ChannelInitializer;
19 import io.netty.channel.local.LocalAddress;
20 import io.netty.channel.local.LocalChannel;
21 import org.slf4j.Logger;
22 import org.slf4j.LoggerFactory;
24 public class ProxyServerHandler extends ChannelInboundHandlerAdapter {
25 private static final Logger LOG = LoggerFactory.getLogger(ProxyServerHandler.class);
26 private final Bootstrap clientBootstrap;
27 private final LocalAddress localAddress;
29 private Channel clientChannel;
31 public ProxyServerHandler(Bootstrap clientBootstrap, LocalAddress localAddress) {
32 this.clientBootstrap = clientBootstrap;
33 this.localAddress = localAddress;
37 public void channelActive(ChannelHandlerContext remoteCtx) {
38 final ProxyClientHandler clientHandler = new ProxyClientHandler(remoteCtx);
39 clientBootstrap.handler(new ChannelInitializer<LocalChannel>() {
41 public void initChannel(LocalChannel ch) throws Exception {
42 ch.pipeline().addLast(clientHandler);
45 ChannelFuture clientChannelFuture = clientBootstrap.connect(localAddress).awaitUninterruptibly();
46 clientChannel = clientChannelFuture.channel();
50 public void channelInactive(ChannelHandlerContext ctx) {
51 LOG.trace("channelInactive - closing client channel");
52 clientChannel.close();
56 public void channelRead(ChannelHandlerContext ctx, final Object msg) {
57 LOG.trace("Writing to client channel");
58 clientChannel.write(msg);
62 public void channelReadComplete(ChannelHandlerContext ctx) {
63 LOG.trace("Flushing client channel");
64 clientChannel.flush();
68 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
69 // Close the connection when an exception is raised.
70 LOG.warn("Unexpected exception from downstream.", cause);
75 class ProxyClientHandler extends ChannelInboundHandlerAdapter {
76 private static final Logger LOG = LoggerFactory.getLogger(ProxyClientHandler.class);
78 private final ChannelHandlerContext remoteCtx;
79 private ChannelHandlerContext localCtx;
81 public ProxyClientHandler(ChannelHandlerContext remoteCtx) {
82 this.remoteCtx = remoteCtx;
86 public void channelActive(ChannelHandlerContext ctx) {
87 checkState(this.localCtx == null);
88 LOG.trace("Client channel active");
93 public void channelRead(ChannelHandlerContext ctx, Object msg) {
94 LOG.trace("Forwarding message");
99 public void channelReadComplete(ChannelHandlerContext ctx) {
100 LOG.trace("Flushing remote ctx");
105 public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
106 // Close the connection when an exception is raised.
107 LOG.warn("Unexpected exception from downstream", cause);
108 checkState(this.localCtx.equals(ctx));
112 // called both when local or remote connection dies
114 public void channelInactive(ChannelHandlerContext ctx) {
115 LOG.trace("channelInactive() called, closing remote client ctx");