1
2
3
4
5
6
7
8
9
10
11 package org.mule.impl.model;
12
13 import org.mule.config.MuleProperties;
14 import org.mule.config.i18n.CoreMessages;
15 import org.mule.impl.ImmutableMuleDescriptor;
16 import org.mule.impl.InterceptorsInvoker;
17 import org.mule.impl.MuleDescriptor;
18 import org.mule.impl.MuleEvent;
19 import org.mule.impl.MuleMessage;
20 import org.mule.impl.OptimizedRequestContext;
21 import org.mule.impl.RequestContext;
22 import org.mule.impl.endpoint.MuleEndpoint;
23 import org.mule.impl.endpoint.MuleEndpointURI;
24 import org.mule.impl.message.ExceptionPayload;
25 import org.mule.management.stats.ComponentStatistics;
26 import org.mule.management.stats.SedaComponentStatistics;
27 import org.mule.providers.AbstractConnector;
28 import org.mule.providers.NullPayload;
29 import org.mule.providers.ReplyToHandler;
30 import org.mule.umo.MessagingException;
31 import org.mule.umo.UMOEvent;
32 import org.mule.umo.UMOException;
33 import org.mule.umo.UMOExceptionPayload;
34 import org.mule.umo.UMOImmutableDescriptor;
35 import org.mule.umo.UMOInterceptor;
36 import org.mule.umo.UMOMessage;
37 import org.mule.umo.endpoint.UMOEndpoint;
38 import org.mule.umo.endpoint.UMOEndpointURI;
39 import org.mule.umo.endpoint.UMOImmutableEndpoint;
40 import org.mule.umo.lifecycle.Disposable;
41 import org.mule.umo.lifecycle.Initialisable;
42 import org.mule.umo.lifecycle.UMOLifecycleAdapter;
43 import org.mule.umo.model.ModelException;
44 import org.mule.umo.model.UMOEntryPointResolver;
45 import org.mule.umo.model.UMOModel;
46 import org.mule.util.ObjectPool;
47 import org.mule.util.queue.QueueSession;
48
49 import java.util.ArrayList;
50 import java.util.Iterator;
51 import java.util.List;
52 import java.util.Map;
53
54 import org.apache.commons.logging.Log;
55 import org.apache.commons.logging.LogFactory;
56
57
58
59
60
61
62 public class DefaultMuleProxy implements MuleProxy
63 {
64
65
66
67 private static Log logger = LogFactory.getLog(DefaultMuleProxy.class);
68
69
70
71
72 private UMOEvent event;
73
74
75
76
77 private UMOLifecycleAdapter umo;
78
79
80
81
82 private ImmutableMuleDescriptor descriptor;
83
84
85
86
87 private boolean suspended = true;
88
89 private List interceptorList;
90
91 private ObjectPool proxyPool;
92
93 private ComponentStatistics stat = null;
94
95 private QueueSession queueSession = null;
96
97
98
99
100
101
102
103
104 public DefaultMuleProxy(Object component, MuleDescriptor descriptor, UMOModel model, ObjectPool proxyPool)
105 throws UMOException
106 {
107 this.descriptor = new ImmutableMuleDescriptor(descriptor);
108 this.proxyPool = proxyPool;
109
110 UMOEntryPointResolver resolver = model.getEntryPointResolver();
111 umo = model.getLifecycleAdapterFactory().create(component, descriptor, resolver);
112
113 interceptorList = new ArrayList(descriptor.getInterceptors().size() + 1);
114 interceptorList.addAll(descriptor.getInterceptors());
115 interceptorList.add(umo);
116
117 for (Iterator iter = interceptorList.iterator(); iter.hasNext();)
118 {
119 UMOInterceptor interceptor = (UMOInterceptor) iter.next();
120 if (interceptor instanceof Initialisable)
121 {
122 try
123 {
124 ((Initialisable) interceptor).initialise();
125 }
126 catch (Exception e)
127 {
128 throw new ModelException(
129 CoreMessages.objectFailedToInitialise(
130 "Component '" + descriptor.getName() + "'"), e);
131 }
132 }
133 }
134 }
135
136 public void start() throws UMOException
137 {
138 checkDisposed();
139 if (!umo.isStarted())
140 {
141 try
142 {
143 umo.start();
144 }
145 catch (Exception e)
146 {
147 throw new ModelException(
148 CoreMessages.failedToStart("Component '" + descriptor.getName() + "'"), e);
149 }
150 }
151
152 }
153
154 public boolean isStarted()
155 {
156 return umo.isStarted();
157 }
158
159 public void stop() throws UMOException
160 {
161 checkDisposed();
162 if (umo.isStarted())
163 {
164 try
165 {
166 umo.stop();
167 }
168 catch (Exception e)
169 {
170 throw new ModelException(
171 CoreMessages.failedToStop("Component '" + descriptor.getName() + "'"), e);
172 }
173 }
174 }
175
176 public void dispose()
177 {
178 checkDisposed();
179 for (Iterator iter = interceptorList.iterator(); iter.hasNext();)
180 {
181 UMOInterceptor interceptor = (UMOInterceptor) iter.next();
182 if (interceptor instanceof Disposable)
183 {
184 try
185 {
186 ((Disposable) interceptor).dispose();
187 }
188 catch (Exception e)
189 {
190
191 logger.error(
192 CoreMessages.failedToDispose("Component '" + descriptor.getName() + "'"), e);
193 }
194 }
195 }
196 }
197
198 private void checkDisposed()
199 {
200 if (umo.isDisposed())
201 {
202 throw new IllegalStateException("Component has already been disposed of");
203 }
204 }
205
206
207
208
209
210
211 public void onEvent(QueueSession session, UMOEvent event)
212 {
213 this.queueSession = session;
214 this.event = event;
215 }
216
217 public ComponentStatistics getStatistics()
218 {
219 return stat;
220 }
221
222 public void setStatistics(ComponentStatistics stat)
223 {
224 this.stat = stat;
225 }
226
227
228
229
230
231
232
233
234 public Object onCall(UMOEvent event) throws UMOException
235 {
236 if (logger.isTraceEnabled())
237 {
238 logger.trace("MuleProxy: sync call for Mule UMO " + descriptor.getName());
239 }
240
241 UMOMessage returnMessage = null;
242 try
243 {
244 if (event.getEndpoint().canReceive())
245 {
246 event = OptimizedRequestContext.unsafeSetEvent(event);
247 Object replyTo = event.getMessage().getReplyTo();
248 ReplyToHandler replyToHandler = getReplyToHandler(event.getMessage(), event.getEndpoint());
249 InterceptorsInvoker invoker = new InterceptorsInvoker(interceptorList, descriptor,
250 event.getMessage());
251
252
253 long startTime = 0;
254 if (stat.isEnabled())
255 {
256 startTime = System.currentTimeMillis();
257 }
258 returnMessage = invoker.execute();
259
260
261 if (stat.isEnabled())
262 {
263 stat.addExecutionTime(System.currentTimeMillis() - startTime);
264 }
265
266 event = RequestContext.getEvent();
267 if (event.isStopFurtherProcessing())
268 {
269 logger.debug("Event stop further processing has been set, no outbound routing will be performed.");
270 }
271 if (returnMessage != null && !event.isStopFurtherProcessing())
272 {
273 if (descriptor.getOutboundRouter().hasEndpoints())
274 {
275 UMOMessage outboundReturnMessage = descriptor.getOutboundRouter().route(
276 returnMessage, event.getSession(), event.isSynchronous());
277 if (outboundReturnMessage != null)
278 {
279 returnMessage = outboundReturnMessage;
280 }
281 }
282 else
283 {
284 logger.debug("Outbound router on component '" + descriptor.getName()
285 + "' doesn't have any endpoints configured.");
286 }
287 }
288
289
290 if (returnMessage != null && descriptor.getResponseRouter() != null)
291 {
292 logger.debug("Waiting for response router message");
293 returnMessage = descriptor.getResponseRouter().getResponse(returnMessage);
294 }
295
296
297 if (returnMessage != null && replyToHandler != null)
298 {
299 String requestor = (String) returnMessage.getProperty(MuleProperties.MULE_REPLY_TO_REQUESTOR_PROPERTY);
300 if ((requestor != null && !requestor.equals(descriptor.getName())) || requestor == null)
301 {
302 replyToHandler.processReplyTo(event, returnMessage, replyTo);
303 }
304 }
305
306 }
307 else
308 {
309 returnMessage = event.getSession().sendEvent(event);
310 processReplyTo(returnMessage);
311 }
312
313
314 if (stat.isEnabled())
315 {
316 stat.incSentEventSync();
317 }
318 }
319 catch (Exception e)
320 {
321 event.getSession().setValid(false);
322 if (e instanceof MessagingException)
323 {
324 handleException(e);
325 }
326 else
327 {
328 handleException(
329 new MessagingException(
330 CoreMessages.eventProcessingFailedFor(descriptor.getName()),
331 event.getMessage(), e));
332 }
333
334 if (returnMessage == null)
335 {
336 returnMessage = new MuleMessage(NullPayload.getInstance(), (Map) null);
337 }
338 UMOExceptionPayload exceptionPayload = RequestContext.getExceptionPayload();
339 if (exceptionPayload == null)
340 {
341 exceptionPayload = new ExceptionPayload(e);
342 }
343 returnMessage.setExceptionPayload(exceptionPayload);
344 }
345 return returnMessage;
346 }
347
348
349
350
351
352
353
354 public void handleException(Exception exception)
355 {
356 descriptor.getExceptionListener().exceptionThrown(exception);
357 }
358
359 public String toString()
360 {
361 return "proxy for: " + descriptor.toString();
362 }
363
364
365
366
367
368
369 public boolean isSuspended()
370 {
371 return suspended;
372 }
373
374
375
376
377 public void suspend()
378 {
379 suspended = true;
380 }
381
382
383
384
385 public void resume()
386 {
387 suspended = false;
388 }
389
390 protected ReplyToHandler getReplyToHandler(UMOMessage message, UMOImmutableEndpoint endpoint)
391 {
392 Object replyTo = message.getReplyTo();
393 ReplyToHandler replyToHandler = null;
394 if (replyTo != null)
395 {
396 replyToHandler = ((AbstractConnector) endpoint.getConnector()).getReplyToHandler();
397
398 if (endpoint.getResponseTransformer() != null)
399 {
400 replyToHandler.setTransformer(endpoint.getResponseTransformer());
401 }
402 }
403 return replyToHandler;
404 }
405
406 private void processReplyTo(UMOMessage returnMessage) throws UMOException
407 {
408 if (returnMessage != null && returnMessage.getReplyTo() != null)
409 {
410 if (logger.isDebugEnabled())
411 {
412 logger.debug("sending reply to: " + returnMessage.getReplyTo());
413 }
414
415 UMOEndpointURI endpointUri = new MuleEndpointURI(returnMessage.getReplyTo().toString());
416
417
418 UMOEndpoint endpoint = MuleEndpoint.getOrCreateEndpointForUri(endpointUri,
419 UMOEndpoint.ENDPOINT_TYPE_SENDER);
420
421
422
423 returnMessage.removeProperty(MuleProperties.MULE_REPLY_TO_PROPERTY);
424
425
426 UMOEvent replyToEvent = new MuleEvent(returnMessage, endpoint, event.getSession(), false);
427
428
429 onEvent(queueSession, replyToEvent);
430
431 if (logger.isDebugEnabled())
432 {
433 logger.debug("reply to sent: " + returnMessage.getReplyTo());
434 }
435
436 if (stat.isEnabled())
437 {
438 stat.incSentReplyToEvent();
439 }
440 }
441 }
442
443 public void run()
444 {
445 if (logger.isTraceEnabled())
446 {
447 logger.trace("MuleProxy: async onEvent for Mule UMO " + descriptor.getName());
448 }
449
450 try
451 {
452 if (event.getEndpoint().canReceive())
453 {
454
455 event = OptimizedRequestContext.criticalSetEvent(event);
456 Object replyTo = event.getMessage().getReplyTo();
457 ReplyToHandler replyToHandler = getReplyToHandler(event.getMessage(), event.getEndpoint());
458 InterceptorsInvoker invoker =
459 new InterceptorsInvoker(interceptorList, descriptor, event.getMessage());
460
461
462 long startTime = 0;
463 if (stat.isEnabled())
464 {
465 startTime = System.currentTimeMillis();
466 }
467 UMOMessage result = invoker.execute();
468 if (stat.isEnabled())
469 {
470 stat.addExecutionTime(System.currentTimeMillis() - startTime);
471 }
472
473 event = RequestContext.getEvent();
474 if (result != null && !event.isStopFurtherProcessing())
475 {
476 descriptor.getOutboundRouter().route(result, event.getSession(), event.isSynchronous());
477 }
478
479
480 if (result != null && replyToHandler != null)
481 {
482 String requestor = (String) result.getProperty(MuleProperties.MULE_REPLY_TO_REQUESTOR_PROPERTY);
483 if ((requestor != null && !requestor.equals(descriptor.getName())) || requestor == null)
484 {
485 replyToHandler.processReplyTo(event, result, replyTo);
486 }
487 }
488 }
489 else
490 {
491 event.getEndpoint().dispatch(event);
492 }
493
494 if (stat.isEnabled())
495 {
496 stat.incSentEventASync();
497 }
498 }
499 catch (Exception e)
500 {
501 event.getSession().setValid(false);
502 if (e instanceof MessagingException)
503 {
504 handleException(e);
505 }
506 else
507 {
508 handleException(
509 new MessagingException(
510 CoreMessages.eventProcessingFailedFor(descriptor.getName()),
511 event.getMessage(), e));
512 }
513 }
514 finally
515 {
516 try
517 {
518 proxyPool.returnObject(this);
519 }
520 catch (Exception e2)
521 {
522
523 logger.error("Failed to return proxy: " + e2.getMessage(), e2);
524 }
525
526 if (getStatistics() instanceof SedaComponentStatistics)
527 {
528 ((SedaComponentStatistics) getStatistics()).setComponentPoolSize(proxyPool.getSize());
529 }
530 }
531 }
532
533 public void release()
534 {
535
536 }
537
538 public UMOImmutableDescriptor getDescriptor()
539 {
540 return descriptor;
541 }
542 }