View Javadoc
1   /*
2    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
3    * The software in this package is published under the terms of the CPAL v1.0
4    * license, a copy of which has been included with this distribution in the
5    * LICENSE.txt file.
6    */
7   package org.mule.routing.requestreply;
8   
9   import static junit.framework.Assert.assertNull;
10  import static org.junit.Assert.assertEquals;
11  import static org.junit.Assert.assertFalse;
12  import static org.junit.Assert.assertTrue;
13  import static org.junit.Assert.fail;
14  import static org.mockito.Mockito.mock;
15  import org.mule.MessageExchangePattern;
16  import org.mule.api.MuleEvent;
17  import org.mule.api.MuleException;
18  import org.mule.api.context.WorkManager;
19  import org.mule.api.context.WorkManagerSource;
20  import org.mule.api.endpoint.InboundEndpoint;
21  import org.mule.api.processor.MessageProcessor;
22  import org.mule.api.processor.RequestReplyRequesterMessageProcessor;
23  import org.mule.api.routing.ResponseTimeoutException;
24  import org.mule.api.service.Service;
25  import org.mule.api.source.MessageSource;
26  import org.mule.processor.AsyncInterceptingMessageProcessor;
27  import org.mule.tck.SensingNullMessageProcessor;
28  import org.mule.tck.junit4.AbstractMuleContextTestCase;
29  import org.mule.util.concurrent.Latch;
30  
31  import java.beans.ExceptionListener;
32  import java.util.concurrent.CountDownLatch;
33  import java.util.concurrent.TimeUnit;
34  
35  import javax.resource.spi.work.Work;
36  
37  import org.junit.Test;
38  
39  public class AsyncRequestReplyRequesterTestCase extends AbstractMuleContextTestCase
40      implements ExceptionListener
41  {
42  
43      @Test
44      public void testSingleEventNoTimeout() throws Exception
45      {
46          RequestReplyRequesterMessageProcessor asyncReplyMP = new TestAsyncRequestReplyRequester();
47          SensingNullMessageProcessor target = getSensingNullMessageProcessor();
48  
49          asyncReplyMP.setListener(target);
50          asyncReplyMP.setReplySource(target.getMessageSource());
51  
52          MuleEvent event = getTestEvent(TEST_MESSAGE, getTestService());
53  
54          MuleEvent resultEvent = asyncReplyMP.process(event);
55  
56          // Can't assert same because we copy event when we receive async reply
57          assertEquals(event.getMessageAsString(), resultEvent.getMessageAsString());
58          assertEquals(event.getMessage().getUniqueId(), resultEvent.getMessage().getUniqueId());
59      }
60  
61      @Test
62      public void testSingleEventNoTimeoutAsync() throws Exception
63      {
64          RequestReplyRequesterMessageProcessor asyncReplyMP = new TestAsyncRequestReplyRequester();
65          SensingNullMessageProcessor target = getSensingNullMessageProcessor();
66          AsyncInterceptingMessageProcessor asyncMP = new AsyncInterceptingMessageProcessor(
67              new WorkManagerSource()
68              {
69                  public WorkManager getWorkManager() throws MuleException
70                  {
71                      return muleContext.getWorkManager();
72                  }
73              }
74          );
75  
76          asyncMP.setListener(target);
77          asyncReplyMP.setListener(asyncMP);
78          asyncReplyMP.setReplySource(target.getMessageSource());
79  
80          MuleEvent event = getTestEvent(TEST_MESSAGE, getTestService(),
81              getTestInboundEndpoint(MessageExchangePattern.ONE_WAY));
82  
83          MuleEvent resultEvent = asyncReplyMP.process(event);
84  
85          // Can't assert same because we copy event for async and also on async reply currently
86          assertEquals(event.getMessageAsString(), resultEvent.getMessageAsString());
87          assertEquals(event.getMessage().getUniqueId(), resultEvent.getMessage().getUniqueId());
88      }
89  
90      @Test
91      public void testSingleEventTimeout() throws Exception
92      {
93          TestAsyncRequestReplyRequester asyncReplyMP = new TestAsyncRequestReplyRequester();
94          asyncReplyMP.setTimeout(1);
95          SensingNullMessageProcessor target = getSensingNullMessageProcessor();
96          target.setWaitTime(50);
97          AsyncInterceptingMessageProcessor asyncMP = new AsyncInterceptingMessageProcessor(
98              new WorkManagerSource()
99              {
100 
101                 public WorkManager getWorkManager() throws MuleException
102                 {
103                     return muleContext.getWorkManager();
104                 }
105             }
106         );
107 
108         asyncMP.setListener(target);
109         asyncReplyMP.setListener(asyncMP);
110         asyncReplyMP.setReplySource(target.getMessageSource());
111 
112         MuleEvent event = getTestEvent(TEST_MESSAGE, getTestService(),
113             getTestInboundEndpoint(MessageExchangePattern.ONE_WAY));
114 
115         try
116         {
117             asyncReplyMP.process(event);
118             fail("ResponseTimeoutException expected");
119         }
120         catch (Exception e)
121         {
122             assertEquals(ResponseTimeoutException.class, e.getClass());
123         }
124     }
125 
126     @Test
127     public void returnsNullWhenInterruptedWhileWaitingForReply() throws Exception
128     {
129         final Latch fakeLatch = new Latch()
130         {
131             @Override
132             public void await() throws InterruptedException
133             {
134                 throw new InterruptedException();
135             }
136         };
137 
138         final RequestReplyRequesterMessageProcessor asyncReplyMP = new TestAsyncRequestReplyRequester()
139         {
140             @Override
141             protected Latch createEventLock()
142             {
143                 return fakeLatch;
144             }
145         };
146 
147         final MuleEvent event = getTestEvent(TEST_MESSAGE, getTestService(),
148                                              getTestInboundEndpoint(MessageExchangePattern.ONE_WAY));
149 
150         final CountDownLatch processingLatch = new CountDownLatch(1);
151 
152         MessageProcessor target = mock(MessageProcessor.class);
153         asyncReplyMP.setListener(target);
154 
155         MessageSource messageSource = mock(MessageSource.class);
156         asyncReplyMP.setReplySource(messageSource);
157 
158         final boolean[] exceptionThrown = new boolean[1];
159         final Object[] responseEvent = new Object[1];
160 
161         Thread thread = new Thread(new Runnable()
162         {
163             public void run()
164             {
165                 try
166                 {
167                     responseEvent[0] = asyncReplyMP.process(event);
168                 }
169                 catch (MuleException e)
170                 {
171                     exceptionThrown[0] = true;
172                 }
173                 finally
174                 {
175                     processingLatch.countDown();
176                 }
177             }
178         });
179 
180         thread.start();
181         assertTrue(processingLatch.await(RECEIVE_TIMEOUT, TimeUnit.MILLISECONDS));
182         assertFalse(exceptionThrown[0]);
183         assertNull(responseEvent[0]);
184     }
185 
186     @Test
187     public void testMultiple() throws Exception
188     {
189         final RequestReplyRequesterMessageProcessor asyncReplyMP = new TestAsyncRequestReplyRequester();
190         SensingNullMessageProcessor target = getSensingNullMessageProcessor();
191         target.setWaitTime(50);
192         AsyncInterceptingMessageProcessor asyncMP = new AsyncInterceptingMessageProcessor(
193             new WorkManagerSource()
194             {
195 
196                 public WorkManager getWorkManager() throws MuleException
197                 {
198                     return muleContext.getWorkManager();
199                 }
200             }
201         );
202 
203         asyncMP.setListener(target);
204         asyncReplyMP.setListener(asyncMP);
205         asyncReplyMP.setReplySource(target.getMessageSource());
206 
207         final InboundEndpoint inboundEndpoint = getTestInboundEndpoint(MessageExchangePattern.ONE_WAY);
208         final Service service = getTestService();
209 
210         for (int i = 0; i < 500; i++)
211         {
212             muleContext.getWorkManager().scheduleWork(new Work()
213             {
214                 public void run()
215                 {
216                     MuleEvent event;
217                     try
218                     {
219                         event = getTestEvent(TEST_MESSAGE, service, inboundEndpoint);
220                         MuleEvent resultEvent = asyncReplyMP.process(event);
221 
222                         // Can't assert same because we copy event for async currently
223                         assertEquals(event.getMessageAsString(), resultEvent.getMessageAsString());
224                         assertEquals(event.getMessage().getUniqueId(), resultEvent.getMessage().getUniqueId());
225                     }
226                     catch (Exception e)
227                     {
228                         throw new RuntimeException(e);
229                     }
230                 }
231 
232                 public void release()
233                 {
234                     // nop
235                 }
236             });
237         }
238     }
239 
240     public void exceptionThrown(Exception e)
241     {
242         e.printStackTrace();
243         fail(e.getMessage());
244     }
245 
246     class TestAsyncRequestReplyRequester extends AbstractAsyncRequestReplyRequester
247     {
248         // no custom methods
249     }
250 }