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.example.loanbroker.tests;
8   
9   import org.mule.api.MuleException;
10  import org.mule.api.MuleMessage;
11  import org.mule.api.client.MuleClient;
12  import org.mule.example.loanbroker.messages.Customer;
13  import org.mule.example.loanbroker.messages.CustomerQuoteRequest;
14  import org.mule.example.loanbroker.messages.LoanQuote;
15  import org.mule.transport.NullPayload;
16  import org.mule.util.ExceptionHolder;
17  import org.mule.util.StringMessageUtils;
18  
19  import java.beans.ExceptionListener;
20  
21  import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
22  
23  import org.apache.commons.lang.time.StopWatch;
24  
25  import static org.junit.Assert.assertFalse;
26  import static org.junit.Assert.assertNotNull;
27  import static org.junit.Assert.assertTrue;
28  import static org.junit.Assert.fail;
29  
30  /**
31   * Tests the Loan Broker application asynchronously.  Note that a simple thread delay is used to wait for the
32   * incoming responses to arrive.  This may or may not be sufficient depending on external factors (processor
33   * speed, logging detail, etc.).  To make the tests reliable, a more accurate mechanism should be employed
34   * (notifications, thread-safe counter, etc.)
35   */
36  public abstract class AbstractAsynchronousLoanBrokerTestCase extends AbstractLoanBrokerTestCase
37  {
38  
39      @Override
40      protected int getNumberOfRequests()
41      {
42          return 100;
43      }
44  
45      /** Milliseconds to wait after sending each message in order for the thread to "catch up" with the test. */
46      protected int getDelay()
47      {
48          return 30000;
49      }
50  
51      protected int getWarmUpMessages()
52      {
53          return 50;
54      }
55  
56      @Override
57      public void testSingleLoanRequest() throws Exception
58      {
59          final MuleClient client = muleContext.getClient();
60          Customer c = new Customer("Ross Mason", 1234);
61          CustomerQuoteRequest request = new CustomerQuoteRequest(c, 10000, 48);
62          // Send asynchronous request
63          client.dispatch("CustomerRequests", request, null);
64  
65          // Wait for asynchronous response
66          MuleMessage result = client.request("CustomerResponses", getDelay());
67          assertNotNull("Result is null", result);
68          assertFalse("Result is null", result.getPayload() instanceof NullPayload);
69          assertTrue("Result should be LoanQuote but is " + result.getPayload().getClass().getName(),
70                  result.getPayload() instanceof LoanQuote);
71          LoanQuote quote = (LoanQuote) result.getPayload();
72          assertNotNull(quote.getBankName());
73          assertTrue(quote.getInterestRate() > 0);
74      }
75  
76      @Override
77      public void testLotsOfLoanRequests() throws Exception
78      {
79          final MuleClient client = muleContext.getClient();
80          Customer c = new Customer("Ross Mason", 1234);
81          CustomerQuoteRequest[] requests = new CustomerQuoteRequest[3];
82          requests[0] = new CustomerQuoteRequest(c, 100000, 48);
83          requests[1] = new CustomerQuoteRequest(c, 1000, 12);
84          requests[2] = new CustomerQuoteRequest(c, 10, 24);
85  
86          final StopWatch stopWatch = new StopWatch();
87  
88          final int numRequests = getNumberOfRequests() + getWarmUpMessages();
89          int i = 0;
90  
91          int numberOfThreads = 1;
92  
93          CountDownLatch latch = new CountDownLatch(numberOfThreads);
94          ExceptionHolder exceptionHolder = new ExceptionHolder();
95          try
96          {
97              for (int x = 0; x < numberOfThreads; x++)
98              {
99                  Thread thread = new Thread(new ClientReceiver(latch, numRequests / numberOfThreads, exceptionHolder));
100                 thread.start();
101             }
102 
103 
104             for (i = 0; i < numRequests; i++)
105             {
106                 if (i == getWarmUpMessages())
107                 {
108                     stopWatch.start();
109                 }
110                 client.dispatch("CustomerRequests", requests[i % 3], null);
111             }
112         }
113         finally
114         {
115             latch.await();
116             stopWatch.stop();
117             System.out.println("Total running time was: " + stopWatch.getTime() + "ms");
118             System.out.println("Requests processed was: " + i);
119             int mps = (int) (numRequests / ((double) stopWatch.getTime() / (double) 1000));
120             System.out.println("Msg/sec: " + mps + " (warm up msgs = " + getWarmUpMessages() + ")");
121             if(exceptionHolder.isExceptionThrown())
122             {
123                 exceptionHolder.print();
124                 fail("Exceptions thrown during async processing");
125             }
126         }
127     }
128 
129     private class ClientReceiver implements Runnable
130     {
131 
132         private CountDownLatch latch;
133         private int numberOfRequests;
134         private ExceptionListener exListener;
135 
136         public ClientReceiver(CountDownLatch latch, int numberOfRequests, ExceptionListener exListener)
137         {
138             this.latch = latch;
139             this.numberOfRequests = numberOfRequests;
140             this.exListener = exListener;
141         }
142 
143         public void run()
144         {
145             int i = 0;
146             try
147             {
148                 final MuleClient client = muleContext.getClient();
149                 MuleMessage result = null;
150                 for (i = 0; i < numberOfRequests; i++)
151                 {
152                     try
153                     {
154                         result = client.request("CustomerResponses", getDelay());
155                     }
156                     catch (MuleException e)
157                     {
158                         exListener.exceptionThrown(e);
159                         break;
160                     }
161                     //System.out.println("Received: " + i);
162                     assertNotNull("Result is null", result);
163                     assertFalse("Result is null", result.getPayload() instanceof NullPayload);
164                     assertTrue("Result should be LoanQuote but is " + result.getPayload().getClass().getName(),
165                             result.getPayload() instanceof LoanQuote);
166                     LoanQuote quote = (LoanQuote) result.getPayload();
167                     assertTrue(quote.getInterestRate() > 0);
168                 }
169             }
170             catch (Throwable e)
171             {
172                 //e.printStackTrace();
173                 System.out.println(StringMessageUtils.getBoilerPlate("Processed Messages=" + i));
174                 if(e instanceof Error)
175                 {
176                     //throw (Error)e;
177                     exListener.exceptionThrown(new Exception(e));
178                 }
179                 else
180                 {
181                     exListener.exceptionThrown((Exception)e);
182                 }
183             }
184             finally
185             {
186                 latch.countDown();
187             }
188         }
189     }
190 }