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