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(Object message) {
133 if (message instanceof IoBuffer ) {
134 IoBuffer buff = (IoBuffer)message;
135 boolean check = buff.get() == 1;
136 buff.rewind();
137 return check;
138 } else {
139 return false;
140 }
141 }
142
143 static boolean checkResponse(Object message) {
144 if (message instanceof IoBuffer ) {
145 IoBuffer buff = (IoBuffer)message;
146 boolean check = buff.get() == 2;
147 buff.rewind();
148 return check;
149 } else {
150 return false;
151 }
152 }
153
154
155 private final class ServerFactory implements KeepAliveMessageFactory {
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 return checkRequest(message);
166 }
167
168 public boolean isResponse(IoSession session, Object message) {
169 return checkResponse(message);
170 }
171 }
172
173 private final class ClientFactory implements KeepAliveMessageFactory {
174 public Object getRequest(IoSession session) {
175 return PING.duplicate();
176 }
177
178 public Object getResponse(IoSession session, Object request) {
179 return null;
180 }
181
182 public boolean isRequest(IoSession session, Object message) {
183 return checkRequest(message);
184 }
185
186 public boolean isResponse(IoSession session, Object message) {
187 return checkResponse(message);
188 }
189 }
190 }