View Javadoc

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