1
2
3
4
5
6
7 package org.mule;
8
9 import org.mule.api.MuleContext;
10 import org.mule.api.MuleEvent;
11 import org.mule.api.MuleException;
12 import org.mule.api.MuleMessage;
13 import org.mule.api.construct.FlowConstruct;
14 import org.mule.api.construct.FlowConstructAware;
15 import org.mule.api.context.MuleContextAware;
16 import org.mule.api.endpoint.ImmutableEndpoint;
17 import org.mule.api.lifecycle.Disposable;
18 import org.mule.api.lifecycle.Initialisable;
19 import org.mule.api.lifecycle.InitialisationException;
20 import org.mule.api.lifecycle.Lifecycle;
21 import org.mule.api.lifecycle.Stoppable;
22 import org.mule.api.routing.OutboundRouter;
23 import org.mule.exception.AbstractMessagingExceptionStrategy;
24 import org.mule.message.DefaultExceptionPayload;
25 import org.mule.session.DefaultMuleSession;
26 import org.mule.transport.NullPayload;
27 import org.mule.util.ObjectUtils;
28
29 import org.apache.commons.lang.exception.ExceptionUtils;
30
31
32
33
34
35
36
37
38
39 public class RouteableExceptionStrategy extends AbstractMessagingExceptionStrategy implements FlowConstructAware, Lifecycle
40 {
41
42 private OutboundRouter router;
43
44 private boolean stopFurtherProcessing = true;
45
46
47
48
49 @Override
50 public MuleEvent handleException(Exception e, MuleEvent event)
51 {
52 int currentRootExceptionHashCode = 0;
53 int originalRootExceptionHashCode = 0;
54 MuleMessage msg = null;
55
56 StringBuffer logInfo = new StringBuffer();
57
58 try
59 {
60 logInfo.append("****++******Alternate Exception Strategy******++*******\n");
61 logInfo.append("Current Thread = " + Thread.currentThread().toString() + "\n");
62
63 if (event != null && event.getFlowConstruct() != null)
64 {
65 String serviceName = event.getFlowConstruct().getName();
66 logInfo.append("serviceName = " + serviceName + "\n");
67
68 int eventHashCode = event.hashCode();
69 logInfo.append("eventHashCode = " + eventHashCode + "\n");
70 }
71
72 if (event != null && event.isStopFurtherProcessing())
73 {
74 logInfo.append("MuleEvent stop further processing has been set, This is probably the same exception being routed again. no Exception routing will be performed.\n"
75 + e
76 + "\n");
77 event.getMessage().setPayload(NullPayload.getInstance());
78 event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
79 return event;
80 }
81
82 Throwable root = ExceptionUtils.getRootCause(e);
83 currentRootExceptionHashCode = root == null ? -1 : root.hashCode();
84
85 msg = event == null ? null : event.getMessage();
86
87 if (msg != null)
88 {
89 int msgHashCode = msg.hashCode();
90 logInfo.append("msgHashCode = " + msgHashCode + "\n");
91
92 if (msg.getExceptionPayload() != null)
93 {
94 Throwable t = msg.getExceptionPayload().getRootException();
95 if (t != null && t.hashCode() == currentRootExceptionHashCode)
96 {
97 logInfo.append("*#*#*#*#*\n");
98 logInfo.append("This error has already been handeled, returning without doing anything: "
99 + e.getMessage()
100 + "\n");
101 logInfo.append("*#*#*#*#*\n");
102 originalRootExceptionHashCode = currentRootExceptionHashCode;
103 event.getMessage().setPayload(NullPayload.getInstance());
104 event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
105 return event;
106 }
107 }
108
109 originalRootExceptionHashCode = msg.getIntProperty("RootExceptionHashCode", 0);
110
111 logInfo.append("Original RootExceptionHashCode: " + originalRootExceptionHashCode + "\n");
112 logInfo.append("Current RootExceptionHashCode: " + currentRootExceptionHashCode + "\n");
113
114 if (originalRootExceptionHashCode == 0)
115 {
116 msg.setIntProperty("RootExceptionHashCode", currentRootExceptionHashCode);
117 originalRootExceptionHashCode = currentRootExceptionHashCode;
118 }
119 else if (originalRootExceptionHashCode == currentRootExceptionHashCode)
120 {
121 logInfo.append("*#*#*#*#*\n");
122 logInfo.append("This error has already been handeled, returning without doing anything: "
123 + e.getMessage()
124 + "\n");
125 logInfo.append("*#*#*#*#*\n");
126 event.getMessage().setPayload(NullPayload.getInstance());
127 event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
128 return event;
129 }
130 else
131 {
132 msg.setIntProperty("RootExceptionHashCode", currentRootExceptionHashCode);
133 }
134 }
135
136 logInfo.append(e.getMessage());
137
138 StackTraceElement[] st = e.getStackTrace();
139 for (int i = 0; i < st.length; i++)
140 {
141 if (st[i].getClassName().equals("org.mule.AlternateExceptionStrategy"))
142 {
143 logger.warn("*#*#*#*#*\n"
144 + "Recursive error in AlternateExceptionStrategy "
145 + e
146 + "\n"
147 + "*#*#*#*#*");
148 event.getMessage().setPayload(NullPayload.getInstance());
149 event.getMessage().setExceptionPayload(new DefaultExceptionPayload(e));
150 return event;
151 }
152 logger.debug(st[i].toString());
153 }
154 return super.handleException(e, event);
155 }
156 finally
157 {
158 if (event != null && this.stopFurtherProcessing) event.setStopFurtherProcessing(true);
159
160 if (msg != null && currentRootExceptionHashCode != 0
161 && currentRootExceptionHashCode != originalRootExceptionHashCode)
162 msg.setIntProperty("RootExceptionHashCode", currentRootExceptionHashCode);
163
164 logInfo.append("****__******Alternate Exception Strategy******__*******\n");
165 logger.debug(logInfo.toString());
166 }
167 }
168
169
170
171
172 public void handleMessagingException(MuleMessage message, Throwable t)
173 {
174 defaultHandler(message, t);
175 routeException(getMessageFromContext(message), (ImmutableEndpoint) null, t);
176 }
177
178 public void handleRoutingException(MuleMessage message, ImmutableEndpoint endpoint, Throwable t)
179 {
180 defaultHandler(message, t);
181 routeException(getMessageFromContext(message), endpoint, t);
182 }
183
184
185
186
187 public void handleLifecycleException(Object component, Throwable t)
188 {
189 logger.error("The object that failed is: \n" + ObjectUtils.toString(component, "null"));
190 handleStandardException(t);
191 }
192
193
194
195
196 public void handleStandardException(Throwable t)
197 {
198 handleTransaction(t);
199 if (RequestContext.getEvent() != null)
200 {
201 handleMessagingException(RequestContext.getEvent().getMessage(), t);
202 }
203 else
204 {
205 logger.info("There is no current event available, routing Null message with the exception");
206 handleMessagingException(new DefaultMuleMessage(NullPayload.getInstance(), muleContext), t);
207 }
208 }
209
210 protected void defaultHandler(MuleMessage message, Throwable t)
211 {
212 if (RequestContext.getEvent() != null && RequestContext.getEvent().getMessage() != null)
213 {
214 RequestContext.getEvent().getMessage().setExceptionPayload(new DefaultExceptionPayload(t));
215 }
216
217 if (message != null) message.setExceptionPayload(new DefaultExceptionPayload(t));
218 }
219
220 protected MuleMessage getMessageFromContext(MuleMessage message)
221 {
222 if (RequestContext.getEvent() != null)
223 {
224 return RequestContext.getEvent().getMessage();
225 }
226 else if (message != null)
227 {
228 return message;
229 }
230 else
231 {
232 return new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
233 }
234 }
235
236 protected void routeException(MuleMessage msg, ImmutableEndpoint failedEndpoint, Throwable t)
237 {
238 MuleMessage contextMsg = null;
239 MuleEvent exceptionEvent = RequestContext.getEvent();
240 contextMsg = exceptionEvent == null ? msg : exceptionEvent.getMessage();
241
242 if (contextMsg == null)
243 {
244 contextMsg = new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
245 contextMsg.setExceptionPayload(new DefaultExceptionPayload(t));
246 }
247
248 if (exceptionEvent == null)
249 {
250 exceptionEvent = new DefaultMuleEvent(contextMsg, failedEndpoint, new DefaultMuleSession(muleContext));
251 }
252
253
254 DefaultMuleMessage messageCopy = new DefaultMuleMessage(contextMsg.getPayload(), contextMsg, muleContext);
255
256
257 try
258 {
259 router.process(exceptionEvent);
260 }
261 catch (MuleException e)
262 {
263 logFatal(exceptionEvent, e);
264 }
265 }
266
267 public OutboundRouter getRouter()
268 {
269 return router;
270 }
271
272 public void setRouter(OutboundRouter router)
273 {
274 this.router = router;
275 }
276
277 public boolean isStopFurtherProcessing()
278 {
279 return stopFurtherProcessing;
280 }
281
282 public void setStopFurtherProcessing(boolean stopFurtherProcessing)
283 {
284 this.stopFurtherProcessing = stopFurtherProcessing;
285 }
286
287 @Override
288 public void setFlowConstruct(FlowConstruct flowConstruct)
289 {
290 if (router instanceof FlowConstructAware)
291 {
292 router.setFlowConstruct(flowConstruct);
293 }
294 }
295
296 @Override
297 public void setMuleContext(MuleContext context)
298 {
299 super.setMuleContext(context);
300 if (router instanceof MuleContextAware)
301 {
302 router.setMuleContext(context);
303 }
304 }
305
306 @Override
307 protected void doInitialise(MuleContext muleContext) throws InitialisationException
308 {
309 super.doInitialise(muleContext);
310 if (router instanceof Initialisable)
311 {
312 router.initialise();
313 }
314 }
315
316 @Override
317 public void dispose()
318 {
319 super.dispose();
320 if (router instanceof Disposable)
321 {
322 router.dispose();
323 }
324 }
325
326 @Override
327 public void stop() throws MuleException
328 {
329 if (router instanceof Stoppable)
330 {
331 router.stop();
332 }
333 }
334
335 @Override
336 public void start() throws MuleException
337 {
338 if (router instanceof Stoppable)
339 {
340 router.stop();
341 }
342 }
343 }