View Javadoc

1   /*
2    * $Id: AbstractMessagingExceptionStrategy.java 22772 2011-08-27 15:20:15Z 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.exception;
12  
13  import org.mule.RequestContext;
14  import org.mule.api.ExceptionPayload;
15  import org.mule.api.MuleContext;
16  import org.mule.api.MuleEvent;
17  import org.mule.api.MuleException;
18  import org.mule.api.construct.FlowConstruct;
19  import org.mule.api.exception.MessagingExceptionHandler;
20  import org.mule.api.exception.RollbackSourceCallback;
21  import org.mule.api.lifecycle.Lifecycle;
22  import org.mule.api.lifecycle.Stoppable;
23  import org.mule.management.stats.FlowConstructStatistics;
24  import org.mule.message.DefaultExceptionPayload;
25  import org.mule.transport.NullPayload;
26  
27  /**
28   * Fire a notification, log exception, increment statistics, route the problematic message to a destination 
29   * if one is configured (DLQ pattern), commit or rollback transaction if one exists, close any open streams.
30   */
31  public abstract class AbstractMessagingExceptionStrategy extends AbstractExceptionStrategy implements MessagingExceptionHandler
32  {
33      /** 
34       * Stop the flow/service when an exception occurs.  You will need to restart the flow/service manually after this (e.g, using JMX). 
35       */
36      private boolean stopMessageProcessing;
37  
38      public AbstractMessagingExceptionStrategy(MuleContext muleContext)
39      {
40          super(muleContext);
41      }
42  
43      public MuleEvent handleException(Exception ex, MuleEvent event, RollbackSourceCallback rollbackMethod)
44      {
45          fireNotification(ex);
46  
47          // Work with the root exception, not anything that wraps it
48          //Throwable t = ExceptionHelper.getRootException(ex);
49  
50          logException(ex);
51          
52          doHandleException(ex, event, rollbackMethod);
53  
54          ExceptionPayload exceptionPayload = new DefaultExceptionPayload(ex);
55          if (RequestContext.getEvent() != null)
56          {
57              RequestContext.setExceptionPayload(exceptionPayload);
58          }
59          event.getMessage().setPayload(NullPayload.getInstance());
60          event.getMessage().setExceptionPayload(exceptionPayload);
61          return event;
62      }
63      
64      public MuleEvent handleException(Exception ex, MuleEvent event)
65      {
66          return handleException(ex, event, null);
67      }
68      
69      protected void doHandleException(Exception ex, MuleEvent event, RollbackSourceCallback rollbackMethod)
70      {
71          FlowConstructStatistics statistics = event.getFlowConstruct().getStatistics();
72          if (statistics != null && statistics.isEnabled())
73          {
74              statistics.incExecutionError();
75          }
76  
77          if (isRollback(ex))
78          {
79              logger.debug("Rolling back transaction");
80              rollback(rollbackMethod);
81  
82              logger.debug("Routing exception message");
83              routeException(event, ex);
84          }
85          else
86          {
87              logger.debug("Routing exception message");
88              routeException(event, ex);
89              
90              logger.debug("Committing transaction");
91              commit();
92          }
93  
94          closeStream(event.getMessage());        
95  
96          if (stopMessageProcessing)
97          {
98              stopFlow(event.getFlowConstruct());
99          }        
100     }
101 
102     protected void stopFlow(FlowConstruct flow)
103     {
104         if (flow instanceof Stoppable)
105         {
106             logger.info("Stopping flow '" + flow.getName() + "' due to exception");
107 
108             try
109             {
110                 ((Lifecycle) flow).stop();
111             }
112             catch (MuleException e)
113             {
114                 logger.error("Unable to stop flow '" + flow.getName() + "'", e);
115             }
116         }
117         else
118         {
119             logger.warn("Flow is not stoppable");
120         }
121     }
122 
123     public boolean isStopMessageProcessing()
124     {
125         return stopMessageProcessing;
126     }
127 
128     public void setStopMessageProcessing(boolean stopMessageProcessing)
129     {
130         this.stopMessageProcessing = stopMessageProcessing;
131     }
132 }