View Javadoc

1   /*
2    * $Id: OutboundEndpointTestCase.java 23030 2011-09-26 18:02:33Z 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.endpoint.outbound;
12  
13  import org.mule.MessageExchangePattern;
14  import org.mule.RequestContext;
15  import org.mule.api.MuleEvent;
16  import org.mule.api.MuleException;
17  import org.mule.api.MuleMessage;
18  import org.mule.api.config.MuleProperties;
19  import org.mule.api.endpoint.OutboundEndpoint;
20  import org.mule.api.lifecycle.LifecycleException;
21  import org.mule.api.routing.filter.Filter;
22  import org.mule.api.security.SecurityFilter;
23  import org.mule.api.transaction.TransactionConfig;
24  import org.mule.api.transformer.Transformer;
25  import org.mule.api.transport.Connector;
26  import org.mule.api.transport.MessageDispatcher;
27  import org.mule.context.notification.EndpointMessageNotification;
28  import org.mule.context.notification.SecurityNotification;
29  import org.mule.endpoint.AbstractMessageProcessorTestCase;
30  import org.mule.endpoint.EndpointURIEndpointBuilder;
31  import org.mule.tck.security.TestSecurityFilter;
32  import org.mule.tck.testmodels.mule.TestMessageDispatcher;
33  import org.mule.tck.testmodels.mule.TestMessageDispatcherFactory;
34  import org.mule.transformer.simple.OutboundAppendTransformer;
35  import org.mule.transformer.simple.ResponseAppendTransformer;
36  import org.mule.transport.AbstractMessageDispatcher;
37  import org.mule.util.concurrent.Latch;
38  
39  import java.util.concurrent.TimeUnit;
40  
41  import org.junit.Test;
42  
43  import static org.junit.Assert.assertEquals;
44  import static org.junit.Assert.assertNotNull;
45  import static org.junit.Assert.assertNotSame;
46  import static org.junit.Assert.assertNull;
47  import static org.junit.Assert.assertTrue;
48  import static org.junit.Assert.fail;
49  
50  /**
51   * Tests flow of messages from {@link OutboundEndpoint#process(MuleEvent)} down to
52   * {@link AbstractMessageDispatcher} and the chain of MessageProcessor's that
53   * implement the outbound endpoint processing.
54   */
55  public class OutboundEndpointTestCase extends AbstractMessageProcessorTestCase
56  {
57      protected FakeMessageDispatcher dispacher;
58      protected MuleEvent testOutboundEvent;
59  
60      @Test
61      public void testDefaultFlowSync() throws Exception
62      {
63          OutboundEndpoint endpoint = createOutboundEndpoint(null, null, null, null, 
64              MessageExchangePattern.REQUEST_RESPONSE, null);
65  
66          testOutboundEvent = createTestOutboundEvent();
67          MuleEvent result = endpoint.process(testOutboundEvent);
68  
69          assertMessageSentSame(true);
70  
71          // Response message is not the same because we rewrite the response event and
72          // this change the properties
73          // (See: OutboundRewriteResponseEventMessageProcessor)
74          assertNotSame(responseMessage, result.getMessage());
75  
76          // Everything else about the message apart from addition of encoding property
77          // is the same though
78          assertMessageEqualEncodingPropertyAdded(responseMessage, result.getMessage());
79  
80      }
81  
82      @Test
83      public void testDefaultFlowAsync() throws Exception
84      {
85          OutboundEndpoint endpoint = createOutboundEndpoint(null, null, null, null, 
86              MessageExchangePattern.ONE_WAY, null);
87  
88          testOutboundEvent = createTestOutboundEvent();
89          MuleEvent result = endpoint.process(testOutboundEvent);
90  
91          dispacher.latch.await(RECEIVE_TIMEOUT, TimeUnit.MILLISECONDS);
92          assertMessageSentSame(false);
93          assertNull(result);
94      }
95  
96      @Test
97      public void testSecurityFilterAccept() throws Exception
98      {
99          OutboundEndpoint endpoint = createOutboundEndpoint(null, new TestSecurityFilter(true), 
100             null, null, MessageExchangePattern.REQUEST_RESPONSE, null);
101 
102         testOutboundEvent = createTestOutboundEvent();
103         MuleEvent result = endpoint.process(testOutboundEvent);
104 
105         assertMessageSentSame(true);
106 
107         // Response message is not the same because we rewrite the response event and
108         // this change the properties
109         // (See: OutboundRewriteResponseEventMessageProcessor)
110         assertNotSame(responseMessage, result.getMessage());
111 
112         // Everything else about the message apart from addition of encoding property
113         // is the same though
114         assertMessageEqualEncodingPropertyAdded(responseMessage, result.getMessage());
115     }
116 
117     @Test
118     public void testSecurityFilterNotAccept() throws Exception
119     {
120         TestSecurityNotificationListener securityNotificationListener = new TestSecurityNotificationListener();
121         muleContext.registerListener(securityNotificationListener);
122 
123         OutboundEndpoint endpoint = createOutboundEndpoint(null, new TestSecurityFilter(false), 
124             null, null, MessageExchangePattern.REQUEST_RESPONSE, null);
125 
126         testOutboundEvent = createTestOutboundEvent();
127         RequestContext.setEvent(testOutboundEvent);
128         try
129         {
130             endpoint.process(testOutboundEvent);
131             fail("Exception expected");
132         }
133         catch (TestSecurityFilter.StaticMessageUnauthorisedException e)
134         {
135             testOutboundEvent.getFlowConstruct().getExceptionListener().handleException(e, testOutboundEvent);
136         }
137 
138         assertMessageNotSent();
139 
140         assertTrue(securityNotificationListener.latch.await(RECEIVE_TIMEOUT, TimeUnit.MILLISECONDS));
141         assertEquals(SecurityNotification.SECURITY_AUTHENTICATION_FAILED,
142             securityNotificationListener.securityNotification.getAction());
143         assertEquals(securityNotificationListener.securityNotification.getResourceIdentifier(),
144             TestSecurityFilter.StaticMessageUnauthorisedException.class.getName());
145     }
146 
147     @Test
148     public void testSendNotfication() throws Exception
149     {
150         TestEndpointMessageNotificationListener listener = new TestEndpointMessageNotificationListener(2);
151         muleContext.registerListener(listener);
152 
153         OutboundEndpoint endpoint = createOutboundEndpoint(null, null, null, null, 
154             MessageExchangePattern.REQUEST_RESPONSE, null);
155         MuleEvent outboundEvent = createTestOutboundEvent();
156         endpoint.process(outboundEvent);
157 
158         assertTrue(listener.latch.await(RECEIVE_TIMEOUT, TimeUnit.MILLISECONDS));
159         assertEquals(2, listener.messageNotificationList.size());
160         assertEquals(EndpointMessageNotification.MESSAGE_SEND_BEGIN, listener.messageNotificationList.get(0).getAction());
161         assertEquals(EndpointMessageNotification.MESSAGE_SEND_END, listener.messageNotificationList.get(1).getAction());
162         assertEquals(endpoint.getEndpointURI().getUri().toString(),
163             listener.messageNotificationList.get(0).getEndpoint());
164                 assertEquals(endpoint.getEndpointURI().getUri().toString(),
165             listener.messageNotificationList.get(1).getEndpoint());
166         assertTrue(listener.messageNotificationList.get(0).getSource() instanceof MuleMessage);
167         assertTrue(listener.messageNotificationList.get(1).getSource() instanceof MuleMessage);
168         assertEquals(outboundEvent.getMessage().getPayload(),
169             listener.messageNotificationList.get(0).getSource().getPayload());
170         assertEquals(RESPONSE_MESSAGE,
171             listener.messageNotificationList.get(1).getSource().getPayload());
172     }
173 
174     @Test
175     public void testDispatchNotfication() throws Exception
176     {
177         TestEndpointMessageNotificationListener listener = new TestEndpointMessageNotificationListener(2);
178         muleContext.registerListener(listener);
179 
180         OutboundEndpoint endpoint = createOutboundEndpoint(null, null, null, null, 
181             MessageExchangePattern.ONE_WAY, null);
182         MuleEvent outboundEvent = createTestOutboundEvent();
183         endpoint.process(outboundEvent);
184 
185         assertTrue(listener.latch.await(RECEIVE_TIMEOUT, TimeUnit.MILLISECONDS));
186         assertEquals(2, listener.messageNotificationList.size());
187         assertEquals(EndpointMessageNotification.MESSAGE_DISPATCH_BEGIN, listener.messageNotificationList.get(0).getAction());
188         assertEquals(EndpointMessageNotification.MESSAGE_DISPATCH_END, listener.messageNotificationList.get(1).getAction());
189         assertEquals(endpoint.getEndpointURI().getUri().toString(),
190             listener.messageNotificationList.get(0).getEndpoint());
191                 assertEquals(endpoint.getEndpointURI().getUri().toString(),
192             listener.messageNotificationList.get(1).getEndpoint());
193         assertTrue(listener.messageNotificationList.get(0).getSource() instanceof MuleMessage);
194         assertTrue(listener.messageNotificationList.get(1).getSource() instanceof MuleMessage);
195         assertEquals(outboundEvent.getMessage().getPayload(),
196             listener.messageNotificationList.get(0).getSource().getPayload());
197         assertEquals(outboundEvent.getMessage().getPayload(),
198             listener.messageNotificationList.get(1).getSource().getPayload());
199     }
200 
201     @Test
202     public void testTransformers() throws Exception
203     {
204         OutboundEndpoint endpoint = createOutboundEndpoint(null, null, new OutboundAppendTransformer(),
205             new ResponseAppendTransformer(), MessageExchangePattern.REQUEST_RESPONSE, null);
206         MuleEvent outboundEvent = createTestOutboundEvent();
207         MuleEvent result = endpoint.process(outboundEvent);
208 
209         assertMessageSent(true);
210 
211         assertEquals(TEST_MESSAGE + OutboundAppendTransformer.APPEND_STRING,
212         dispacher.sensedSendEvent.getMessageAsString());
213 
214         assertNotNull(result);
215         assertEquals(RESPONSE_MESSAGE + ResponseAppendTransformer.APPEND_STRING, result.getMessageAsString());
216     }
217 
218     @Test
219     public void testConnectorNotStarted() throws Exception
220     {
221         OutboundEndpoint endpoint = createOutboundEndpoint(null, null, null, null, 
222             MessageExchangePattern.REQUEST_RESPONSE, null);
223         testOutboundEvent = createTestOutboundEvent();
224         endpoint.getConnector().stop();
225 
226         try
227         {
228             endpoint.process(testOutboundEvent);
229             fail("Exception expected");
230         }
231         catch (LifecycleException e)
232         {
233             // expected
234         }
235     }
236 
237     @Test
238     public void testTimeoutSetOnEvent() throws Exception
239     {
240 
241         int testTimeout = 999;
242 
243         OutboundEndpoint endpoint = createOutboundEndpoint(null, null, null, null, 
244             MessageExchangePattern.REQUEST_RESPONSE, null);
245         testOutboundEvent = createTestOutboundEvent();
246         testOutboundEvent.getMessage()
247             .setOutboundProperty(MuleProperties.MULE_EVENT_TIMEOUT_PROPERTY, testTimeout);
248 
249         endpoint.process(testOutboundEvent);
250 
251         assertEquals(testTimeout, dispacher.sensedSendEvent.getTimeout());
252     }
253     
254     @Test
255     public void testObjectAwareInjection() throws Exception
256     {
257         EndpointURIEndpointBuilder endpointBuilder = new EndpointURIEndpointBuilder(TEST_URI, muleContext);
258         endpointBuilder.addMessageProcessor(new ObjectAwareProcessor());
259 
260         OutboundEndpoint endpoint = endpointBuilder.buildOutboundEndpoint();
261         endpoint.process(createTestOutboundEvent());
262         
263         ObjectAwareProcessor objectAware = (ObjectAwareProcessor) endpoint.getMessageProcessors().get(0);
264         
265         assertEquals(muleContext, objectAware.context);
266         assertEquals(endpoint, objectAware.endpoint);
267     }
268 
269     @Test
270     public void testTransaction()
271     {
272         // TODO
273     }
274 
275     @Test
276     public void testExceptionHandling()
277     {
278         // TODO
279     }
280 
281     protected MuleEvent assertMessageSent(boolean sync) throws MuleException
282     {
283         MuleEvent event;
284         if (sync)
285         {
286             assertNull(dispacher.sensedDispatchEvent);
287             assertNotNull(dispacher.sensedSendEvent);
288             event = dispacher.sensedSendEvent;
289         }
290         else
291         {
292             assertNull(dispacher.sensedSendEvent);
293             assertNotNull(dispacher.sensedDispatchEvent);
294             event = dispacher.sensedDispatchEvent;
295         }
296         assertNotNull(event.getMessage());
297         return event;
298     }
299 
300     protected MuleEvent assertMessageSentSame(boolean sync) throws MuleException
301     {
302         MuleEvent event = assertMessageSent(sync);
303         if (sync)
304         {
305             // We can't assert this for async because event gets rewritten
306             assertEquals(testOutboundEvent, event);
307         }
308         assertEquals(TEST_MESSAGE, event.getMessageAsString());
309         assertEquals("value1", event.getMessage().getOutboundProperty("prop1"));
310         return event;
311     }
312 
313     protected void assertMessageNotSent() throws MuleException
314     {
315         assertNull(dispacher.sensedSendEvent);
316         assertNull(dispacher.sensedDispatchEvent);
317     }
318 
319     protected void assertMessageEqualEncodingPropertyAdded(MuleMessage expect, MuleMessage actual)
320     {
321         assertEquals(expect.getPayload(), actual.getPayload());
322         assertEquals(expect.getEncoding(), actual.getEncoding());
323         assertEquals(expect.getUniqueId(), actual.getUniqueId());
324         assertEquals(expect.getExceptionPayload(), actual.getExceptionPayload());
325 
326         // Outbound endcodin property is added
327         assertEquals(muleContext.getConfiguration().getDefaultEncoding(),
328                      actual.getOutboundProperty(MuleProperties.MULE_ENCODING_PROPERTY));
329 
330     }
331 
332     protected OutboundEndpoint createOutboundEndpoint(String uri, Filter filter,
333                                                       SecurityFilter securityFilter,
334                                                       Transformer in,
335                                                       Transformer response,
336                                                       MessageExchangePattern exchangePattern,
337                                                       TransactionConfig txConfig) throws Exception
338     {
339 
340         OutboundEndpoint endpoint = createTestOutboundEndpoint(uri, filter, securityFilter, in, response,
341             exchangePattern, txConfig);
342         dispacher = new FakeMessageDispatcher(endpoint);
343         Connector connector = endpoint.getConnector();
344         connector.setDispatcherFactory(new TestMessageDispatcherFactory()
345         {
346             @Override
347             public MessageDispatcher create(OutboundEndpoint ep) throws MuleException
348             {
349                 return dispacher;
350             }
351 
352         });
353         return endpoint;
354     }
355 
356     protected OutboundEndpoint createOutboundEndpoint(Filter filter,
357                                                       SecurityFilter securityFilter,
358                                                       Transformer in,
359                                                       Transformer response,
360                                                       MessageExchangePattern exchangePattern,
361                                                       TransactionConfig txConfig) throws Exception
362     {
363         return createOutboundEndpoint("test://test", filter, securityFilter, in, response, exchangePattern, txConfig);
364 
365     }
366 
367     static class FakeMessageDispatcher extends TestMessageDispatcher
368     {
369         Latch latch = new Latch();
370         MuleEvent sensedSendEvent;
371         MuleEvent sensedDispatchEvent;
372 
373         public FakeMessageDispatcher(OutboundEndpoint endpoint)
374         {
375             super(endpoint);
376         }
377 
378         @Override
379         protected MuleMessage doSend(MuleEvent event) throws Exception
380         {
381             sensedSendEvent = event;
382             latch.countDown();
383             return responseMessage;
384         }
385 
386         @Override
387         protected void doDispatch(MuleEvent event) throws Exception
388         {
389             sensedDispatchEvent = event;
390             latch.countDown();
391         }
392     }
393 
394 }