1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.mina.filter.keepalive;
21
22 import static org.apache.mina.filter.keepalive.KeepAliveRequestTimeoutHandler.EXCEPTION;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertNotNull;
25
26 import java.net.InetSocketAddress;
27 import java.util.concurrent.atomic.AtomicBoolean;
28
29 import org.apache.mina.core.buffer.IoBuffer;
30 import org.apache.mina.core.future.ConnectFuture;
31 import org.apache.mina.core.service.IoHandlerAdapter;
32 import org.apache.mina.core.session.IdleStatus;
33 import org.apache.mina.core.session.IoSession;
34 import org.apache.mina.transport.socket.nio.NioSocketAcceptor;
35 import org.apache.mina.transport.socket.nio.NioSocketConnector;
36 import org.junit.After;
37 import org.junit.Before;
38 import org.junit.Test;
39
40
41
42
43
44
45
46 public class KeepAliveFilterTest {
47
48 static final IoBuffer PING = IoBuffer.wrap(new byte[] { 1 });
49 static final IoBuffer PONG = IoBuffer.wrap(new byte[] { 2 });
50 private static final int INTERVAL = 2;
51 private static final int TIMEOUT = 1;
52
53 private int port;
54 private NioSocketAcceptor acceptor;
55
56 @Before
57 public void setUp() throws Exception {
58 acceptor = new NioSocketAcceptor();
59 KeepAliveMessageFactory factory = new ServerFactory();
60 KeepAliveFilter filter = new KeepAliveFilter(factory,
61 IdleStatus.BOTH_IDLE);
62 acceptor.getFilterChain().addLast("keep-alive", filter);
63 acceptor.setHandler(new IoHandlerAdapter());
64 acceptor.setDefaultLocalAddress(new InetSocketAddress(0));
65 acceptor.bind();
66 port = acceptor.getLocalAddress().getPort();
67 }
68
69 @After
70 public void tearDown() throws Exception {
71 acceptor.unbind();
72 acceptor.dispose();
73 }
74
75 @Test
76 public void testKeepAliveFilterForReaderIdle() throws Exception {
77 keepAliveFilterForIdleStatus(IdleStatus.READER_IDLE);
78 }
79
80 @Test
81 public void testKeepAliveFilterForBothIdle() throws Exception {
82 keepAliveFilterForIdleStatus(IdleStatus.BOTH_IDLE);
83 }
84
85 @Test
86 public void testKeepAliveFilterForWriterIdle() throws Exception {
87 keepAliveFilterForIdleStatus(IdleStatus.WRITER_IDLE);
88 }
89
90
91
92
93
94
95
96 private void keepAliveFilterForIdleStatus(IdleStatus status)
97 throws Exception {
98 NioSocketConnector connector = new NioSocketConnector();
99 KeepAliveFilter filter = new KeepAliveFilter(new ClientFactory(),
100 status, EXCEPTION, INTERVAL, TIMEOUT);
101 filter.setForwardEvent(true);
102 connector.getFilterChain().addLast("keep-alive", filter);
103
104 final AtomicBoolean gotException = new AtomicBoolean(false);
105 connector.setHandler(new IoHandlerAdapter() {
106 @Override
107 public void exceptionCaught(IoSession session, Throwable cause)
108 throws Exception {
109
110 gotException.set(true);
111 }
112
113 @Override
114 public void sessionIdle(IoSession session, IdleStatus status)
115 throws Exception {
116
117 }
118 });
119
120 ConnectFuture future = connector.connect(
121 new InetSocketAddress("127.0.0.1", port)).awaitUninterruptibly();
122 IoSession session = future.getSession();
123 assertNotNull(session);
124
125 Thread.sleep((INTERVAL + TIMEOUT + 1) * 1000);
126
127 assertFalse("got an exception on the client", gotException.get());
128
129 session.close(true);
130 connector.dispose();
131 }
132
133 static boolean checkRequest(IoBuffer message) {
134 IoBuffer buff = message;
135 boolean check = buff.get() == 1;
136 buff.rewind();
137 return check;
138 }
139
140 static boolean checkResponse(IoBuffer message) {
141 IoBuffer buff = message;
142 boolean check = buff.get() == 2;
143 buff.rewind();
144 return check;
145 }
146
147
148 private final class ServerFactory implements KeepAliveMessageFactory {
149
150
151
152 public ServerFactory() {
153 super();
154 }
155
156 public Object getRequest(IoSession session) {
157 return null;
158 }
159
160 public Object getResponse(IoSession session, Object request) {
161 return PONG.duplicate();
162 }
163
164 public boolean isRequest(IoSession session, Object message) {
165 if (message instanceof IoBuffer) {
166 return checkRequest((IoBuffer) message);
167 }
168 return false;
169 }
170
171 public boolean isResponse(IoSession session, Object message) {
172 if (message instanceof IoBuffer) {
173 return checkResponse((IoBuffer) message);
174 }
175 return false;
176 }
177 }
178
179 private final class ClientFactory implements KeepAliveMessageFactory {
180
181
182
183 public ClientFactory() {
184 super();
185 }
186
187 public Object getRequest(IoSession session) {
188 return PING.duplicate();
189 }
190
191 public Object getResponse(IoSession session, Object request) {
192 return null;
193 }
194
195 public boolean isRequest(IoSession session, Object message) {
196 if (message instanceof IoBuffer) {
197 return checkRequest((IoBuffer) message);
198 }
199 return false;
200 }
201
202 public boolean isResponse(IoSession session, Object message) {
203 if (message instanceof IoBuffer) {
204 return checkResponse((IoBuffer) message);
205 }
206 return false;
207 }
208 }
209 }