View Javadoc

1   /*
2    * $Id: InboundEndpointTestCase.java 22377 2011-07-11 12:41:42Z dirk.olmes $
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.inbound;
12  
13  import org.mule.DefaultMuleEvent;
14  import org.mule.DefaultMuleMessage;
15  import org.mule.MessageExchangePattern;
16  import org.mule.RequestContext;
17  import org.mule.api.MuleEvent;
18  import org.mule.api.MuleException;
19  import org.mule.api.MuleMessage;
20  import org.mule.api.endpoint.InboundEndpoint;
21  import org.mule.api.processor.MessageProcessor;
22  import org.mule.api.routing.filter.Filter;
23  import org.mule.api.routing.filter.FilterUnacceptedException;
24  import org.mule.api.security.EndpointSecurityFilter;
25  import org.mule.context.notification.EndpointMessageNotification;
26  import org.mule.context.notification.SecurityNotification;
27  import org.mule.endpoint.AbstractEndpoint;
28  import org.mule.endpoint.AbstractMessageProcessorTestCase;
29  import org.mule.endpoint.EndpointURIEndpointBuilder;
30  import org.mule.message.DefaultExceptionPayload;
31  import org.mule.processor.NullMessageProcessor;
32  import org.mule.tck.security.TestSecurityFilter;
33  import org.mule.transformer.simple.InboundAppendTransformer;
34  import org.mule.transformer.simple.ResponseAppendTransformer;
35  
36  import java.util.HashMap;
37  import java.util.Map;
38  import java.util.concurrent.TimeUnit;
39  
40  import org.junit.Test;
41  
42  import static org.junit.Assert.assertEquals;
43  import static org.junit.Assert.assertFalse;
44  import static org.junit.Assert.assertNotNull;
45  import static org.junit.Assert.assertNull;
46  import static org.junit.Assert.assertTrue;
47  import static org.junit.Assert.fail;
48  
49  public class InboundEndpointTestCase extends AbstractMessageProcessorTestCase
50  {
51      private static final String TEST_MESSAGE = "test";
52      private InboundEndpoint endpoint;
53      private SensingNullMessageProcessor inboundListener;
54      private MuleMessage inMessage;
55      private MuleEvent requestEvent;
56      private MuleEvent responseEvent;
57      private MuleEvent result;
58  
59      private static String RESPONSE_MESSAGE = "response-message";
60  
61      @Override
62      protected void doSetUp() throws Exception
63      {
64          super.doSetUp();
65          inMessage = createTestRequestMessage();
66          inboundListener = new SensingNullMessageProcessor();
67      }
68  
69      @Test
70      public void testDefaultFlowSync() throws Exception
71      {
72          endpoint = createTestInboundEndpoint(null, null, null, null,
73              MessageExchangePattern.REQUEST_RESPONSE, null);
74          endpoint.setListener(inboundListener);
75          requestEvent = createTestRequestEvent(endpoint);
76          responseEvent = createTestResponseEvent(endpoint);
77  
78          MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
79          result = mpChain.process(requestEvent);
80  
81          assertMessageSentSame(true);
82          assertEquals(responseEvent.getMessage(), result.getMessage());
83      }
84  
85      @Test
86      public void testDefaultFlowAsync() throws Exception
87      {
88          endpoint = createTestInboundEndpoint(null, null, null, null,
89              MessageExchangePattern.ONE_WAY, null);
90          endpoint.setListener(inboundListener);
91          requestEvent = createTestRequestEvent(endpoint);
92          responseEvent = createTestResponseEvent(endpoint);
93  
94          MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
95          result = mpChain.process(requestEvent);
96  
97          assertMessageSentSame(false);
98          assertEquals(responseEvent.getMessage(), result.getMessage());
99      }
100 
101     @Test
102     public void testFilterAccept() throws Exception
103     {
104         endpoint = createTestInboundEndpoint(new TestFilter(true), null, null, null,
105             MessageExchangePattern.REQUEST_RESPONSE, null);
106         endpoint.setListener(inboundListener);
107         requestEvent = createTestRequestEvent(endpoint);
108         responseEvent = createTestResponseEvent(endpoint);
109 
110         MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
111         result = mpChain.process(requestEvent);
112 
113         assertMessageSentSame(true);
114         assertEquals(responseEvent.getMessage(), result.getMessage());
115 
116     }
117 
118     @Test
119     public void testFilterNotAccept() throws Exception
120     {
121         endpoint = createTestInboundEndpoint(new TestFilter(false), null, null, null,
122             MessageExchangePattern.REQUEST_RESPONSE, null);
123         endpoint.setListener(inboundListener);
124         requestEvent = createTestRequestEvent(endpoint);
125         responseEvent = createTestResponseEvent(endpoint);
126 
127         MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
128 
129         try
130         {
131             result = mpChain.process(requestEvent);
132             fail("Filter should have thrown a FilterException");
133         }
134         catch (FilterUnacceptedException e)
135         {
136             // expected
137         }
138 
139         assertMessageNotSent();
140     }
141 
142     @Test
143     public void testSecurityFilterAccept() throws Exception
144     {
145         endpoint = createTestInboundEndpoint(null, new TestSecurityFilter(true), null, null,
146             MessageExchangePattern.REQUEST_RESPONSE, null);
147         endpoint.setListener(inboundListener);
148         requestEvent = createTestRequestEvent(endpoint);
149         responseEvent = createTestResponseEvent(endpoint);
150 
151         MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
152         result = mpChain.process(requestEvent);
153 
154         assertMessageSentSame(true);
155         assertEquals(responseEvent.getMessage(), result.getMessage());
156 
157     }
158 
159     @Test
160     public void testSecurityFilterNotAccept() throws Exception
161     {
162         TestSecurityNotificationListener securityNotificationListener = new TestSecurityNotificationListener();
163         muleContext.registerListener(securityNotificationListener);
164 
165         endpoint = createTestInboundEndpoint(null, new TestSecurityFilter(false), null, null,
166             MessageExchangePattern.REQUEST_RESPONSE, null);
167         endpoint.setListener(inboundListener);
168         requestEvent = createTestRequestEvent(endpoint);
169         responseEvent = createTestResponseEvent(endpoint);
170 
171         MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
172 
173         // Required for UnauthorisedException creation
174         RequestContext.setEvent(requestEvent);
175 
176         try
177         {
178             result = mpChain.process(requestEvent);
179             fail("Exception expected");
180         }
181         catch (TestSecurityFilter.StaticMessageUnauthorisedException e)
182         {
183             requestEvent.getFlowConstruct().getExceptionListener().handleException(e, requestEvent);
184         }
185 
186         assertTrue(securityNotificationListener.latch.await(RECEIVE_TIMEOUT, TimeUnit.MILLISECONDS));
187         assertEquals(SecurityNotification.SECURITY_AUTHENTICATION_FAILED,
188             securityNotificationListener.securityNotification.getAction());
189         assertEquals(securityNotificationListener.securityNotification.getResourceIdentifier(),
190             TestSecurityFilter.StaticMessageUnauthorisedException.class.getName());
191     }
192 
193     /**
194      * Assert that {@link EndpointSecurityFilter} is only invoked if endpoint
195      * {@link Filter} accepts message.
196      */
197     @Test
198     public void testFilterFirstThenSecurityFilter() throws Exception
199     {
200         TestSecurityFilter securityFilter = new TestSecurityFilter(false);
201         endpoint = createTestInboundEndpoint(new TestFilter(false), securityFilter, null, null,
202             MessageExchangePattern.REQUEST_RESPONSE, null);
203         endpoint.setListener(inboundListener);
204         requestEvent = createTestRequestEvent(endpoint);
205         responseEvent = createTestResponseEvent(endpoint);
206 
207         MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
208 
209         try
210         {
211             result = mpChain.process(requestEvent);
212             fail("Filter should have thrown a FilterException");
213         }
214         catch (FilterUnacceptedException e)
215         {
216             // expected
217         }
218 
219         assertFalse(securityFilter.wasCalled());
220         assertMessageNotSent();
221     }
222 
223     @Test
224     public void testMessagePropertyErrorMapping() throws Exception
225     {
226         endpoint = createTestInboundEndpoint(null, null, null, null,
227             MessageExchangePattern.REQUEST_RESPONSE, null);
228         endpoint.setListener(inboundListener);
229         requestEvent = createTestRequestEvent(endpoint);
230         responseEvent = createTestResponseEvent(endpoint);
231         responseEvent.getMessage().setExceptionPayload(new DefaultExceptionPayload(new RuntimeException()));
232 
233         MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
234         result = mpChain.process(requestEvent);
235 
236         assertMessageSentSame(true);
237         assertEquals(responseEvent.getMessage(), result.getMessage());
238         final int status = result.getMessage().getOutboundProperty("status", 0);
239         assertEquals(500, status);
240     }
241 
242     @Test
243     public void testResponseTransformerExceptionDetailAfterRequestFlowInterupt() throws Exception
244     {
245         endpoint = createTestInboundEndpoint(null, new TestSecurityFilter(false), null,
246             new ResponseAppendTransformer(), MessageExchangePattern.REQUEST_RESPONSE, null);
247         endpoint.setListener(inboundListener);
248         requestEvent = createTestRequestEvent(endpoint);
249         responseEvent = createTestResponseEvent(endpoint);
250         responseEvent.getMessage().setExceptionPayload(new DefaultExceptionPayload(new RuntimeException()));
251 
252         MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
253 
254         // Required for UnauthorisedException creation
255         RequestContext.setEvent(requestEvent);
256 
257         try
258         {
259             result = mpChain.process(requestEvent);
260             fail("Exception expected");
261         }
262         catch (TestSecurityFilter.StaticMessageUnauthorisedException e)
263         {
264             // expected
265         }
266 
267         assertMessageNotSent();
268     }
269 
270     @Test
271     public void testNotfication() throws Exception
272     {
273         TestEndpointMessageNotificationListener listener = new TestEndpointMessageNotificationListener();
274         muleContext.registerListener(listener);
275 
276         endpoint = createTestInboundEndpoint(null, null, null, null,
277             MessageExchangePattern.REQUEST_RESPONSE, null);
278         endpoint.setListener(inboundListener);
279         requestEvent = createTestRequestEvent(endpoint);
280         responseEvent = createTestResponseEvent(endpoint);
281 
282         MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
283         result = mpChain.process(requestEvent);
284 
285         assertTrue(listener.latch.await(RECEIVE_TIMEOUT, TimeUnit.MILLISECONDS));
286         assertEquals(EndpointMessageNotification.MESSAGE_RECEIVED, listener.messageNotification.getAction());
287         assertEquals(endpoint.getEndpointURI().getUri().toString(),
288             listener.messageNotification.getEndpoint());
289         assertTrue(listener.messageNotification.getSource() instanceof MuleMessage);
290         assertEquals(inMessage.getPayload(), listener.messageNotification.getSource().getPayload());
291     }
292 
293     @Test
294     public void testTransformers() throws Exception
295     {
296         endpoint = createTestInboundEndpoint(null, null, new InboundAppendTransformer(),
297             new ResponseAppendTransformer(), MessageExchangePattern.REQUEST_RESPONSE, null);
298         endpoint.setListener(inboundListener);
299         requestEvent = createTestRequestEvent(endpoint);
300         responseEvent = createTestResponseEvent(endpoint);
301 
302         MessageProcessor mpChain = ((AbstractEndpoint) endpoint).getMessageProcessorChain(requestEvent.getFlowConstruct());
303         result = mpChain.process(requestEvent);
304 
305         assertMessageSent(true);
306         assertEquals(TEST_MESSAGE + InboundAppendTransformer.APPEND_STRING,
307             inboundListener.sensedEvent.getMessageAsString());
308 
309         assertNotNull(result);
310         assertEquals(RESPONSE_MESSAGE + ResponseAppendTransformer.APPEND_STRING,
311             result.getMessage().getPayloadAsString());
312     }
313 
314     @Test
315     public void testObjectAwareInjection() throws Exception
316     {
317         EndpointURIEndpointBuilder endpointBuilder = new EndpointURIEndpointBuilder(TEST_URI, muleContext);
318         endpointBuilder.addMessageProcessor(new ObjectAwareProcessor());
319 
320         endpoint = endpointBuilder.buildInboundEndpoint();
321         endpoint.setListener(new NullMessageProcessor());
322         endpoint.setFlowConstruct(getTestService());
323         endpoint.start();
324 
325         ObjectAwareProcessor objectAware = (ObjectAwareProcessor) endpoint.getMessageProcessors().get(0);
326 
327         assertEquals(muleContext, objectAware.context);
328         assertEquals(endpoint, objectAware.endpoint);
329 
330         endpoint.stop();
331     }
332 
333     protected MuleMessage createTestRequestMessage()
334     {
335         Map<String, Object> props = new HashMap<String, Object>();
336         props.put("prop1", "value1");
337         return new DefaultMuleMessage(TEST_MESSAGE, props, muleContext);
338     }
339 
340     protected MuleEvent createTestRequestEvent(InboundEndpoint ep) throws Exception
341     {
342         return new DefaultMuleEvent(inMessage, ep, getTestSession(getTestService(), muleContext));
343     }
344 
345     protected MuleEvent createTestResponseEvent(InboundEndpoint ep) throws Exception
346     {
347         return new DefaultMuleEvent(new DefaultMuleMessage(RESPONSE_MESSAGE, muleContext),
348             ep, getTestSession(getTestService(), muleContext));
349     }
350 
351     protected MuleEvent assertMessageSent(boolean sync) throws MuleException
352     {
353         MuleEvent event = inboundListener.sensedEvent;
354         assertNotNull(event);
355         assertEquals(sync, event.getExchangePattern().hasResponse());
356         assertNotNull(event.getMessage());
357         return event;
358     }
359 
360     protected MuleEvent assertMessageSentSame(boolean sync) throws MuleException
361     {
362         assertMessageSent(sync);
363         MuleEvent event = inboundListener.sensedEvent;
364         assertEquals(inMessage, event.getMessage());
365         assertEquals(TEST_MESSAGE, event.getMessageAsString());
366         assertEquals("value1", event.getMessage().getOutboundProperty("prop1"));
367         return event;
368     }
369 
370     protected void assertMessageNotSent() throws MuleException
371     {
372         MuleEvent event = inboundListener.sensedEvent;
373         assertNull(event);
374     }
375 
376     private class SensingNullMessageProcessor implements MessageProcessor
377     {
378         MuleEvent sensedEvent;
379 
380         @Override
381         public MuleEvent process(MuleEvent event) throws MuleException
382         {
383             sensedEvent = event;
384             return responseEvent;
385         }
386     }
387 }