Merge "Bug 1362: New AsyncWriteTransaction#submit method"
[controller.git] / opendaylight / netconf / netconf-ssh / src / test / java / org / opendaylight / controller / netconf / netty / EchoClientHandler.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.netty;
10
11 import static com.google.common.base.Preconditions.checkState;
12
13 import com.google.common.base.Charsets;
14 import io.netty.buffer.ByteBuf;
15 import io.netty.buffer.Unpooled;
16 import io.netty.channel.ChannelFuture;
17 import io.netty.channel.ChannelFutureListener;
18 import io.netty.channel.ChannelHandlerContext;
19 import io.netty.channel.ChannelInboundHandlerAdapter;
20 import org.slf4j.Logger;
21 import org.slf4j.LoggerFactory;
22
23 /**
24  * Handler implementation for the echo client.  It initiates the ping-pong
25  * traffic between the echo client and server by sending the first message to
26  * the server.
27  */
28 public class EchoClientHandler extends ChannelInboundHandlerAdapter implements ChannelFutureListener {
29     private static final Logger logger = LoggerFactory.getLogger(EchoClientHandler.class);
30
31     private ChannelHandlerContext ctx;
32     private final StringBuilder fromServer = new StringBuilder();
33
34     public static enum State {CONNECTING, CONNECTED, FAILED_TO_CONNECT, CONNECTION_CLOSED}
35
36
37     private State state = State.CONNECTING;
38
39     @Override
40     public synchronized void channelActive(ChannelHandlerContext ctx) {
41         checkState(this.ctx == null);
42         logger.info("channelActive");
43         this.ctx = ctx;
44         state = State.CONNECTED;
45     }
46
47     @Override
48     public synchronized void channelInactive(ChannelHandlerContext ctx) throws Exception {
49         state = State.CONNECTION_CLOSED;
50     }
51
52     @Override
53     public synchronized void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
54         ByteBuf bb = (ByteBuf) msg;
55         String string = bb.toString(Charsets.UTF_8);
56         fromServer.append(string);
57         logger.info(">{}", string);
58         bb.release();
59     }
60
61     @Override
62     public synchronized void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
63         // Close the connection when an exception is raised.
64         logger.warn("Unexpected exception from downstream.", cause);
65         checkState(this.ctx.equals(ctx));
66         ctx.close();
67         this.ctx = null;
68     }
69
70     public synchronized void write(String message) {
71         ByteBuf byteBuf = Unpooled.copiedBuffer(message.getBytes());
72         ctx.writeAndFlush(byteBuf);
73     }
74
75     public synchronized boolean isConnected() {
76         return state == State.CONNECTED;
77     }
78
79     public synchronized String read() {
80         return fromServer.toString();
81     }
82
83     @Override
84     public synchronized void operationComplete(ChannelFuture future) throws Exception {
85         checkState(state == State.CONNECTING);
86         if (future.isSuccess()) {
87             logger.trace("Successfully connected, state will be switched in channelActive");
88         } else {
89             state = State.FAILED_TO_CONNECT;
90         }
91     }
92
93     public State getState() {
94         return state;
95     }
96 }