1
2
3
4
5
6
7
8
9
10
11 package org.mule.impl.model.seda.optimised;
12
13 import org.mule.config.i18n.CoreMessages;
14 import org.mule.impl.ImmutableMuleDescriptor;
15 import org.mule.impl.MuleDescriptor;
16 import org.mule.impl.MuleMessage;
17 import org.mule.impl.RequestContext;
18 import org.mule.impl.model.MuleProxy;
19 import org.mule.management.stats.ComponentStatistics;
20 import org.mule.management.stats.SedaComponentStatistics;
21 import org.mule.umo.MessagingException;
22 import org.mule.umo.UMOEvent;
23 import org.mule.umo.UMOEventContext;
24 import org.mule.umo.UMOException;
25 import org.mule.umo.UMOImmutableDescriptor;
26 import org.mule.umo.UMOMessage;
27 import org.mule.umo.lifecycle.Callable;
28 import org.mule.umo.lifecycle.Disposable;
29 import org.mule.umo.lifecycle.Startable;
30 import org.mule.umo.lifecycle.Stoppable;
31 import org.mule.umo.model.ModelException;
32 import org.mule.util.ObjectPool;
33 import org.mule.util.queue.QueueSession;
34
35 import org.apache.commons.logging.Log;
36 import org.apache.commons.logging.LogFactory;
37
38
39
40
41
42
43 public class OptimisedMuleProxy implements MuleProxy
44 {
45
46
47
48 private static Log logger = LogFactory.getLog(OptimisedMuleProxy.class);
49
50
51
52
53 private UMOEvent event;
54
55
56
57
58 private ImmutableMuleDescriptor descriptor;
59
60
61
62
63 private boolean suspended = true;
64
65 private ObjectPool proxyPool;
66
67 private ComponentStatistics stat = null;
68
69 private Callable umo;
70
71 private boolean started = false;
72 private boolean disposed = false;
73
74
75
76
77
78
79
80
81 public OptimisedMuleProxy(Callable component, MuleDescriptor descriptor, ObjectPool proxyPool)
82 throws UMOException
83 {
84 this.descriptor = new ImmutableMuleDescriptor(descriptor);
85 this.proxyPool = proxyPool;
86 umo = component;
87 }
88
89 public void start() throws UMOException
90 {
91 checkDisposed();
92 if (!started && umo instanceof Startable)
93 {
94 try
95 {
96 ((Startable) umo).start();
97 started = true;
98 }
99 catch (Exception e)
100 {
101 throw new ModelException(
102 CoreMessages.failedToStart("Component '" + descriptor.getName() + "'"), e);
103 }
104 }
105
106 }
107
108 public boolean isStarted()
109 {
110 return started;
111 }
112
113 public void stop() throws UMOException
114 {
115 checkDisposed();
116
117 if (started && umo instanceof Stoppable)
118 {
119 started = false;
120 try
121 {
122 ((Stoppable) umo).stop();
123 }
124 catch (Exception e)
125 {
126 throw new ModelException(
127 CoreMessages.failedToStop("Component '" + descriptor.getName() + "'"), e);
128 }
129 }
130 }
131
132 public void dispose()
133 {
134 checkDisposed();
135 if (umo instanceof Disposable)
136 {
137 ((Disposable) umo).dispose();
138 disposed = true;
139 }
140 }
141
142 private void checkDisposed()
143 {
144 if (disposed)
145 {
146 throw new IllegalStateException("Components Disposed Of");
147 }
148 }
149
150
151
152
153
154
155 public void onEvent(QueueSession session, UMOEvent event)
156 {
157 this.event = event;
158 }
159
160 public ComponentStatistics getStatistics()
161 {
162 return stat;
163 }
164
165 public void setStatistics(ComponentStatistics stat)
166 {
167 this.stat = stat;
168 }
169
170
171
172
173
174
175
176
177 public Object onCall(UMOEvent event) throws UMOException
178 {
179 if (logger.isTraceEnabled())
180 {
181 logger.trace("MuleProxy: sync call for Mule UMO " + descriptor.getName());
182 }
183
184 UMOMessage returnMessage = null;
185 try
186 {
187 if (event.getEndpoint().canReceive())
188 {
189
190
191
192
193
194
195
196
197
198 long startTime = 0;
199 if (stat.isEnabled())
200 {
201 startTime = System.currentTimeMillis();
202 }
203 returnMessage = invokeUmo(RequestContext.getEventContext());
204
205 if (stat.isEnabled())
206 {
207 stat.addExecutionTime(System.currentTimeMillis() - startTime);
208 }
209
210 event = RequestContext.getEvent();
211 if (event.isStopFurtherProcessing())
212 {
213 logger.debug("Event stop further processing has been set, no outbound routing will be performed.");
214 }
215 if (returnMessage != null && !event.isStopFurtherProcessing())
216 {
217
218
219
220
221 if (descriptor.getOutboundRouter().hasEndpoints())
222 {
223 UMOMessage outboundReturnMessage = descriptor.getOutboundRouter().route(
224 returnMessage, event.getSession(), event.isSynchronous());
225 if (outboundReturnMessage != null)
226 {
227 returnMessage = outboundReturnMessage;
228 }
229 }
230 else
231 {
232 logger.debug("Outbound router on component '" + descriptor.getName()
233 + "' doesn't have any endpoints configured.");
234 }
235 }
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255 }
256 else
257 {
258 returnMessage = event.getSession().sendEvent(event);
259
260 }
261
262
263 if (stat.isEnabled())
264 {
265 stat.incSentEventSync();
266 }
267 }
268 catch (Exception e)
269 {
270 event.getSession().setValid(false);
271 if (e instanceof UMOException)
272 {
273 handleException(e);
274 }
275 else
276 {
277 handleException(
278 new MessagingException(
279 CoreMessages.eventProcessingFailedFor(descriptor.getName()),
280 event.getMessage(), e));
281 }
282 }
283 return returnMessage;
284 }
285
286 protected UMOMessage invokeUmo(UMOEventContext context) throws Exception
287 {
288 Object result = umo.onCall(RequestContext.getEventContext());
289 if (result != null)
290 {
291 if (result instanceof UMOMessage)
292 {
293 return (UMOMessage) result;
294 }
295 else
296 {
297 return new MuleMessage(result, context.getMessage());
298 }
299 }
300 return null;
301 }
302
303
304
305
306
307
308
309 public void handleException(Exception exception)
310 {
311 descriptor.getExceptionListener().exceptionThrown(exception);
312 }
313
314 public String toString()
315 {
316 return "optimised proxy for: " + descriptor.toString();
317 }
318
319
320
321
322
323
324 public boolean isSuspended()
325 {
326 return suspended;
327 }
328
329
330
331
332 public void suspend()
333 {
334 suspended = true;
335 }
336
337
338
339
340 public void resume()
341 {
342 suspended = false;
343 }
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372 public void run()
373 {
374 if (logger.isTraceEnabled())
375 {
376 logger.trace("MuleProxy: async onEvent for Mule UMO " + descriptor.getName());
377 }
378
379 try
380 {
381 if (event.getEndpoint().canReceive())
382 {
383
384 event = RequestContext.setEvent(event);
385
386
387
388
389
390
391
392
393
394
395
396 long startTime = 0;
397 if (stat.isEnabled())
398 {
399 startTime = System.currentTimeMillis();
400 }
401 UMOMessage result = invokeUmo(RequestContext.getEventContext());
402 if (stat.isEnabled())
403 {
404 stat.addExecutionTime(System.currentTimeMillis() - startTime);
405 }
406
407 event = RequestContext.getEvent();
408 if (result != null && !event.isStopFurtherProcessing())
409 {
410 descriptor.getOutboundRouter().route(result, event.getSession(), event.isSynchronous());
411 }
412
413
414
415
416
417
418
419
420
421
422 }
423 else
424 {
425 event.getEndpoint().dispatch(event);
426 }
427
428 if (stat.isEnabled())
429 {
430 stat.incSentEventASync();
431 }
432 }
433 catch (Exception e)
434 {
435 event.getSession().setValid(false);
436 if (e instanceof UMOException)
437 {
438 handleException(e);
439 }
440 else
441 {
442 handleException(
443 new MessagingException(
444 CoreMessages.eventProcessingFailedFor(descriptor.getName()),
445 event.getMessage(), e));
446 }
447 }
448 finally
449 {
450
451 try
452 {
453 proxyPool.returnObject(this);
454 }
455 catch (Exception e2)
456 {
457
458 logger.error("Failed to return proxy: " + e2.getMessage(), e2);
459 }
460
461 if (getStatistics() instanceof SedaComponentStatistics)
462 {
463 ((SedaComponentStatistics) getStatistics()).setComponentPoolSize(proxyPool.getSize());
464 }
465 }
466 }
467
468 public void release()
469 {
470
471 }
472
473 public UMOImmutableDescriptor getDescriptor()
474 {
475 return descriptor;
476 }
477 }