1
2
3
4
5
6
7
8
9
10
11 package org.mule.extras.spring.events;
12
13 import org.mule.MuleManager;
14 import org.mule.MuleRuntimeException;
15 import org.mule.config.MuleConfiguration;
16 import org.mule.config.ThreadingProfile;
17 import org.mule.config.builders.QuickConfigurationBuilder;
18 import org.mule.extras.spring.SpringContainerContext;
19 import org.mule.extras.spring.i18n.SpringMessages;
20 import org.mule.impl.MuleDescriptor;
21 import org.mule.impl.MuleEvent;
22 import org.mule.impl.MuleMessage;
23 import org.mule.impl.MuleSession;
24 import org.mule.impl.RequestContext;
25 import org.mule.impl.endpoint.MuleEndpoint;
26 import org.mule.impl.endpoint.MuleEndpointURI;
27 import org.mule.impl.model.ModelHelper;
28 import org.mule.impl.model.seda.SedaModel;
29 import org.mule.providers.AbstractConnector;
30 import org.mule.routing.filters.ObjectFilter;
31 import org.mule.routing.filters.WildcardFilter;
32 import org.mule.umo.UMOComponent;
33 import org.mule.umo.UMODescriptor;
34 import org.mule.umo.UMOEventContext;
35 import org.mule.umo.UMOException;
36 import org.mule.umo.UMOSession;
37 import org.mule.umo.endpoint.MalformedEndpointException;
38 import org.mule.umo.endpoint.UMOEndpoint;
39 import org.mule.umo.endpoint.UMOEndpointURI;
40 import org.mule.umo.lifecycle.InitialisationException;
41 import org.mule.umo.manager.UMOManager;
42 import org.mule.umo.model.UMOModel;
43 import org.mule.umo.provider.UMOConnector;
44 import org.mule.umo.routing.UMOInboundRouterCollection;
45 import org.mule.umo.transformer.TransformerException;
46 import org.mule.umo.transformer.UMOTransformer;
47 import org.mule.util.ClassUtils;
48 import org.mule.util.MapUtils;
49
50 import java.beans.ExceptionListener;
51 import java.util.ArrayList;
52 import java.util.Iterator;
53 import java.util.List;
54 import java.util.Map;
55 import java.util.Set;
56
57 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArraySet;
58 import edu.emory.mathcs.backport.java.util.concurrent.ExecutorService;
59 import org.apache.commons.logging.Log;
60 import org.apache.commons.logging.LogFactory;
61 import org.springframework.beans.BeansException;
62 import org.springframework.beans.factory.DisposableBean;
63 import org.springframework.context.ApplicationContext;
64 import org.springframework.context.ApplicationContextAware;
65 import org.springframework.context.ApplicationEvent;
66 import org.springframework.context.ApplicationListener;
67 import org.springframework.context.event.ApplicationEventMulticaster;
68 import org.springframework.context.event.ContextClosedEvent;
69 import org.springframework.context.event.ContextRefreshedEvent;
70 import org.springframework.context.support.AbstractApplicationContext;
71
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 implements ApplicationEventMulticaster, ApplicationContextAware, DisposableBean
121 {
122 public static final String EVENT_MULTICASTER_DESCRIPTOR_NAME = "muleEventMulticasterDescriptor";
123
124
125
126
127 protected static final Log logger = LogFactory.getLog(MuleEventMulticaster.class);
128
129
130
131
132 protected final Set listeners = new CopyOnWriteArraySet();
133
134
135
136
137 protected boolean asynchronous = false;
138
139
140
141
142 protected ExecutorService asyncPool = null;
143
144
145
146
147
148
149 protected Map endpointMappings = null;
150
151
152
153
154
155
156
157
158 protected String[] subscriptions = null;
159
160
161
162
163 protected ApplicationContext applicationContext;
164
165
166
167
168 protected UMODescriptor descriptor;
169
170
171
172
173 protected UMOComponent component;
174
175
176
177
178 protected Class subscriptionFilter = WildcardFilter.class;
179
180
181
182
183 protected ExceptionListener exceptionListener = new LoggingExceptionListener();
184
185
186
187
188
189
190
191
192
193
194
195
196 public void addApplicationListener(ApplicationListener listener)
197 {
198 Object listenerToAdd = listener;
199
200 if (asynchronous)
201 {
202 listenerToAdd = new AsynchronousEventListener(asyncPool, listener);
203 }
204
205 listeners.add(listenerToAdd);
206 }
207
208
209
210
211
212
213 public void removeApplicationListener(ApplicationListener listener)
214 {
215 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
216 {
217 ApplicationListener applicationListener = (ApplicationListener)iterator.next();
218 if (applicationListener instanceof AsynchronousEventListener)
219 {
220 if (((AsynchronousEventListener)applicationListener).getListener().equals(listener))
221 {
222 listeners.remove(applicationListener);
223 return;
224 }
225 }
226 else
227 {
228 if (applicationListener.equals(listener))
229 {
230 listeners.remove(applicationListener);
231 return;
232 }
233 }
234 }
235 listeners.remove(listener);
236 }
237
238
239
240
241 public void removeAllListeners()
242 {
243 listeners.clear();
244 }
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259 public void multicastEvent(ApplicationEvent e)
260 {
261 MuleApplicationEvent muleEvent = null;
262
263 if (e instanceof ContextRefreshedEvent)
264 {
265
266
267 if (MuleManager.isInstanciated() && !MuleManager.getInstance().isInitialised())
268 {
269 try
270 {
271 registerMulticasterDescriptor();
272 }
273 catch (UMOException ex)
274 {
275 throw new MuleRuntimeException(SpringMessages.failedToReinitMule(), ex);
276 }
277 }
278 else
279 {
280 initMule();
281 }
282 }
283 else if (e instanceof ContextClosedEvent)
284 {
285 MuleManager.getInstance().dispose();
286 return;
287 }
288 else if (e instanceof MuleApplicationEvent)
289 {
290 muleEvent = (MuleApplicationEvent)e;
291
292
293 if (muleEvent.getMuleEventContext() == null)
294 {
295 try
296 {
297 dispatchEvent(muleEvent);
298 }
299 catch (ApplicationEventException e1)
300 {
301 exceptionListener.exceptionThrown(e1);
302 }
303 return;
304 }
305 }
306
307 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
308 {
309 ApplicationListener listener = (ApplicationListener)iterator.next();
310 if (muleEvent != null)
311 {
312
313
314
315 if (listener instanceof AsynchronousEventListener)
316 {
317 AsynchronousEventListener asyncListener = (AsynchronousEventListener)listener;
318 if (asyncListener.getListener() instanceof MuleSubscriptionEventListener)
319 {
320 if (isSubscriptionMatch(muleEvent.getEndpoint(),
321 ((MuleSubscriptionEventListener)asyncListener.getListener()).getSubscriptions()))
322 {
323 asyncListener.onApplicationEvent(muleEvent);
324 }
325 }
326 else if (asyncListener.getListener() instanceof MuleEventListener)
327 {
328 asyncListener.onApplicationEvent(muleEvent);
329 }
330 else if (!(asyncListener.getListener() instanceof MuleEventListener))
331 {
332 asyncListener.onApplicationEvent(e);
333 }
334
335 }
336 else if (listener instanceof MuleSubscriptionEventListener)
337 {
338 if (isSubscriptionMatch(muleEvent.getEndpoint(),
339 ((MuleSubscriptionEventListener)listener).getSubscriptions()))
340 {
341 listener.onApplicationEvent(muleEvent);
342 }
343 }
344 else if (listener instanceof MuleEventListener)
345 {
346 listener.onApplicationEvent(muleEvent);
347 }
348 }
349 else if (listener instanceof AsynchronousEventListener
350 && !(((AsynchronousEventListener)listener).getListener() instanceof MuleEventListener))
351 {
352 listener.onApplicationEvent(e);
353 }
354 else if (!(listener instanceof MuleEventListener))
355 {
356 listener.onApplicationEvent(e);
357 }
358 else
359 {
360
361
362 for (int i = 0; i < listener.getClass().getInterfaces().length; i++)
363 {
364 if (listener.getClass().getInterfaces()[i].equals(ApplicationListener.class))
365 {
366 listener.onApplicationEvent(e);
367 break;
368 }
369 }
370
371 }
372 }
373 }
374
375
376
377
378
379
380
381
382 private boolean isSubscriptionMatch(String endpoint, String[] subscriptions)
383 {
384 for (int i = 0; i < subscriptions.length; i++)
385 {
386 String subscription = MapUtils.getString(MuleManager.getInstance().getEndpointIdentifiers(),
387 subscriptions[i], subscriptions[i]);
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406 ObjectFilter filter = createFilter(subscription);
407 if (filter.accept(endpoint))
408 {
409 return true;
410 }
411 }
412 return false;
413 }
414
415
416
417
418
419
420 public boolean isAsynchronous()
421 {
422 return asynchronous;
423 }
424
425
426
427
428
429
430 public void setAsynchronous(boolean asynchronous)
431 {
432 this.asynchronous = asynchronous;
433 if (asynchronous)
434 {
435 if (asyncPool == null)
436 {
437 asyncPool = MuleManager.getConfiguration().getDefaultThreadingProfile().createPool(
438 "spring-events");
439 }
440 }
441 else
442 {
443 if (asyncPool != null)
444 {
445 asyncPool.shutdown();
446 asyncPool = null;
447 }
448 }
449 }
450
451
452
453
454
455
456
457 public void onMuleEvent(UMOEventContext context) throws TransformerException, MalformedEndpointException
458 {
459 multicastEvent(new MuleApplicationEvent(context.getTransformedMessage(), context, applicationContext));
460 context.setStopFurtherProcessing(true);
461 }
462
463
464
465
466
467
468
469
470 protected void dispatchEvent(MuleApplicationEvent applicationEvent) throws ApplicationEventException
471 {
472 UMOEndpoint endpoint = null;
473 try
474 {
475 endpoint = MuleEndpoint.getOrCreateEndpointForUri(applicationEvent.getEndpoint(),
476 UMOEndpoint.ENDPOINT_TYPE_SENDER);
477 }
478 catch (UMOException e)
479 {
480 throw new ApplicationEventException("Failed to get endpoint for endpointUri: "
481 + applicationEvent.getEndpoint(), e);
482 }
483 if (endpoint != null)
484 {
485 try
486 {
487
488
489
490
491 MuleMessage message = new MuleMessage(applicationEvent.getSource(),
492 applicationEvent.getProperties());
493
494
495 if (applicationEvent.getMuleEventContext() != null)
496 {
497
498 applicationEvent.getMuleEventContext().setStopFurtherProcessing(true);
499 applicationEvent.getMuleEventContext().dispatchEvent(message, endpoint);
500 }
501 else
502 {
503 UMOSession session = new MuleSession(message,
504 ((AbstractConnector)endpoint.getConnector()).getSessionHandler(), component);
505 RequestContext.setEvent(new MuleEvent(message, endpoint, session, false));
506
507 if (endpoint.getTransformer() != null)
508 {
509 message = new MuleMessage(endpoint.getTransformer().transform(
510 applicationEvent.getSource()), applicationEvent.getProperties());
511 }
512 endpoint.dispatch(new MuleEvent(message, endpoint, session, false));
513 }
514 }
515 catch (Exception e1)
516 {
517 throw new ApplicationEventException("Failed to dispatch event: " + e1.getMessage(), e1);
518 }
519 }
520 else
521 {
522 throw new ApplicationEventException("Failed endpoint using name: "
523 + applicationEvent.getEndpoint());
524 }
525 }
526
527
528
529
530
531
532
533 public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
534 {
535 this.applicationContext = applicationContext;
536 }
537
538 protected void initMule()
539 {
540 try
541 {
542
543
544 if (applicationContext.containsBean(EVENT_MULTICASTER_DESCRIPTOR_NAME))
545 {
546 descriptor = (UMODescriptor)applicationContext.getBean(EVENT_MULTICASTER_DESCRIPTOR_NAME);
547 }
548
549
550 if (applicationContext.containsBean("muleManager"))
551 {
552
553 registerMulticasterDescriptor();
554 return;
555 }
556 UMOManager manager = MuleManager.getInstance();
557 Map map = applicationContext.getBeansOfType(MuleConfiguration.class);
558 if (map != null && map.size() > 0)
559 {
560 MuleManager.setConfiguration((MuleConfiguration)map.values().iterator().next());
561 }
562 if (!manager.isStarted())
563 {
564 MuleManager.getConfiguration().setSynchronous(!asynchronous);
565
566 registerEndpointMappings();
567 }
568
569 SpringContainerContext containerContext = new SpringContainerContext();
570 containerContext.setBeanFactory(applicationContext);
571 manager.setContainerContext(null);
572 manager.setContainerContext(containerContext);
573
574
575 registerConnectors();
576
577
578 registerTransformers();
579
580 registerGlobalEndpoints();
581
582
583 registerMulticasterDescriptor();
584
585 if (!manager.isStarted())
586 {
587 manager.start();
588 }
589 }
590 catch (UMOException e)
591 {
592 throw new MuleRuntimeException(SpringMessages.failedToReinitMule(), e);
593 }
594 }
595
596 protected void registerMulticasterDescriptor() throws UMOException
597 {
598
599 if (descriptor == null)
600 {
601 descriptor = getDefaultDescriptor();
602 setSubscriptionsOnDescriptor((MuleDescriptor)descriptor);
603 component = MuleManager.getInstance().lookupModel(ModelHelper.SYSTEM_MODEL).registerComponent(descriptor);
604 }
605 }
606
607 protected void setSubscriptionsOnDescriptor(MuleDescriptor descriptor) throws UMOException
608 {
609 List endpoints = new ArrayList();
610 for (Iterator iterator = listeners.iterator(); iterator.hasNext();)
611 {
612 ApplicationListener listener = (ApplicationListener)iterator.next();
613 if (listener instanceof AsynchronousEventListener)
614 {
615 listener = ((AsynchronousEventListener)listener).getListener();
616 }
617 if (listener instanceof MuleSubscriptionEventListener)
618 {
619 String[] subscriptions = ((MuleSubscriptionEventListener)listener).getSubscriptions();
620 for (int i = 0; i < subscriptions.length; i++)
621 {
622 if (subscriptions[i].indexOf("*") == -1 && MuleEndpointURI.isMuleUri(subscriptions[i]))
623 {
624 boolean isSoap = registerAsSoap(subscriptions[i], listener);
625
626 if (!isSoap)
627 {
628 endpoints.add(subscriptions[i]);
629 }
630 }
631 }
632 }
633 }
634 if (endpoints.size() > 0)
635 {
636 for (Iterator iterator = endpoints.iterator(); iterator.hasNext();)
637 {
638 String endpoint = (String)iterator.next();
639 MuleEndpoint ep = new MuleEndpoint(endpoint, true);
640
641
642 if (descriptor.getInboundRouter().getEndpoint(ep.getName()) == null)
643 {
644 descriptor.getInboundRouter().addEndpoint(ep);
645 }
646 }
647 }
648 }
649
650 private boolean registerAsSoap(String endpoint, Object listener) throws UMOException
651 {
652 if (endpoint.startsWith("glue") || endpoint.startsWith("soap") || endpoint.startsWith("axis"))
653 {
654 UMOEndpointURI ep = new MuleEndpointURI(endpoint);
655 QuickConfigurationBuilder builder = new QuickConfigurationBuilder();
656
657
658 String serviceName = null;
659 if (ep.getPath() != null)
660 {
661 String path = ep.getPath();
662 if (path.endsWith("/"))
663 {
664 path = path.substring(0, path.length() - 1);
665 }
666 int i = path.lastIndexOf("/");
667 if (i > -1)
668 {
669 serviceName = path.substring(i + 1);
670 }
671 }
672 else
673 {
674 serviceName = descriptor.getName();
675 }
676
677 String newEndpoint = endpoint;
678 int i = newEndpoint.indexOf(serviceName);
679 newEndpoint = newEndpoint.substring(0, i - 1);
680 builder.registerComponentInstance(listener, serviceName, new MuleEndpointURI(newEndpoint));
681 return true;
682 }
683 else
684 {
685 return false;
686 }
687 }
688
689 protected void registerEndpointMappings() throws InitialisationException
690 {
691
692 if (endpointMappings != null)
693 {
694 Map.Entry entry = null;
695 for (Iterator iterator = endpointMappings.entrySet().iterator(); iterator.hasNext();)
696 {
697 entry = (Map.Entry)iterator.next();
698 MuleManager.getInstance().registerEndpointIdentifier((String)entry.getKey(),
699 (String)entry.getValue());
700 }
701 }
702 }
703
704 protected void registerConnectors() throws UMOException
705 {
706 if (!MuleManager.getInstance().isInitialised())
707 {
708
709 Map connectors = applicationContext.getBeansOfType(UMOConnector.class, true, true);
710 if (connectors.size() > 0)
711 {
712 Map.Entry entry;
713 UMOConnector c;
714 for (Iterator iterator = connectors.entrySet().iterator(); iterator.hasNext();)
715 {
716 entry = (Map.Entry)iterator.next();
717 c = (UMOConnector)entry.getValue();
718 if (c.getName() == null)
719 {
720 c.setName(entry.getKey().toString());
721 }
722 MuleManager.getInstance().registerConnector(c);
723 }
724 }
725 }
726 }
727
728 protected void registerGlobalEndpoints() throws UMOException
729 {
730 if (!MuleManager.getInstance().isInitialised())
731 {
732
733 Map endpoints = applicationContext.getBeansOfType(UMOEndpoint.class, true, true);
734 if (endpoints.size() > 0)
735 {
736 Map.Entry entry;
737 UMOEndpoint endpoint;
738 for (Iterator iterator = endpoints.entrySet().iterator(); iterator.hasNext();)
739 {
740 entry = (Map.Entry)iterator.next();
741 endpoint = (UMOEndpoint)entry.getValue();
742 if (endpoint.getName() == null)
743 {
744 endpoint.setName(entry.getKey().toString());
745 }
746 MuleManager.getInstance().registerEndpoint(endpoint);
747 }
748 }
749 }
750 }
751
752 protected void registerTransformers() throws UMOException
753 {
754 if (!MuleManager.getInstance().isInitialised())
755 {
756
757 Map transformers = applicationContext.getBeansOfType(UMOTransformer.class, true, true);
758 if (transformers.size() > 0)
759 {
760 Map.Entry entry;
761 UMOTransformer t;
762 for (Iterator iterator = transformers.entrySet().iterator(); iterator.hasNext();)
763 {
764 entry = (Map.Entry)iterator.next();
765 t = (UMOTransformer)entry.getValue();
766 if (t.getName() == null)
767 {
768 t.setName(entry.getKey().toString());
769 }
770 MuleManager.getInstance().registerTransformer(t);
771 }
772 }
773 }
774 }
775
776 protected UMODescriptor getDefaultDescriptor() throws UMOException
777 {
778
779
780 UMOModel model = MuleManager.getInstance().lookupModel(ModelHelper.SYSTEM_MODEL);
781 if(model==null)
782 {
783 model = new SedaModel();
784 model.setName(ModelHelper.SYSTEM_MODEL);
785 MuleManager.getInstance().registerModel(model);
786 }
787 UMODescriptor descriptor = model.getDescriptor(EVENT_MULTICASTER_DESCRIPTOR_NAME);
788 if (descriptor != null)
789 {
790 model.unregisterComponent(descriptor);
791 }
792 descriptor = new MuleDescriptor(EVENT_MULTICASTER_DESCRIPTOR_NAME);
793 if (subscriptions == null)
794 {
795 logger.info("No receive endpoints have been set, using default '*'");
796 descriptor.setInboundEndpoint(new MuleEndpoint("vm://*", true));
797 }
798 else
799 {
800
801 UMOInboundRouterCollection messageRouter = descriptor.getInboundRouter();
802
803 for (int i = 0; i < subscriptions.length; i++)
804 {
805 String subscription = subscriptions[i];
806 UMOEndpointURI endpointUri = new MuleEndpointURI(subscription);
807 UMOEndpoint endpoint = MuleEndpoint.getOrCreateEndpointForUri(endpointUri,
808 UMOEndpoint.ENDPOINT_TYPE_RECEIVER);
809 if (!asynchronous)
810 {
811 endpoint.setSynchronous(true);
812 }
813 messageRouter.addEndpoint(endpoint);
814 }
815 }
816
817 descriptor.setImplementation(AbstractApplicationContext.APPLICATION_EVENT_MULTICASTER_BEAN_NAME);
818 return descriptor;
819 }
820
821 protected ObjectFilter createFilter(String pattern)
822 {
823 try
824 {
825 if (getSubscriptionFilter() == null)
826 {
827 setSubscriptionFilter(WildcardFilter.class);
828 }
829 ObjectFilter filter = (ObjectFilter)ClassUtils.instanciateClass(getSubscriptionFilter(),
830 new Object[]{pattern});
831 return filter;
832 }
833 catch (Exception e)
834 {
835 exceptionListener.exceptionThrown(e);
836 return new WildcardFilter(pattern);
837 }
838 }
839
840
841
842
843
844
845
846 public Class getSubscriptionFilter()
847 {
848 return subscriptionFilter;
849 }
850
851
852
853
854
855
856 public void setSubscriptionFilter(Class subscriptionFilter)
857 {
858 this.subscriptionFilter = subscriptionFilter;
859 }
860
861
862
863
864
865
866
867
868 public Map getEndpointMappings()
869 {
870 return endpointMappings;
871 }
872
873
874
875
876
877
878
879
880 public void setEndpointMappings(Map endpointMappings)
881 {
882 this.endpointMappings = endpointMappings;
883 }
884
885
886
887
888
889
890
891
892
893
894 public String[] getSubscriptions()
895 {
896 return subscriptions;
897 }
898
899
900
901
902
903
904
905
906
907
908 public void setSubscriptions(String[] subscriptions)
909 {
910 this.subscriptions = subscriptions;
911 }
912
913 protected void setExceptionListener(ExceptionListener listener)
914 {
915 if (listener != null)
916 {
917 this.exceptionListener = listener;
918 }
919 else
920 {
921 throw new IllegalArgumentException("exceptionListener may not be null");
922 }
923 }
924
925 private class LoggingExceptionListener implements ExceptionListener
926 {
927 public void exceptionThrown(Exception e)
928 {
929 logger.error(e.getMessage(), e);
930 }
931 }
932
933
934 public void destroy() throws Exception
935 {
936 MuleManager.getInstance().dispose();
937 }
938 }