View Javadoc

1   /*
2    * $Id: InboundMessageLossTestCase.java 23284 2011-10-31 23:07:39Z 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.transport.http.reliability;
12  
13  import org.mule.DefaultMuleEvent;
14  import org.mule.DefaultMuleMessage;
15  import org.mule.MessageExchangePattern;
16  import org.mule.api.ExceptionPayload;
17  import org.mule.api.MessagingException;
18  import org.mule.api.MuleContext;
19  import org.mule.api.MuleEvent;
20  import org.mule.api.MuleException;
21  import org.mule.api.MuleMessage;
22  import org.mule.api.MuleSession;
23  import org.mule.api.construct.FlowConstruct;
24  import org.mule.api.exception.RollbackSourceCallback;
25  import org.mule.api.security.Credentials;
26  import org.mule.api.transformer.DataType;
27  import org.mule.api.transformer.Transformer;
28  import org.mule.api.transformer.TransformerException;
29  import org.mule.api.transport.PropertyScope;
30  import org.mule.api.transport.ReplyToHandler;
31  import org.mule.exception.AbstractMessagingExceptionStrategy;
32  import org.mule.exception.DefaultSystemExceptionStrategy;
33  import org.mule.management.stats.ProcessingTime;
34  import org.mule.message.DefaultExceptionPayload;
35  import org.mule.routing.filters.WildcardFilter;
36  import org.mule.tck.DynamicPortTestCase;
37  import org.mule.transport.NullPayload;
38  import org.mule.transport.http.HttpConstants;
39  
40  import org.apache.commons.httpclient.HttpClient;
41  import org.apache.commons.httpclient.HttpMethodBase;
42  import org.apache.commons.httpclient.methods.GetMethod;
43  
44  import javax.activation.DataHandler;
45  import java.io.OutputStream;
46  import java.net.URI;
47  import java.util.List;
48  import java.util.Map;
49  import java.util.Set;
50  
51  /**
52   * Verify that no inbound messages are lost when exceptions occur.  
53   * The message must either make it all the way to the SEDA queue (in the case of 
54   * an asynchronous inbound endpoint), or be restored/rolled back at the source.
55   * 
56   * In the case of the HTTP transport, there is no way to restore the source message
57   * so an exception is simply returned to the client.
58   */
59  public class InboundMessageLossTestCase extends DynamicPortTestCase
60  {
61      protected HttpClient httpClient = new HttpClient();
62      
63      @Override
64      protected String getConfigResources()
65      {
66          return "reliability/inbound-message-loss.xml";
67      }
68  
69      @Override
70      protected void doSetUp() throws Exception
71      {
72          super.doSetUp();
73          
74          // Set SystemExceptionStrategy to redeliver messages (this can only be configured programatically for now)
75          ((DefaultSystemExceptionStrategy) muleContext.getExceptionListener()).setRollbackTxFilter(new WildcardFilter("*"));
76      }
77  
78      public void testNoException() throws Exception
79      {
80          HttpMethodBase request = createRequest(getBaseUri() + "/noException");
81          int status = httpClient.executeMethod(request);
82          assertEquals(HttpConstants.SC_OK, status);
83          assertEquals("Here you go", request.getResponseBodyAsString());
84      }
85      
86      public void testTransformerException() throws Exception
87      {
88          HttpMethodBase request = createRequest(getBaseUri() + "/transformerException");
89          int status = httpClient.executeMethod(request);
90          assertEquals(HttpConstants.SC_INTERNAL_SERVER_ERROR, status);
91          assertTrue(request.getResponseBodyAsString().contains("Failure"));
92      }
93  
94      public void testHandledTransformerException() throws Exception
95      {
96          HttpMethodBase request = createRequest(getBaseUri() + "/handledTransformerException");
97          int status = httpClient.executeMethod(request);
98          assertEquals(HttpConstants.SC_OK, status);
99          assertTrue(request.getResponseBodyAsString().contains("Success"));
100     }
101 
102     public void testNotHandledTransformerException() throws Exception
103     {
104         HttpMethodBase request = createRequest(getBaseUri() + "/notHandledTransformerException");
105         int status = httpClient.executeMethod(request);
106         assertEquals(HttpConstants.SC_INTERNAL_SERVER_ERROR, status);
107         assertTrue(request.getResponseBodyAsString().contains("Bad news"));
108     }
109 
110     public void testRouterException() throws Exception
111     {
112         HttpMethodBase request = createRequest(getBaseUri() + "/routerException");
113         int status = httpClient.executeMethod(request);
114         assertEquals(HttpConstants.SC_INTERNAL_SERVER_ERROR, status);
115         assertTrue(request.getResponseBodyAsString().contains("Failure"));
116     }
117     
118     public void testComponentException() throws Exception
119     {
120         HttpMethodBase request = createRequest(getBaseUri() + "/componentException");
121         int status = httpClient.executeMethod(request);
122         // Component exception occurs after the SEDA queue for an asynchronous request, but since 
123         // this request is synchronous, the failure propagates back to the client.
124         assertEquals(HttpConstants.SC_INTERNAL_SERVER_ERROR, status);
125         assertTrue(request.getResponseBodyAsString().contains("exception"));
126     }    
127 
128     protected HttpMethodBase createRequest(String uri)
129     {
130         return new GetMethod(uri);
131     }
132     
133     protected String getBaseUri()
134     {
135         return "http://localhost:" + getPorts().get(0);
136     }
137     
138     @Override
139     protected int getNumPortsToFind()
140     {
141         return 1;
142     }
143 
144     /**
145      * Custom Exception Handler that handles an exception
146      */
147     public static class Handler extends AbstractMessagingExceptionStrategy
148     {
149         public Handler(MuleContext muleContext)
150         {
151             super(muleContext);
152         }
153 
154         @Override
155         public MuleEvent handleException(Exception ex, MuleEvent event, RollbackSourceCallback rollbackMethod)
156         {
157             doHandleException(ex, event, rollbackMethod);
158             return new DefaultMuleEvent(new DefaultMuleMessage("Success!", muleContext), event);
159         }
160     }
161 
162     /**
163      * Custom Exception Handler that creates a different exception
164      */
165     public static class BadHandler extends AbstractMessagingExceptionStrategy
166     {
167         public BadHandler(MuleContext muleContext)
168         {
169             super(muleContext);
170         }
171 
172         @Override
173         public MuleEvent handleException(Exception ex, MuleEvent event, RollbackSourceCallback rollbackMethod)
174         {
175             doHandleException(ex, event, rollbackMethod);
176             DefaultMuleMessage message = new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
177             message.setExceptionPayload(
178                 new DefaultExceptionPayload(new MessagingException(event, new RuntimeException("Bad news!"))));
179             return new DefaultMuleEvent(message, event);
180         }
181     }
182 }