1 10 11 package org.mule.impl; 12 13 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList; 14 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean; 15 import org.apache.commons.logging.Log; 16 import org.apache.commons.logging.LogFactory; 17 import org.mule.config.ExceptionHelper; 18 import org.mule.impl.message.ExceptionMessage; 19 import org.mule.transaction.TransactionCoordination; 20 import org.mule.umo.MessagingException; 21 import org.mule.umo.TransactionException; 22 import org.mule.umo.UMOEvent; 23 import org.mule.umo.UMOEventContext; 24 import org.mule.umo.UMOException; 25 import org.mule.umo.UMOMessage; 26 import org.mule.umo.UMOTransaction; 27 import org.mule.umo.endpoint.UMOEndpoint; 28 import org.mule.umo.endpoint.UMOEndpointURI; 29 import org.mule.umo.endpoint.UMOImmutableEndpoint; 30 import org.mule.umo.lifecycle.Initialisable; 31 import org.mule.umo.lifecycle.InitialisationException; 32 import org.mule.umo.lifecycle.LifecycleException; 33 import org.mule.umo.routing.RoutingException; 34 import org.mule.providers.NullPayload; 35 36 import java.beans.ExceptionListener ; 37 import java.util.Iterator ; 38 import java.util.List ; 39 40 50 public abstract class AbstractExceptionListener implements ExceptionListener , Initialisable 51 { 52 55 protected transient Log logger = LogFactory.getLog(getClass()); 56 57 protected List endpoints = new CopyOnWriteArrayList(); 58 59 protected AtomicBoolean initialised = new AtomicBoolean(false); 60 61 public List getEndpoints() 62 { 63 return endpoints; 64 } 65 66 public void setEndpoints(List endpoints) 67 { 68 for (Iterator iterator = endpoints.iterator(); iterator.hasNext();) 69 { 70 addEndpoint((UMOEndpoint)iterator.next()); 71 } 72 } 73 74 public void addEndpoint(UMOEndpoint endpoint) 75 { 76 if (endpoint != null) 77 { 78 endpoint.setType(UMOEndpoint.ENDPOINT_TYPE_SENDER); 79 endpoints.add(endpoint); 80 } 81 } 82 83 public boolean removeEndpoint(UMOEndpoint endpoint) 84 { 85 return endpoints.remove(endpoint); 86 } 87 88 public void exceptionThrown(Exception e) 89 { 90 Throwable t = getExceptionType(e, RoutingException.class); 91 if (t != null) 92 { 93 RoutingException re = (RoutingException)t; 94 handleRoutingException(re.getUmoMessage(), re.getEndpoint(), e); 95 return; 96 } 97 98 t = getExceptionType(e, MessagingException.class); 99 if (t != null) 100 { 101 MessagingException me = (MessagingException)t; 102 handleMessagingException(me.getUmoMessage(), e); 103 return; 104 } 105 106 t = getExceptionType(e, LifecycleException.class); 107 if (t != null) 108 { 109 LifecycleException le = (LifecycleException)t; 110 handleLifecycleException(le.getComponent(), e); 111 if (RequestContext.getEventContext() != null) 112 { 113 handleMessagingException(RequestContext.getEventContext().getMessage(), e); 114 } 115 else 116 { 117 logger.info("There is no current event available, routing Null message with the exception"); 118 handleMessagingException(new MuleMessage(new NullPayload()), e); 119 } 120 return; 121 } 122 123 handleStandardException(e); 124 } 125 126 protected Throwable getExceptionType(Exception e, Class exceptionType) 127 { 128 Throwable current = e; 129 while (current != null) 130 { 131 if (exceptionType.isAssignableFrom(e.getClass())) 132 { 133 return current; 134 } 135 current = current.getCause(); 136 } 137 return null; 138 } 139 140 148 public synchronized final void initialise() throws InitialisationException 149 { 150 if (!initialised.get()) 151 { 152 doInitialise(); 153 initialised.set(true); 154 } 155 } 156 157 protected void doInitialise() throws InitialisationException 158 { 159 logger.info("Initialising exception listener: " + toString()); 160 for (Iterator iterator = endpoints.iterator(); iterator.hasNext();) 161 { 162 UMOEndpoint umoEndpoint = (UMOEndpoint)iterator.next(); 163 umoEndpoint.initialise(); 164 } 165 } 166 167 172 protected void markTransactionForRollback() 173 { 174 UMOTransaction tx = TransactionCoordination.getInstance().getTransaction(); 175 try 176 { 177 if (tx != null) 178 { 179 tx.setRollbackOnly(); 180 } 181 } 182 catch (TransactionException e) 183 { 184 logException(e); 185 } 186 } 187 188 203 protected void routeException(UMOMessage message, UMOImmutableEndpoint failedEndpoint, Throwable t) 204 { 205 UMOEndpoint endpoint = getEndpoint(t); 206 if (endpoint != null) 207 { 208 try 209 { 210 logger.error("Message being processed is: " + (message == null ? "null" : message.toString())); 211 UMOEventContext ctx = RequestContext.getEventContext(); 212 String component = "Unknown"; 213 UMOEndpointURI endpointUri = null; 214 if (ctx != null) 215 { 216 if (ctx.getComponentDescriptor() != null) 217 { 218 component = ctx.getComponentDescriptor().getName(); 219 } 220 endpointUri = ctx.getEndpointURI(); 221 } 222 else if (failedEndpoint != null) 223 { 224 endpointUri = failedEndpoint.getEndpointURI(); 225 } 226 ExceptionMessage msg; 227 msg = new ExceptionMessage(getErrorMessagePayload(message), t, component, endpointUri); 228 229 UMOMessage exceptionMessage; 230 if (ctx == null) 231 { 232 exceptionMessage = new MuleMessage(msg); 233 } 234 else 235 { 236 exceptionMessage = new MuleMessage(msg, ctx.getMessage()); 237 } 238 UMOEvent exceptionEvent = new MuleEvent(exceptionMessage, endpoint, new MuleSession( 239 exceptionMessage, new MuleSessionHandler()), true); 240 RequestContext.setEvent(exceptionEvent); 241 endpoint.getConnector().getDispatcher(endpoint).send(exceptionEvent); 242 243 if (logger.isDebugEnabled()) 244 { 245 logger.debug("routed Exception message via " + endpoint); 246 } 247 248 } 249 catch (UMOException e) 250 { 251 logFatal(message, e); 252 } 253 } 254 else 255 { 256 markTransactionForRollback(); 257 } 258 } 259 260 protected Object getErrorMessagePayload(UMOMessage message) 261 { 262 try 263 { 264 return message.getPayloadAsString(); 265 } 266 catch (Exception e) 267 { 268 logException(e); 269 logger.info("Failed to read message payload as string, using raw payload"); 270 return message.getPayload(); 271 } 272 } 273 274 284 protected UMOEndpoint getEndpoint(Throwable t) 285 { 286 if (endpoints.size() > 0) 287 { 288 return (UMOEndpoint)endpoints.get(0); 289 } 290 else 291 { 292 return null; 293 } 294 } 295 296 301 protected void logException(Throwable t) 302 { 303 UMOException umoe = ExceptionHelper.getRootMuleException(t); 304 if (umoe != null) 305 { 306 logger.error(umoe.getDetailedMessage()); 307 } 308 else 309 { 310 logger.error("Caught exception in Exception Strategy: " + t.getMessage(), t); 311 } 312 } 313 314 322 protected void logFatal(UMOMessage message, Throwable t) 323 { 324 logger.fatal( 325 "Failed to dispatch message to error queue after it failed to process. This may cause message loss." 326 + (message == null ? "" : "Logging Message here: \n" + message.toString()), t); 327 } 328 329 public boolean isInitialised() 330 { 331 return initialised.get(); 332 } 333 334 344 public abstract void handleMessagingException(UMOMessage message, Throwable e); 345 346 359 public abstract void handleRoutingException(UMOMessage message, UMOImmutableEndpoint endpoint, Throwable e); 360 361 373 public abstract void handleLifecycleException(Object component, Throwable e); 374 375 380 public abstract void handleStandardException(Throwable e); 381 } 382 | Popular Tags |