1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.spring.events;
12
13 import org.mule.DefaultMuleEvent;
14 import org.mule.DefaultMuleMessage;
15 import org.mule.MessageExchangePattern;
16 import org.mule.RequestContext;
17 import org.mule.api.MuleContext;
18 import org.mule.api.MuleEventContext;
19 import org.mule.api.MuleException;
20 import org.mule.api.MuleRuntimeException;
21 import org.mule.api.MuleSession;
22 import org.mule.api.config.MuleProperties;
23 import org.mule.api.config.ThreadingProfile;
24 import org.mule.api.context.MuleContextAware;
25 import org.mule.api.endpoint.EndpointBuilder;
26 import org.mule.api.endpoint.EndpointFactory;
27 import org.mule.api.endpoint.EndpointURI;
28 import org.mule.api.endpoint.InboundEndpoint;
29 import org.mule.api.endpoint.MalformedEndpointException;
30 import org.mule.api.endpoint.OutboundEndpoint;
31 import org.mule.api.lifecycle.Callable;
32 import org.mule.api.lifecycle.Initialisable;
33 import org.mule.api.lifecycle.InitialisationException;
34 import org.mule.api.model.Model;
35 import org.mule.api.routing.filter.ObjectFilter;
36 import org.mule.api.service.Service;
37 import org.mule.api.source.CompositeMessageSource;
38 import org.mule.api.transformer.Transformer;
39 import org.mule.api.transformer.TransformerException;
40 import org.mule.api.transport.Connector;
41 import org.mule.component.DefaultJavaComponent;
42 import org.mule.config.QueueProfile;
43 import org.mule.endpoint.MuleEndpointURI;
44 import org.mule.model.seda.SedaModel;
45 import org.mule.model.seda.SedaService;
46 import org.mule.module.spring.i18n.SpringMessages;
47 import org.mule.object.SingletonObjectFactory;
48 import org.mule.routing.filters.WildcardFilter;
49 import org.mule.service.ServiceCompositeMessageSource;
50 import org.mule.session.DefaultMuleSession;
51 import org.mule.util.ClassUtils;
52
53 import java.beans.ExceptionListener;
54 import java.util.ArrayList;
55 import java.util.Iterator;
56 import java.util.List;
57 import java.util.Map;
58 import java.util.Set;
59 import java.util.concurrent.CopyOnWriteArraySet;
60 import java.util.concurrent.ExecutorService;
61
62 import org.apache.commons.logging.Log;
63 import org.apache.commons.logging.LogFactory;
64 import org.springframework.beans.BeansException;
65 import org.springframework.context.ApplicationContext;
66 import org.springframework.context.ApplicationContextAware;
67 import org.springframework.context.ApplicationEvent;
68 import org.springframework.context.ApplicationListener;
69 import org.springframework.context.event.ApplicationEventMulticaster;
70 import org.springframework.context.event.ContextClosedEvent;
71 import org.springframework.context.event.ContextRefreshedEvent;
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120 public class MuleEventMulticaster
121 implements ApplicationEventMulticaster, ApplicationContextAware, MuleContextAware, Callable, Initialisable
122 {
123 public static final String EVENT_MULTICASTER_DESCRIPTOR_NAME = "muleEventMulticasterDescriptor";
124
125
126
127
128 protected static final Log logger = LogFactory.getLog(MuleEventMulticaster.class);
129
130
131
132
133 protected final Set listeners = new CopyOnWriteArraySet();
134
135
136
137
138 protected boolean asynchronous = false;
139
140
141
142
143 protected ExecutorService asyncPool = null;
144
145
146
147
148
149
150
151
152 protected String[] subscriptions = null;
153
154
155
156
157 protected ApplicationContext applicationContext;
158
159
160
161
162 protected Service service;
163
164
165
166
167 protected Class subscriptionFilter = WildcardFilter.class;
168
169
170
171
172 protected ExceptionListener exceptionListener = new LoggingExceptionListener();
173
174 protected MuleContext muleContext;
175
176 public void setMuleContext(MuleContext context)
177 {
178 this.muleContext = context;
179 }
180
181 public void initialise() throws InitialisationException
182 {
183 if (asynchronous)
184 {
185 if (asyncPool == null)
186 {
187 asyncPool = muleContext.getDefaultThreadingProfile().createPool("spring-events");
188 }
189 }
190 else
191 {
192 if (asyncPool != null)
193 {
194 asyncPool.shutdown();
195 asyncPool = null;
196 }
197 }
198 }
199
200
201
202
203
204
205
206
207
208
209
210
211 public void addApplicationListener(ApplicationListener listener)
212 {
213 Object listenerToAdd = listener;
214
215 if (asynchronous)
216 {
217 listenerToAdd = new AsynchronousEventListener(asyncPool, listener);
218 }
219
220 listeners.add(listenerToAdd);
221 }
222
223
224
225
226
227
228 public void removeApplicationListener(ApplicationListener listener)
229 {
230 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
231 {
232 ApplicationListener applicationListener = (ApplicationListener) iterator.next();
233 if (applicationListener instanceof AsynchronousEventListener)
234 {
235 if (((AsynchronousEventListener) applicationListener).getListener().equals(listener))
236 {
237 listeners.remove(applicationListener);
238 return;
239 }
240 }
241 else
242 {
243 if (applicationListener.equals(listener))
244 {
245 listeners.remove(applicationListener);
246 return;
247 }
248 }
249 }
250 listeners.remove(listener);
251 }
252
253
254 public void addApplicationListenerBean(String s)
255 {
256 Object listener = applicationContext.getBean(s);
257 if(listener instanceof ApplicationListener)
258 {
259 addApplicationListener((ApplicationListener)listener);
260 }
261 else
262 {
263 throw new IllegalArgumentException(SpringMessages.beanNotInstanceOfApplicationListener(s).getMessage());
264 }
265 }
266
267 public void removeApplicationListenerBean(String s)
268 {
269 Object listener = applicationContext.getBean(s);
270 if(listener instanceof ApplicationListener)
271 {
272 removeApplicationListener((ApplicationListener)listener);
273 }
274 else
275 {
276 throw new IllegalArgumentException(SpringMessages.beanNotInstanceOfApplicationListener(s).getMessage());
277 }
278 }
279
280
281
282
283 public void removeAllListeners()
284 {
285 listeners.clear();
286 }
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301 public void multicastEvent(ApplicationEvent e)
302 {
303 MuleApplicationEvent muleEvent = null;
304
305 if (e instanceof ContextRefreshedEvent)
306 {
307 try
308 {
309 registerMulticasterComponent();
310 }
311 catch (MuleException ex)
312 {
313 throw new MuleRuntimeException(SpringMessages.failedToReinitMule(), ex);
314 }
315 }
316 else if (e instanceof ContextClosedEvent)
317 {
318 if (!muleContext.isDisposing() && !muleContext.isDisposed())
319 {
320 muleContext.dispose();
321 }
322 return;
323 }
324 else if (e instanceof MuleApplicationEvent)
325 {
326 muleEvent = (MuleApplicationEvent) e;
327
328
329 if (muleEvent.getMuleEventContext() == null)
330 {
331 try
332 {
333 dispatchEvent(muleEvent);
334 }
335 catch (ApplicationEventException e1)
336 {
337 exceptionListener.exceptionThrown(e1);
338 }
339 return;
340 }
341 }
342
343 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
344 {
345 ApplicationListener listener = (ApplicationListener) iterator.next();
346 if (muleEvent != null)
347 {
348
349
350
351 if (listener instanceof AsynchronousEventListener)
352 {
353 AsynchronousEventListener asyncListener = (AsynchronousEventListener) listener;
354 if (asyncListener.getListener() instanceof MuleSubscriptionEventListener)
355 {
356 if (isSubscriptionMatch(muleEvent.getEndpoint(),
357 ((MuleSubscriptionEventListener) asyncListener.getListener()).getSubscriptions()))
358 {
359 asyncListener.onApplicationEvent(muleEvent);
360 }
361 }
362 else if (asyncListener.getListener() instanceof MuleEventListener)
363 {
364 asyncListener.onApplicationEvent(muleEvent);
365 }
366 else if (!(asyncListener.getListener() instanceof MuleEventListener))
367 {
368 asyncListener.onApplicationEvent(e);
369 }
370
371 }
372 else if (listener instanceof MuleSubscriptionEventListener)
373 {
374 if (isSubscriptionMatch(muleEvent.getEndpoint(),
375 ((MuleSubscriptionEventListener) listener).getSubscriptions()))
376 {
377 listener.onApplicationEvent(muleEvent);
378 }
379 }
380 else if (listener instanceof MuleEventListener)
381 {
382 listener.onApplicationEvent(muleEvent);
383 }
384 }
385 else if (listener instanceof AsynchronousEventListener
386 && !(((AsynchronousEventListener) listener).getListener() instanceof MuleEventListener))
387 {
388 listener.onApplicationEvent(e);
389 }
390 else if (!(listener instanceof MuleEventListener))
391 {
392 listener.onApplicationEvent(e);
393 }
394 else
395 {
396
397
398 for (int i = 0; i < listener.getClass().getInterfaces().length; i++)
399 {
400 if (listener.getClass().getInterfaces()[i].equals(ApplicationListener.class))
401 {
402 listener.onApplicationEvent(e);
403 break;
404 }
405 }
406
407 }
408 }
409 }
410
411
412
413
414
415
416
417
418 private boolean isSubscriptionMatch(String endpoint, String[] subscriptions)
419 {
420 for (int i = 0; i < subscriptions.length; i++)
421 {
422 String subscription = subscriptions[i];
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441 ObjectFilter filter = createFilter(subscription);
442 if (filter.accept(endpoint))
443 {
444 return true;
445 }
446 }
447 return false;
448 }
449
450
451
452
453
454
455 public boolean isAsynchronous()
456 {
457 return asynchronous;
458 }
459
460
461
462
463
464
465 public void setAsynchronous(boolean asynchronous)
466 {
467 this.asynchronous = asynchronous;
468 }
469
470
471
472
473
474
475
476 public Object onCall(MuleEventContext context) throws TransformerException, MalformedEndpointException
477 {
478 multicastEvent(new MuleApplicationEvent(context.getMessage().getPayload(), context, applicationContext));
479 context.setStopFurtherProcessing(true);
480 return null;
481 }
482
483
484
485
486
487
488
489
490 protected void dispatchEvent(MuleApplicationEvent applicationEvent) throws ApplicationEventException
491 {
492 OutboundEndpoint endpoint;
493 try
494 {
495 endpoint = muleContext.getEndpointFactory().getOutboundEndpoint(
496 applicationEvent.getEndpoint());
497 }
498 catch (MuleException e)
499 {
500 throw new ApplicationEventException("Failed to get endpoint for endpointUri: "
501 + applicationEvent.getEndpoint(), e);
502 }
503 if (endpoint != null)
504 {
505 try
506 {
507
508
509
510
511 DefaultMuleMessage message = new DefaultMuleMessage(applicationEvent.getSource(),
512 applicationEvent.getProperties(), muleContext);
513
514
515 if (applicationEvent.getMuleEventContext() != null)
516 {
517
518 applicationEvent.getMuleEventContext().setStopFurtherProcessing(true);
519 applicationEvent.getMuleEventContext().dispatchEvent(message, endpoint);
520 }
521 else
522 {
523 MuleSession session = new DefaultMuleSession(service, muleContext);
524 DefaultMuleEvent event = new DefaultMuleEvent(message, endpoint.getExchangePattern(),
525 session);
526 RequestContext.setEvent(event);
527
528 if (endpoint.getTransformers() != null)
529 {
530 message = new DefaultMuleMessage(applicationEvent.getSource(),
531 applicationEvent.getProperties(), muleContext);
532 message.applyTransformers(event, endpoint.getTransformers());
533 }
534 endpoint.process(new DefaultMuleEvent(message, endpoint.getExchangePattern(), session));
535 }
536 }
537 catch (Exception e1)
538 {
539 throw new ApplicationEventException("Failed to dispatch event: " + e1.getMessage(), e1);
540 }
541 }
542 else
543 {
544 throw new ApplicationEventException("Failed endpoint using name: "
545 + applicationEvent.getEndpoint());
546 }
547 }
548
549
550
551
552
553
554
555 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
556 {
557 this.applicationContext = applicationContext;
558 }
559
560 protected void registerMulticasterComponent() throws MuleException
561 {
562
563 if (service == null)
564 {
565 service = getDefaultService();
566 setSubscriptionsOnService(service);
567 muleContext.getRegistry().registerService(service);
568 }
569 }
570
571 protected void setSubscriptionsOnService(Service service) throws MuleException
572 {
573 String[] subscriptions;
574 List endpoints = new ArrayList();
575 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
576 {
577 ApplicationListener listener = (ApplicationListener) iterator.next();
578 if (listener instanceof AsynchronousEventListener)
579 {
580 listener = ((AsynchronousEventListener) listener).getListener();
581 }
582 if (listener instanceof MuleSubscriptionEventListener)
583 {
584 subscriptions = ((MuleSubscriptionEventListener) listener).getSubscriptions();
585 for (int i = 0; i < subscriptions.length; i++)
586 {
587 if (subscriptions[i].indexOf("*") == -1 && MuleEndpointURI.isMuleUri(subscriptions[i]))
588 {
589 boolean isSoap = registerAsSoap(subscriptions[i], listener);
590
591 if (!isSoap)
592 {
593 endpoints.add(subscriptions[i]);
594 }
595 }
596 }
597 }
598 }
599 if (endpoints.size() > 0)
600 {
601 String endpoint;
602 for (Iterator iterator = endpoints.iterator(); iterator.hasNext();)
603 {
604 endpoint = (String) iterator.next();
605
606 InboundEndpoint ep = muleContext.getEndpointFactory().getInboundEndpoint(
607 endpoint);
608
609
610
611 if (((ServiceCompositeMessageSource) service.getMessageSource()).getEndpoint(ep.getName()) == null)
612 {
613 ((ServiceCompositeMessageSource) service.getMessageSource()).addSource(ep);
614 }
615 }
616 }
617 }
618
619 private boolean registerAsSoap(String endpoint, Object listener) throws MuleException
620 {
621 if (endpoint.startsWith("soap") || endpoint.startsWith("axis") || endpoint.startsWith("cxf"))
622 {
623 EndpointURI ep = new MuleEndpointURI(endpoint, muleContext);
624
625
626 String serviceName = null;
627 if (ep.getPath() != null)
628 {
629 String path = ep.getPath();
630 if (path.endsWith("/"))
631 {
632 path = path.substring(0, path.length() - 1);
633 }
634 int i = path.lastIndexOf("/");
635 if (i > -1)
636 {
637 serviceName = path.substring(i + 1);
638 }
639 }
640 else
641 {
642 serviceName = service.getName();
643 }
644
645 String newEndpoint = endpoint;
646 int i = newEndpoint.indexOf(serviceName);
647 newEndpoint = newEndpoint.substring(0, i - 1);
648 SedaService s = new SedaService(muleContext);
649 s.setName(serviceName);
650 s.setModel(muleContext.getRegistry().lookupSystemModel());
651
652 QueueProfile queueProfile = QueueProfile.newInstancePersistingToDefaultMemoryQueueStore(muleContext);
653 s.setQueueProfile(queueProfile);
654
655 ((CompositeMessageSource) s.getMessageSource()).addSource(
656 muleContext.getEndpointFactory().getInboundEndpoint(newEndpoint));
657 final DefaultJavaComponent component = new DefaultJavaComponent(new SingletonObjectFactory(listener));
658 component.setMuleContext(muleContext);
659 s.setComponent(component);
660 muleContext.getRegistry().registerService(s);
661 return true;
662 }
663 else
664 {
665 return false;
666 }
667 }
668
669 protected void registerConnectors() throws MuleException
670 {
671 if (!muleContext.isInitialised())
672 {
673
674 Map connectors = applicationContext.getBeansOfType(Connector.class, true, true);
675 if (connectors.size() > 0)
676 {
677 Map.Entry entry;
678 Connector c;
679 for (Iterator iterator = connectors.entrySet().iterator(); iterator.hasNext();)
680 {
681 entry = (Map.Entry) iterator.next();
682 c = (Connector) entry.getValue();
683 if (c.getName() == null)
684 {
685 c.setName(entry.getKey().toString());
686 }
687 muleContext.getRegistry().registerConnector(c);
688 }
689 }
690 }
691 }
692
693 protected void registerTransformers() throws MuleException
694 {
695 if (!muleContext.isInitialised())
696 {
697
698 Map transformers = applicationContext.getBeansOfType(Transformer.class, true, true);
699 if (transformers.size() > 0)
700 {
701 Map.Entry entry;
702 Transformer t;
703 for (Iterator iterator = transformers.entrySet().iterator(); iterator.hasNext();)
704 {
705 entry = (Map.Entry) iterator.next();
706 t = (Transformer) entry.getValue();
707 if (t.getName() == null)
708 {
709 t.setName(entry.getKey().toString());
710 }
711 muleContext.getRegistry().registerTransformer(t);
712 }
713 }
714 }
715 }
716
717 protected Service getDefaultService() throws MuleException
718 {
719
720
721 Model model = muleContext.getRegistry().lookupModel(MuleProperties.OBJECT_SYSTEM_MODEL);
722 if (model == null)
723 {
724 model = new SedaModel();
725 model.setName(MuleProperties.OBJECT_SYSTEM_MODEL);
726 muleContext.getRegistry().registerModel(model);
727 }
728 Service service = muleContext.getRegistry().lookupService(EVENT_MULTICASTER_DESCRIPTOR_NAME);
729 if (service != null)
730 {
731 muleContext.getRegistry().unregisterService(service.getName());
732 }
733 service = new SedaService(muleContext);
734 service.setName(EVENT_MULTICASTER_DESCRIPTOR_NAME);
735 service.setModel(model);
736 if (subscriptions == null)
737 {
738 logger.info("No receive endpoints have been set, using default '*'");
739 ((CompositeMessageSource) service.getMessageSource()).addSource(
740 muleContext.getEndpointFactory().getInboundEndpoint("vm://*"));
741 }
742 else
743 {
744
745 ServiceCompositeMessageSource messageRouter = (ServiceCompositeMessageSource) service.getMessageSource();
746
747 for (int i = 0; i < subscriptions.length; i++)
748 {
749 String subscription = subscriptions[i];
750
751 EndpointFactory endpointFactory = muleContext.getEndpointFactory();
752 EndpointBuilder endpointBuilder = endpointFactory.getEndpointBuilder(subscription);
753 endpointBuilder.setExchangePattern(MessageExchangePattern.fromSyncFlag(!asynchronous));
754 InboundEndpoint endpoint = endpointFactory.getInboundEndpoint(endpointBuilder);
755
756 messageRouter.addSource(endpoint);
757 }
758 }
759 DefaultJavaComponent component = new DefaultJavaComponent(new SingletonObjectFactory(this));
760 component.setMuleContext(muleContext);
761 service.setComponent(component);
762 return service;
763 }
764
765 protected ObjectFilter createFilter(String pattern)
766 {
767 try
768 {
769 if (getSubscriptionFilter() == null)
770 {
771 setSubscriptionFilter(WildcardFilter.class);
772 }
773 return (ObjectFilter) ClassUtils.instanciateClass(getSubscriptionFilter(), pattern);
774 }
775 catch (Exception e)
776 {
777 exceptionListener.exceptionThrown(e);
778 return new WildcardFilter(pattern);
779 }
780 }
781
782
783
784
785
786
787
788 public Class getSubscriptionFilter()
789 {
790 return subscriptionFilter;
791 }
792
793
794
795
796
797
798 public void setSubscriptionFilter(Class subscriptionFilter)
799 {
800 this.subscriptionFilter = subscriptionFilter;
801 }
802
803
804
805
806
807
808
809
810
811
812 public String[] getSubscriptions()
813 {
814 return subscriptions;
815 }
816
817
818
819
820
821
822
823
824
825
826 public void setSubscriptions(String[] subscriptions)
827 {
828 this.subscriptions = subscriptions;
829 }
830
831 protected void setExceptionListener(ExceptionListener listener)
832 {
833 if (listener != null)
834 {
835 this.exceptionListener = listener;
836 }
837 else
838 {
839 throw new IllegalArgumentException("exceptionListener may not be null");
840 }
841 }
842
843 private static class LoggingExceptionListener implements ExceptionListener
844 {
845 public LoggingExceptionListener()
846 {
847 super();
848 }
849
850 public void exceptionThrown(Exception e)
851 {
852 logger.error(e.getMessage(), e);
853 }
854 }
855 }