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