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.reqres;
21
22 import java.util.NoSuchElementException;
23 import java.util.concurrent.Executors;
24 import java.util.concurrent.ScheduledExecutorService;
25
26 import junit.framework.TestCase;
27
28 import org.apache.mina.core.filterchain.IoFilterChain;
29 import org.apache.mina.core.filterchain.IoFilter.NextFilter;
30 import org.apache.mina.core.session.DummySession;
31 import org.apache.mina.core.session.IoSession;
32 import org.apache.mina.core.write.DefaultWriteRequest;
33 import org.apache.mina.core.write.WriteRequest;
34 import org.easymock.AbstractMatcher;
35 import org.easymock.MockControl;
36 import org.junit.After;
37 import org.junit.Assert;
38 import org.junit.Before;
39 import org.junit.Test;
40
41
42
43
44
45
46
47 public class RequestResponseFilterTest extends TestCase {
48
49 private ScheduledExecutorService scheduler;
50
51 private RequestResponseFilter filter;
52
53 private IoSession session;
54
55 private IoFilterChain chain;
56
57 private NextFilter nextFilter;
58
59 private MockControl nextFilterControl;
60
61 private final WriteRequestMatcher matcher = new WriteRequestMatcher();
62
63 @Override
64 @Before
65 public void setUp() throws Exception {
66 scheduler = Executors.newScheduledThreadPool(1);
67 filter = new RequestResponseFilter(new MessageInspector(), scheduler);
68
69
70 session = new DummySession();
71 chain = session.getFilterChain();
72 nextFilterControl = MockControl.createControl(NextFilter.class);
73 nextFilter = (NextFilter) nextFilterControl.getMock();
74
75
76 filter.onPreAdd(chain, "reqres", nextFilter);
77 filter.onPostAdd(chain, "reqres", nextFilter);
78 Assert.assertFalse(session.getAttributeKeys().isEmpty());
79 }
80
81 @Override
82 @After
83 public void tearDown() throws Exception {
84
85 filter.onPreRemove(chain, "reqres", nextFilter);
86 filter.onPostRemove(chain, "reqres", nextFilter);
87 filter.destroy();
88 filter = null;
89 scheduler.shutdown();
90 }
91
92 @Test
93 public void testWholeResponse() throws Exception {
94 Request req = new Request(1, new Object(), Long.MAX_VALUE);
95 Response res = new Response(req, new Message(1, ResponseType.WHOLE),
96 ResponseType.WHOLE);
97 WriteRequest rwr = new DefaultWriteRequest(req);
98
99
100 nextFilter.filterWrite(session, new DefaultWriteRequest(req
101 .getMessage()));
102 nextFilterControl.setMatcher(matcher);
103 nextFilter.messageSent(session, rwr);
104 nextFilter.messageReceived(session, res);
105
106
107 nextFilterControl.replay();
108 filter.filterWrite(nextFilter, session, rwr);
109 filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
110 filter.messageReceived(nextFilter, session, res.getMessage());
111 filter.messageReceived(nextFilter, session, res.getMessage());
112
113
114 nextFilterControl.verify();
115 Assert.assertEquals(res, req.awaitResponse());
116 assertNoSuchElementException(req);
117 }
118
119 private void assertNoSuchElementException(Request req)
120 throws InterruptedException {
121
122 try {
123 req.awaitResponse();
124 Assert.fail();
125 } catch (NoSuchElementException e) {
126
127 }
128 }
129
130 @Test
131 public void testPartialResponse() throws Exception {
132 Request req = new Request(1, new Object(), Long.MAX_VALUE);
133 Response res1 = new Response(req, new Message(1, ResponseType.PARTIAL),
134 ResponseType.PARTIAL);
135 Response res2 = new Response(req, new Message(1,
136 ResponseType.PARTIAL_LAST), ResponseType.PARTIAL_LAST);
137 WriteRequest rwr = new DefaultWriteRequest(req);
138
139
140 nextFilter.filterWrite(session, new DefaultWriteRequest(req
141 .getMessage()));
142 nextFilterControl.setMatcher(matcher);
143 nextFilter.messageSent(session, rwr);
144 nextFilter.messageReceived(session, res1);
145 nextFilter.messageReceived(session, res2);
146
147
148 nextFilterControl.replay();
149 filter.filterWrite(nextFilter, session, rwr);
150 filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
151 filter.messageReceived(nextFilter, session, res1.getMessage());
152 filter.messageReceived(nextFilter, session, res2.getMessage());
153 filter.messageReceived(nextFilter, session, res1.getMessage());
154 filter.messageReceived(nextFilter, session, res2.getMessage());
155
156
157 nextFilterControl.verify();
158 Assert.assertEquals(res1, req.awaitResponse());
159 Assert.assertEquals(res2, req.awaitResponse());
160 assertNoSuchElementException(req);
161 }
162
163 @Test
164 public void testWholeResponseTimeout() throws Exception {
165 Request req = new Request(1, new Object(), 10);
166 Response res = new Response(req, new Message(1, ResponseType.WHOLE),
167 ResponseType.WHOLE);
168 WriteRequest rwr = new DefaultWriteRequest(req);
169
170
171 nextFilter.filterWrite(session, new DefaultWriteRequest(req
172 .getMessage()));
173 nextFilterControl.setMatcher(matcher);
174 nextFilter.messageSent(session, rwr);
175 nextFilter.exceptionCaught(session, new RequestTimeoutException(req));
176 nextFilterControl.setMatcher(new ExceptionMatcher());
177
178
179 nextFilterControl.replay();
180 filter.filterWrite(nextFilter, session, rwr);
181 filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
182 Thread.sleep(300);
183 filter.messageReceived(nextFilter, session, res.getMessage());
184
185
186 nextFilterControl.verify();
187 assertRequestTimeoutException(req);
188 assertNoSuchElementException(req);
189 }
190
191 private void assertRequestTimeoutException(Request req)
192 throws InterruptedException {
193 try {
194 req.awaitResponse();
195 Assert.fail();
196 } catch (RequestTimeoutException e) {
197
198 }
199 }
200
201 @Test
202 public void testPartialResponseTimeout() throws Exception {
203 Request req = new Request(1, new Object(), 10);
204 Response res1 = new Response(req, new Message(1, ResponseType.PARTIAL),
205 ResponseType.PARTIAL);
206 Response res2 = new Response(req, new Message(1,
207 ResponseType.PARTIAL_LAST), ResponseType.PARTIAL_LAST);
208 WriteRequest rwr = new DefaultWriteRequest(req);
209
210
211 nextFilter.filterWrite(session, new DefaultWriteRequest(req
212 .getMessage()));
213 nextFilterControl.setMatcher(matcher);
214 nextFilter.messageSent(session, rwr);
215 nextFilter.messageReceived(session, res1);
216 nextFilter.exceptionCaught(session, new RequestTimeoutException(req));
217 nextFilterControl.setMatcher(new ExceptionMatcher());
218
219
220 nextFilterControl.replay();
221 filter.filterWrite(nextFilter, session, rwr);
222 filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
223 filter.messageReceived(nextFilter, session, res1.getMessage());
224 Thread.sleep(300);
225 filter.messageReceived(nextFilter, session, res2.getMessage());
226 filter.messageReceived(nextFilter, session, res1.getMessage());
227
228
229 nextFilterControl.verify();
230 Assert.assertEquals(res1, req.awaitResponse());
231 assertRequestTimeoutException(req);
232 assertNoSuchElementException(req);
233 }
234
235 @Test
236 public void testTimeoutByDisconnection() throws Exception {
237
238
239 testWholeResponse();
240 nextFilterControl.reset();
241
242 Request req1 = new Request(1, new Object(), Long.MAX_VALUE);
243 Request req2 = new Request(2, new Object(), Long.MAX_VALUE);
244 WriteRequest rwr1 = new DefaultWriteRequest(req1);
245 WriteRequest rwr2 = new DefaultWriteRequest(req2);
246
247
248 nextFilter.filterWrite(session, new DefaultWriteRequest(req1
249 .getMessage()));
250 nextFilterControl.setMatcher(matcher);
251 nextFilter.messageSent(session, rwr1);
252 nextFilter.filterWrite(session, new DefaultWriteRequest(req2
253 .getMessage()));
254 nextFilter.messageSent(session, rwr2);
255 nextFilter.exceptionCaught(session, new RequestTimeoutException(req1));
256 nextFilterControl.setMatcher(new ExceptionMatcher());
257 nextFilter.exceptionCaught(session, new RequestTimeoutException(req2));
258 nextFilter.sessionClosed(session);
259
260
261 nextFilterControl.replay();
262 filter.filterWrite(nextFilter, session, rwr1);
263 filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
264 filter.filterWrite(nextFilter, session, rwr2);
265 filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
266 filter.sessionClosed(nextFilter, session);
267
268
269 nextFilterControl.verify();
270 assertRequestTimeoutException(req1);
271 assertRequestTimeoutException(req2);
272 }
273
274 private static class Message {
275 private final int id;
276
277 private final ResponseType type;
278
279 private Message(int id, ResponseType type) {
280 this.id = id;
281 this.type = type;
282 }
283
284 public int getId() {
285 return id;
286 }
287
288 public ResponseType getType() {
289 return type;
290 }
291 }
292
293 private static class MessageInspector implements ResponseInspector {
294
295 public Object getRequestId(Object message) {
296 if (!(message instanceof Message)) {
297 return null;
298 }
299
300 return ((Message) message).getId();
301 }
302
303 public ResponseType getResponseType(Object message) {
304 if (!(message instanceof Message)) {
305 return null;
306 }
307
308 return ((Message) message).getType();
309 }
310 }
311
312 private static class WriteRequestMatcher extends AbstractMatcher {
313 private WriteRequest lastWriteRequest;
314
315 public WriteRequest getLastWriteRequest() {
316 return lastWriteRequest;
317 }
318
319 @Override
320 protected boolean argumentMatches(Object expected, Object actual) {
321 if (actual instanceof WriteRequest
322 && expected instanceof WriteRequest) {
323 boolean answer = ((WriteRequest) expected).getMessage().equals(
324 ((WriteRequest) actual).getMessage());
325 lastWriteRequest = (WriteRequest) actual;
326 return answer;
327 }
328 return super.argumentMatches(expected, actual);
329 }
330 }
331
332 private static class ExceptionMatcher extends AbstractMatcher {
333 @Override
334 protected boolean argumentMatches(Object expected, Object actual) {
335 if (actual instanceof RequestTimeoutException
336 && expected instanceof RequestTimeoutException) {
337 return ((RequestTimeoutException) expected)
338 .getRequest()
339 .equals(((RequestTimeoutException) actual).getRequest());
340 }
341 return super.argumentMatches(expected, actual);
342 }
343 }
344 }