View Javadoc

1   /*
2    * $Id: UntilSuccessfulTestCase.java 22812 2011-09-01 06:57:42Z mike.schilling $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
9    */
10  
11  package org.mule.routing;
12  
13  import org.mule.api.MuleEvent;
14  import org.mule.api.MuleException;
15  import org.mule.api.endpoint.EndpointBuilder;
16  import org.mule.api.endpoint.OutboundEndpoint;
17  import org.mule.api.processor.MessageProcessor;
18  import org.mule.api.store.ListableObjectStore;
19  import org.mule.tck.junit4.AbstractMuleContextTestCase;
20  import org.mule.util.store.SimpleMemoryObjectStore;
21  
22  import java.io.ByteArrayInputStream;
23  
24  import org.junit.Test;
25  
26  import static org.junit.Assert.assertEquals;
27  import static org.junit.Assert.assertNull;
28  import static org.mockito.Matchers.any;
29  import static org.mockito.Mockito.mock;
30  import static org.mockito.Mockito.verify;
31  import static org.mockito.Mockito.when;
32  
33  public class UntilSuccessfulTestCase extends AbstractMuleContextTestCase
34  {
35      public static class ConfigurableMessageProcessor implements MessageProcessor
36      {
37          private volatile int eventCount;
38          private volatile MuleEvent event;
39          private volatile int numberOfFailuresToSimulate;
40  
41          @Override
42          public MuleEvent process(final MuleEvent evt) throws MuleException
43          {
44              eventCount++;
45              if (numberOfFailuresToSimulate-- > 0)
46              {
47                  throw new RuntimeException("simulated problem");
48              }
49              this.event = evt;
50              return evt;
51          }
52  
53          public MuleEvent getEventReceived()
54          {
55              return event;
56          }
57  
58          public int getEventCount()
59          {
60              return eventCount;
61          }
62  
63          public void setNumberOfFailuresToSimulate(int numberOfFailuresToSimulate)
64          {
65              this.numberOfFailuresToSimulate = numberOfFailuresToSimulate;
66          }
67      }
68  
69      private UntilSuccessful untilSuccessful;
70  
71      private ListableObjectStore<MuleEvent> objectStore;
72      private ConfigurableMessageProcessor targetMessageProcessor;
73  
74      @Override
75      protected void doSetUp() throws Exception
76      {
77          super.doSetUp();
78  
79          untilSuccessful = new UntilSuccessful();
80          untilSuccessful.setMuleContext(muleContext);
81          untilSuccessful.setFlowConstruct(getTestService());
82          untilSuccessful.setMaxRetries(2);
83          untilSuccessful.setSecondsBetweenRetries(1);
84  
85          objectStore = new SimpleMemoryObjectStore<MuleEvent>();
86          untilSuccessful.setObjectStore(objectStore);
87  
88          targetMessageProcessor = new ConfigurableMessageProcessor();
89          untilSuccessful.addRoute(targetMessageProcessor);
90      }
91  
92      @Override
93      protected void doTearDown() throws Exception
94      {
95          untilSuccessful.stop();
96      }
97  
98      @Test
99      public void testSuccessfulDelivery() throws Exception
100     {
101         untilSuccessful.initialise();
102         untilSuccessful.start();
103 
104         final MuleEvent testEvent = getTestEvent("test_data");
105         assertNull(untilSuccessful.process(testEvent));
106         ponderUntilEventProcessed(testEvent);
107     }
108 
109     @Test
110     public void testSuccessfulDeliveryStreamPayload() throws Exception
111     {
112         untilSuccessful.initialise();
113         untilSuccessful.start();
114 
115         final MuleEvent testEvent = getTestEvent(new ByteArrayInputStream("test_data".getBytes()));
116         assertNull(untilSuccessful.process(testEvent));
117         ponderUntilEventProcessed(testEvent);
118     }
119 
120     @Test
121     public void testSuccessfulDeliveryAckExpression() throws Exception
122     {
123         untilSuccessful.setAckExpression("#[string:ACK]");
124         untilSuccessful.initialise();
125         untilSuccessful.start();
126 
127         final MuleEvent testEvent = getTestEvent("test_data");
128         assertEquals("ACK", untilSuccessful.process(testEvent).getMessageAsString());
129         ponderUntilEventProcessed(testEvent);
130     }
131 
132     @Test
133     public void testSuccessfulDeliveryFailureExpression() throws Exception
134     {
135         untilSuccessful.setFailureExpression("#[regex:(?i)error]");
136         untilSuccessful.initialise();
137         untilSuccessful.start();
138 
139         final MuleEvent testEvent = getTestEvent("test_data");
140         assertNull(untilSuccessful.process(testEvent));
141         ponderUntilEventProcessed(testEvent);
142     }
143 
144     @Test
145     public void testPermanentDeliveryFailure() throws Exception
146     {
147         targetMessageProcessor.setNumberOfFailuresToSimulate(Integer.MAX_VALUE);
148 
149         untilSuccessful.initialise();
150         untilSuccessful.start();
151 
152         final MuleEvent testEvent = getTestEvent("ERROR");
153         assertNull(untilSuccessful.process(testEvent));
154         ponderUntilEventAborted(testEvent);
155     }
156 
157     @Test
158     public void testPermanentDeliveryFailureExpression() throws Exception
159     {
160         untilSuccessful.setFailureExpression("#[regex:(?i)error]");
161         untilSuccessful.initialise();
162         untilSuccessful.start();
163 
164         final MuleEvent testEvent = getTestEvent("ERROR");
165         assertNull(untilSuccessful.process(testEvent));
166         ponderUntilEventAborted(testEvent);
167     }
168 
169     @Test
170     public void testPermanentDeliveryFailureDLQ() throws Exception
171     {
172         targetMessageProcessor.setNumberOfFailuresToSimulate(Integer.MAX_VALUE);
173         EndpointBuilder dlqEndpointBuilder = mock(EndpointBuilder.class);
174         OutboundEndpoint dlqEndpoint = mock(OutboundEndpoint.class);
175         when(dlqEndpointBuilder.buildOutboundEndpoint()).thenReturn(dlqEndpoint);
176         untilSuccessful.setDeadLetterQueue(dlqEndpointBuilder);
177         untilSuccessful.initialise();
178         untilSuccessful.start();
179 
180         final MuleEvent testEvent = getTestEvent("ERROR");
181         assertNull(untilSuccessful.process(testEvent));
182         ponderUntilEventAborted(testEvent);
183 
184         verify(dlqEndpoint).process(any(MuleEvent.class));
185     }
186 
187     @Test
188     public void testTemporaryDeliveryFailure() throws Exception
189     {
190         targetMessageProcessor.setNumberOfFailuresToSimulate(untilSuccessful.getMaxRetries());
191 
192         untilSuccessful.initialise();
193         untilSuccessful.start();
194 
195         final MuleEvent testEvent = getTestEvent("ERROR");
196         assertNull(untilSuccessful.process(testEvent));
197         ponderUntilEventProcessed(testEvent);
198         assertEquals(targetMessageProcessor.getEventCount(), untilSuccessful.getMaxRetries() + 1);
199     }
200 
201     @Test
202     public void testPreExistingEvents() throws Exception
203     {
204         final MuleEvent testEvent = getTestEvent("test_data");
205         objectStore.store(UntilSuccessful.EventStoreKey.buildFor(testEvent), testEvent);
206         untilSuccessful.initialise();
207         untilSuccessful.start();
208         ponderUntilEventProcessed(testEvent);
209     }
210 
211     private void ponderUntilEventProcessed(final MuleEvent testEvent)
212         throws InterruptedException, MuleException
213     {
214         while (targetMessageProcessor.getEventReceived() == null)
215         {
216             Thread.yield();
217             Thread.sleep(250L);
218         }
219 
220         assertEquals(0, objectStore.allKeys().size());
221         assertLogicallyEqualEvents(testEvent, targetMessageProcessor.getEventReceived());
222     }
223 
224     private void ponderUntilEventAborted(final MuleEvent testEvent)
225         throws InterruptedException, MuleException
226     {
227         while (targetMessageProcessor.getEventCount() <= untilSuccessful.getMaxRetries())
228         {
229             Thread.yield();
230             Thread.sleep(250L);
231         }
232 
233         assertEquals(0, objectStore.allKeys().size());
234         assertEquals(targetMessageProcessor.getEventCount(), 1 + untilSuccessful.getMaxRetries());
235     }
236 
237     private void assertLogicallyEqualEvents(final MuleEvent testEvent, MuleEvent eventReceived)
238         throws MuleException
239     {
240         // events have been rewritten so are different but the correlation ID has been carried around
241         assertEquals(testEvent.getMessage().getCorrelationId(), eventReceived.getMessage().getCorrelationId());
242         // and their payload
243         assertEquals(testEvent.getMessageAsString(), eventReceived.getMessageAsString());
244     }
245 }