Merge "Fix checkstyle warnings in netty-threadgroup-config."
[controller.git] / opendaylight / netconf / netconf-tcp / src / main / java / org / opendaylight / controller / netconf / tcp / netty / ProxyServerHandler.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.tcp.netty;
10
11 import static com.google.common.base.Preconditions.checkState;
12
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;
23
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;
28
29     private Channel clientChannel;
30
31     public ProxyServerHandler(Bootstrap clientBootstrap, LocalAddress localAddress) {
32         this.clientBootstrap = clientBootstrap;
33         this.localAddress = localAddress;
34     }
35
36     @Override
37     public void channelActive(ChannelHandlerContext remoteCtx) {
38         final ProxyClientHandler clientHandler = new ProxyClientHandler(remoteCtx);
39         clientBootstrap.handler(new ChannelInitializer<LocalChannel>() {
40             @Override
41             public void initChannel(LocalChannel ch) throws Exception {
42                 ch.pipeline().addLast(clientHandler);
43             }
44         });
45         ChannelFuture clientChannelFuture = clientBootstrap.connect(localAddress).awaitUninterruptibly();
46         clientChannel = clientChannelFuture.channel();
47     }
48
49     @Override
50     public void channelInactive(ChannelHandlerContext ctx) {
51         LOG.trace("channelInactive - closing client channel");
52         clientChannel.close();
53     }
54
55     @Override
56     public void channelRead(ChannelHandlerContext ctx, final Object msg) {
57         LOG.trace("Writing to client channel");
58         clientChannel.write(msg);
59     }
60
61     @Override
62     public void channelReadComplete(ChannelHandlerContext ctx) {
63         LOG.trace("Flushing client channel");
64         clientChannel.flush();
65     }
66
67     @Override
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);
71         ctx.close();
72     }
73 }
74
75 class ProxyClientHandler extends ChannelInboundHandlerAdapter {
76     private static final Logger LOG = LoggerFactory.getLogger(ProxyClientHandler.class);
77
78     private final ChannelHandlerContext remoteCtx;
79     private ChannelHandlerContext localCtx;
80
81     public ProxyClientHandler(ChannelHandlerContext remoteCtx) {
82         this.remoteCtx = remoteCtx;
83     }
84
85     @Override
86     public void channelActive(ChannelHandlerContext ctx) {
87         checkState(this.localCtx == null);
88         LOG.trace("Client channel active");
89         this.localCtx = ctx;
90     }
91
92     @Override
93     public void channelRead(ChannelHandlerContext ctx, Object msg) {
94         LOG.trace("Forwarding message");
95         remoteCtx.write(msg);
96     }
97
98     @Override
99     public void channelReadComplete(ChannelHandlerContext ctx) {
100         LOG.trace("Flushing remote ctx");
101         remoteCtx.flush();
102     }
103
104     @Override
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));
109         ctx.close();
110     }
111
112     // called both when local or remote connection dies
113     @Override
114     public void channelInactive(ChannelHandlerContext ctx) {
115         LOG.trace("channelInactive() called, closing remote client ctx");
116         remoteCtx.close();
117     }
118
119 }