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 static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertTrue;
25 import static org.junit.Assert.fail;
26
27 import java.util.NoSuchElementException;
28 import java.util.concurrent.Executors;
29 import java.util.concurrent.ScheduledExecutorService;
30
31 import org.apache.mina.core.filterchain.IoFilterChain;
32 import org.apache.mina.core.filterchain.IoFilter.NextFilter;
33 import org.apache.mina.core.session.DummySession;
34 import org.apache.mina.core.session.IoSession;
35 import org.apache.mina.core.write.DefaultWriteRequest;
36 import org.apache.mina.core.write.WriteRequest;
37 import org.easymock.AbstractMatcher;
38 import org.easymock.MockControl;
39 import org.junit.After;
40 import org.junit.Before;
41 import org.junit.Test;
42
43
44
45
46
47
48 public class RequestResponseFilterTest {
49
50 private ScheduledExecutorService scheduler;
51
52 private RequestResponseFilter filter;
53
54 private IoSession session;
55
56 private IoFilterChain chain;
57
58 private NextFilter nextFilter;
59
60 private MockControl nextFilterControl;
61
62 private final WriteRequestMatcher matcher = new WriteRequestMatcher();
63
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 assertFalse(session.getAttributeKeys().isEmpty());
79 }
80
81 @After
82 public void tearDown() throws Exception {
83
84 filter.onPreRemove(chain, "reqres", nextFilter);
85 filter.onPostRemove(chain, "reqres", nextFilter);
86 filter.destroy();
87 filter = null;
88 scheduler.shutdown();
89 }
90
91 @Test
92 public void testWholeResponse() throws Exception {
93 Request req = new Request(1, new Object(), Long.MAX_VALUE);
94 Response res = new Response(req, new Message(1, ResponseType.WHOLE),
95 ResponseType.WHOLE);
96 WriteRequest rwr = new DefaultWriteRequest(req);
97
98
99 nextFilter.filterWrite(session, new DefaultWriteRequest(req
100 .getMessage()));
101 nextFilterControl.setMatcher(matcher);
102 nextFilter.messageSent(session, rwr);
103 nextFilter.messageReceived(session, res);
104
105
106 nextFilterControl.replay();
107 filter.filterWrite(nextFilter, session, rwr);
108 filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
109 filter.messageReceived(nextFilter, session, res.getMessage());
110 filter.messageReceived(nextFilter, session, res.getMessage());
111
112
113 nextFilterControl.verify();
114 assertEquals(res, req.awaitResponse());
115 assertNoSuchElementException(req);
116 }
117
118 private void assertNoSuchElementException(Request req)
119 throws InterruptedException {
120
121 try {
122 req.awaitResponse();
123 fail();
124 } catch (NoSuchElementException e) {
125
126 assertTrue(true);
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 assertEquals(res1, req.awaitResponse());
159 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 fail();
196 } catch (RequestTimeoutException e) {
197
198 assertTrue(true);
199 }
200 }
201
202 @Test
203 public void testPartialResponseTimeout() throws Exception {
204 Request req = new Request(1, new Object(), 10);
205 Response res1 = new Response(req, new Message(1, ResponseType.PARTIAL),
206 ResponseType.PARTIAL);
207 Response res2 = new Response(req, new Message(1,
208 ResponseType.PARTIAL_LAST), ResponseType.PARTIAL_LAST);
209 WriteRequest rwr = new DefaultWriteRequest(req);
210
211
212 nextFilter.filterWrite(session, new DefaultWriteRequest(req
213 .getMessage()));
214 nextFilterControl.setMatcher(matcher);
215 nextFilter.messageSent(session, rwr);
216 nextFilter.messageReceived(session, res1);
217 nextFilter.exceptionCaught(session, new RequestTimeoutException(req));
218 nextFilterControl.setMatcher(new ExceptionMatcher());
219
220
221 nextFilterControl.replay();
222 filter.filterWrite(nextFilter, session, rwr);
223 filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
224 filter.messageReceived(nextFilter, session, res1.getMessage());
225 Thread.sleep(300);
226 filter.messageReceived(nextFilter, session, res2.getMessage());
227 filter.messageReceived(nextFilter, session, res1.getMessage());
228
229
230 nextFilterControl.verify();
231 assertEquals(res1, req.awaitResponse());
232 assertRequestTimeoutException(req);
233 assertNoSuchElementException(req);
234 }
235
236 @Test
237 public void testTimeoutByDisconnection() throws Exception {
238
239
240 testWholeResponse();
241 nextFilterControl.reset();
242
243 Request req1 = new Request(1, new Object(), Long.MAX_VALUE);
244 Request req2 = new Request(2, new Object(), Long.MAX_VALUE);
245 WriteRequest rwr1 = new DefaultWriteRequest(req1);
246 WriteRequest rwr2 = new DefaultWriteRequest(req2);
247
248
249 nextFilter.filterWrite(session, new DefaultWriteRequest(req1
250 .getMessage()));
251 nextFilterControl.setMatcher(matcher);
252 nextFilter.messageSent(session, rwr1);
253 nextFilter.filterWrite(session, new DefaultWriteRequest(req2
254 .getMessage()));
255 nextFilter.messageSent(session, rwr2);
256 nextFilter.exceptionCaught(session, new RequestTimeoutException(req1));
257 nextFilterControl.setMatcher(new ExceptionMatcher());
258 nextFilter.exceptionCaught(session, new RequestTimeoutException(req2));
259 nextFilter.sessionClosed(session);
260
261
262 nextFilterControl.replay();
263 filter.filterWrite(nextFilter, session, rwr1);
264 filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
265 filter.filterWrite(nextFilter, session, rwr2);
266 filter.messageSent(nextFilter, session, matcher.getLastWriteRequest());
267 filter.sessionClosed(nextFilter, session);
268
269
270 nextFilterControl.verify();
271 assertRequestTimeoutException(req1);
272 assertRequestTimeoutException(req2);
273 }
274
275 static class Message {
276 private final int id;
277
278 private final ResponseType type;
279
280 Message(int id, ResponseType type) {
281 this.id = id;
282 this.type = type;
283 }
284
285 public int getId() {
286 return id;
287 }
288
289 public ResponseType getType() {
290 return type;
291 }
292 }
293
294 private static class MessageInspector implements ResponseInspector {
295
296
297
298 public MessageInspector() {
299 super();
300 }
301
302 public Object getRequestId(Object message) {
303 if (!(message instanceof Message)) {
304 return null;
305 }
306
307 return ((Message) message).getId();
308 }
309
310 public ResponseType getResponseType(Object message) {
311 if (!(message instanceof Message)) {
312 return null;
313 }
314
315 return ((Message) message).getType();
316 }
317 }
318
319 private static class WriteRequestMatcher extends AbstractMatcher {
320 private WriteRequest lastWriteRequest;
321
322
323
324
325 public WriteRequestMatcher() {
326 super();
327 }
328
329 public WriteRequest getLastWriteRequest() {
330 return lastWriteRequest;
331 }
332
333 @Override
334 protected boolean argumentMatches(Object expected, Object actual) {
335 if (actual instanceof WriteRequest
336 && expected instanceof WriteRequest) {
337 boolean answer = ((WriteRequest) expected).getMessage().equals(
338 ((WriteRequest) actual).getMessage());
339 lastWriteRequest = (WriteRequest) actual;
340 return answer;
341 }
342 return super.argumentMatches(expected, actual);
343 }
344 }
345
346 static class ExceptionMatcher extends AbstractMatcher {
347 @Override
348 protected boolean argumentMatches(Object expected, Object actual) {
349 if (actual instanceof RequestTimeoutException
350 && expected instanceof RequestTimeoutException) {
351 return ((RequestTimeoutException) expected)
352 .getRequest()
353 .equals(((RequestTimeoutException) actual).getRequest());
354 }
355 return super.argumentMatches(expected, actual);
356 }
357 }
358 }