View Javadoc

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