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
50 static final IoBuffer PONG = IoBuffer.wrap(new byte[] { 2 });
51
52 private static final int INTERVAL = 2;
53
54 private static final int TIMEOUT = 1;
55
56 private int port;
57
58 private NioSocketAcceptor acceptor;
59
60 @Before
61 public void setUp() throws Exception {
62 acceptor = new NioSocketAcceptor();
63 KeepAliveMessageFactory factory = new ServerFactory();
64 KeepAliveFilter filter = new KeepAliveFilter(factory, IdleStatus.BOTH_IDLE);
65 acceptor.getFilterChain().addLast("keep-alive", filter);
66 acceptor.setHandler(new IoHandlerAdapter());
67 acceptor.setDefaultLocalAddress(new InetSocketAddress(0));
68 acceptor.bind();
69 port = acceptor.getLocalAddress().getPort();
70 }
71
72 @After
73 public void tearDown() throws Exception {
74 acceptor.unbind();
75 acceptor.dispose();
76 }
77
78 @Test
79 public void testKeepAliveFilterForReaderIdle() throws Exception {
80 keepAliveFilterForIdleStatus(IdleStatus.READER_IDLE);
81 }
82
83 @Test
84 public void testKeepAliveFilterForBothIdle() throws Exception {
85 keepAliveFilterForIdleStatus(IdleStatus.BOTH_IDLE);
86 }
87
88 @Test
89 public void testKeepAliveFilterForWriterIdle() throws Exception {
90 keepAliveFilterForIdleStatus(IdleStatus.WRITER_IDLE);
91 }
92
93
94
95
96
97
98
99 private void keepAliveFilterForIdleStatus(IdleStatus status) throws Exception {
100 NioSocketConnector connector = new NioSocketConnector();
101 KeepAliveFilter filter = new KeepAliveFilter(new ClientFactory(), status, EXCEPTION, INTERVAL, TIMEOUT);
102 filter.setForwardEvent(true);
103 connector.getFilterChain().addLast("keep-alive", filter);
104
105 final AtomicBoolean gotException = new AtomicBoolean(false);
106 connector.setHandler(new IoHandlerAdapter() {
107 @Override
108 public void exceptionCaught(IoSession session, Throwable cause) throws Exception {
109
110 gotException.set(true);
111 }
112
113 @Override
114 public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
115
116 }
117 });
118
119 ConnectFuture future = connector.connect(new InetSocketAddress("127.0.0.1", port)).awaitUninterruptibly();
120 IoSession session = future.getSession();
121 assertNotNull(session);
122
123 Thread.sleep((INTERVAL + TIMEOUT + 1) * 1000);
124
125 assertFalse("got an exception on the client", gotException.get());
126
127 session.closeNow();
128 connector.dispose();
129 }
130
131 static boolean checkRequest(IoBuffer message) {
132 IoBuffer buff = message;
133 boolean check = buff.get() == 1;
134 buff.rewind();
135 return check;
136 }
137
138 static boolean checkResponse(IoBuffer message) {
139 IoBuffer buff = message;
140 boolean check = buff.get() == 2;
141 buff.rewind();
142 return check;
143 }
144
145
146 private final class ServerFactory implements KeepAliveMessageFactory {
147
148
149
150 public ServerFactory() {
151 super();
152 }
153
154 public Object getRequest(IoSession session) {
155 return null;
156 }
157
158 public Object getResponse(IoSession session, Object request) {
159 return PONG.duplicate();
160 }
161
162 public boolean isRequest(IoSession session, Object message) {
163 if (message instanceof IoBuffer) {
164 return checkRequest((IoBuffer) message);
165 }
166 return false;
167 }
168
169 public boolean isResponse(IoSession session, Object message) {
170 if (message instanceof IoBuffer) {
171 return checkResponse((IoBuffer) message);
172 }
173 return false;
174 }
175 }
176
177 private final class ClientFactory implements KeepAliveMessageFactory {
178
179
180
181 public ClientFactory() {
182 super();
183 }
184
185 public Object getRequest(IoSession session) {
186 return PING.duplicate();
187 }
188
189 public Object getResponse(IoSession session, Object request) {
190 return null;
191 }
192
193 public boolean isRequest(IoSession session, Object message) {
194 if (message instanceof IoBuffer) {
195 return checkRequest((IoBuffer) message);
196 }
197 return false;
198 }
199
200 public boolean isResponse(IoSession session, Object message) {
201 if (message instanceof IoBuffer) {
202 return checkResponse((IoBuffer) message);
203 }
204 return false;
205 }
206 }
207 }