1
2
3
4
5
6
7
8
9
10
11 package org.mule.module.client;
12
13 import org.mule.DefaultMuleEvent;
14 import org.mule.DefaultMuleMessage;
15 import org.mule.DefaultMuleSession;
16 import org.mule.MuleServer;
17 import org.mule.api.FutureMessageResult;
18 import org.mule.api.MessagingException;
19 import org.mule.api.MuleContext;
20 import org.mule.api.MuleEvent;
21 import org.mule.api.MuleException;
22 import org.mule.api.MuleMessage;
23 import org.mule.api.MuleSession;
24 import org.mule.api.config.ConfigurationBuilder;
25 import org.mule.api.config.ConfigurationException;
26 import org.mule.api.config.MuleConfiguration;
27 import org.mule.api.config.MuleProperties;
28 import org.mule.api.context.MuleContextBuilder;
29 import org.mule.api.endpoint.EndpointBuilder;
30 import org.mule.api.endpoint.EndpointURI;
31 import org.mule.api.endpoint.ImmutableEndpoint;
32 import org.mule.api.endpoint.InboundEndpoint;
33 import org.mule.api.endpoint.OutboundEndpoint;
34 import org.mule.api.lifecycle.Disposable;
35 import org.mule.api.lifecycle.InitialisationException;
36 import org.mule.api.registry.RegistrationException;
37 import org.mule.api.service.Service;
38 import org.mule.api.transport.DispatchException;
39 import org.mule.api.transport.ReceiveException;
40 import org.mule.config.DefaultMuleConfiguration;
41 import org.mule.config.i18n.CoreMessages;
42 import org.mule.config.spring.SpringXmlConfigurationBuilder;
43 import org.mule.context.DefaultMuleContextBuilder;
44 import org.mule.context.DefaultMuleContextFactory;
45 import org.mule.endpoint.EndpointURIEndpointBuilder;
46 import org.mule.endpoint.MuleEndpointURI;
47 import org.mule.module.client.i18n.ClientMessages;
48 import org.mule.security.MuleCredentials;
49 import org.mule.transformer.TransformerUtils;
50 import org.mule.transport.AbstractConnector;
51 import org.mule.transport.NullPayload;
52 import org.mule.util.StringUtils;
53
54 import java.util.ArrayList;
55 import java.util.HashMap;
56 import java.util.Iterator;
57 import java.util.LinkedList;
58 import java.util.List;
59 import java.util.Map;
60
61 import edu.emory.mathcs.backport.java.util.concurrent.Callable;
62 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
63 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentMap;
64
65 import org.apache.commons.logging.Log;
66 import org.apache.commons.logging.LogFactory;
67
68
69
70
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 public class MuleClient implements Disposable
97 {
98
99
100
101 protected static final Log logger = LogFactory.getLog(MuleClient.class);
102
103
104
105
106 private MuleContext muleContext;
107
108 private List dispatchers = new ArrayList();
109
110 private MuleCredentials user;
111
112 private DefaultMuleContextFactory muleContextFactory = new DefaultMuleContextFactory();
113
114 private ConcurrentMap inboundEndpointCache = new ConcurrentHashMap();
115 private ConcurrentMap outboundEndpointCache = new ConcurrentHashMap();
116
117
118
119
120
121
122
123 public MuleClient() throws MuleException
124 {
125 this(true);
126 }
127
128 public MuleClient(boolean startContext) throws MuleException
129 {
130 init(startContext);
131 }
132
133 public MuleClient(MuleContext context) throws MuleException
134 {
135 this.muleContext = context;
136 init(false);
137 }
138
139
140
141
142
143
144
145
146
147
148
149 public MuleClient(String configResources) throws MuleException
150 {
151 this(configResources, new SpringXmlConfigurationBuilder(configResources));
152 }
153
154
155
156
157
158
159
160
161
162 public MuleClient(String user, String password) throws MuleException
163 {
164 init(
165 this.user = new MuleCredentials(user, password.toCharArray());
166 }
167
168
169
170
171
172
173
174
175
176
177
178
179 public MuleClient(String configResources, ConfigurationBuilder builder)
180 throws ConfigurationException, InitialisationException
181 {
182 if (builder == null)
183 {
184 logger.info("Builder passed in was null, using default builder: "
185 + SpringXmlConfigurationBuilder.class.getName());
186 builder = new SpringXmlConfigurationBuilder(configResources);
187 }
188 logger.info("Initializing Mule...");
189 muleContext = muleContextFactory.createMuleContext(builder);
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205 public MuleClient(String configResources, ConfigurationBuilder builder, String user, String password)
206 throws ConfigurationException, InitialisationException
207 {
208 this(configResources, builder);
209 this.user = new MuleCredentials(user, password.toCharArray());
210 }
211
212
213
214
215
216
217
218 private void init(boolean startManager) throws MuleException
219 {
220
221
222
223 if (muleContext == null)
224 {
225 muleContext = MuleServer.getMuleContext();
226 }
227 if (muleContext == null)
228 {
229 logger.info("No existing ManagementContext found, creating a new Mule instance");
230
231 MuleContextBuilder contextBuilder = new DefaultMuleContextBuilder();
232 DefaultMuleConfiguration config = new DefaultMuleConfiguration();
233 config.setClientMode(true);
234 contextBuilder.setMuleConfiguration(config);
235 muleContext = muleContextFactory.createMuleContext(contextBuilder);
236 }
237 else
238 {
239 logger.info("Using existing MuleContext: " + muleContext);
240 }
241
242 if (!muleContext.isStarted() && startManager == true)
243 {
244 logger.info("Starting Mule...");
245 muleContext.start();
246 }
247 }
248
249
250
251
252
253
254
255
256
257
258
259
260
261 public void dispatch(String url, Object payload, Map messageProperties) throws MuleException
262 {
263 dispatch(url, new DefaultMuleMessage(payload, messageProperties));
264 }
265
266
267
268
269
270
271
272
273
274
275 public void dispatch(String url, MuleMessage message) throws MuleException
276 {
277 MuleEvent event = getEvent(message, url, false);
278 try
279 {
280 event.getSession().dispatchEvent(event);
281 }
282 catch (MuleException e)
283 {
284 throw e;
285 }
286 catch (Exception e)
287 {
288 throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), event.getMessage(),
289 event.getEndpoint(), e);
290 }
291 }
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306 public MuleMessage sendDirect(String component, String transformers, Object payload, Map messageProperties)
307 throws MuleException
308 {
309 MuleMessage message = new DefaultMuleMessage(payload, messageProperties);
310 return sendDirect(component, transformers, message);
311 }
312
313
314
315
316
317
318
319
320
321
322
323
324 public MuleMessage sendDirect(String componentName, String transformers, MuleMessage message)
325 throws MuleException
326 {
327 Service service = muleContext.getRegistry().lookupService(componentName);
328 if (service == null)
329 {
330 throw new MessagingException(CoreMessages.objectNotRegistered("Service", componentName),
331 message);
332 }
333 List trans = null;
334 if (transformers != null)
335 {
336 trans = TransformerUtils.getTransformers(transformers);
337 }
338
339 if (!muleContext.getConfiguration().isDefaultSynchronousEndpoints())
340 {
341 logger.warn("The mule muleContext is not running synchronously, a null message payload will be returned");
342 }
343 MuleSession session = new DefaultMuleSession(service, muleContext);
344 ImmutableEndpoint endpoint = getDefaultClientEndpoint(service, message.getPayload());
345 MuleEvent event = new DefaultMuleEvent(message, endpoint, session, true);
346
347 if (logger.isDebugEnabled())
348 {
349 logger.debug("MuleClient sending event direct to: " + componentName + ". MuleEvent is: " + event);
350 }
351
352 MuleMessage result = event.getService().sendEvent(event);
353
354 if (logger.isDebugEnabled())
355 {
356 logger.debug("Result of MuleClient sendDirect is: "
357 + (result == null ? "null" : result.getPayload()));
358 }
359
360 if (result != null && trans != null)
361 {
362 result.applyTransformers(trans);
363 }
364 return result;
365 }
366
367
368
369
370
371
372
373
374
375
376
377 public void dispatchDirect(String component, Object payload, Map messageProperties) throws MuleException
378 {
379 dispatchDirect(component, new DefaultMuleMessage(payload, messageProperties));
380 }
381
382
383
384
385
386
387
388
389
390 public void dispatchDirect(String componentName, MuleMessage message) throws MuleException
391 {
392 Service service = muleContext.getRegistry().lookupService(componentName);
393 if (service == null)
394 {
395 throw new MessagingException(CoreMessages.objectNotRegistered("Service", componentName),
396 message);
397 }
398 MuleSession session = new DefaultMuleSession(service, muleContext);
399 ImmutableEndpoint endpoint = getDefaultClientEndpoint(service, message.getPayload());
400 MuleEvent event = new DefaultMuleEvent(message, endpoint, session, true);
401
402 if (logger.isDebugEnabled())
403 {
404 logger.debug("MuleClient dispatching event direct to: " + componentName + ". MuleEvent is: " + event);
405 }
406
407 event.getService().dispatchEvent(event);
408 }
409
410
411
412
413
414
415
416
417
418
419
420
421
422 public FutureMessageResult sendAsync(final String url, final Object payload, final Map messageProperties)
423 throws MuleException
424 {
425 return sendAsync(url, payload, messageProperties, 0);
426 }
427
428
429
430
431
432
433
434
435
436
437
438 public FutureMessageResult sendAsync(final String url, final MuleMessage message) throws MuleException
439 {
440 return sendAsync(url, message, MuleEvent.TIMEOUT_NOT_SET_VALUE);
441 }
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456 public FutureMessageResult sendAsync(final String url,
457 final Object payload,
458 final Map messageProperties,
459 final int timeout) throws MuleException
460 {
461 return sendAsync(url, new DefaultMuleMessage(payload, messageProperties), timeout);
462 }
463
464
465
466
467
468
469
470
471
472
473
474
475 public FutureMessageResult sendAsync(final String url, final MuleMessage message, final int timeout)
476 throws MuleException
477 {
478 Callable call = new Callable()
479 {
480 public Object call() throws Exception
481 {
482 return send(url, message, timeout);
483 }
484 };
485
486 FutureMessageResult result = new FutureMessageResult(call);
487
488 if (muleContext.getWorkManager() != null)
489 {
490 result.setExecutor(muleContext.getWorkManager());
491 }
492
493 result.execute();
494 return result;
495 }
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513 public FutureMessageResult sendDirectAsync(final String component,
514 String transformers,
515 final Object payload,
516 final Map messageProperties) throws MuleException
517 {
518 return sendDirectAsync(component, transformers, new DefaultMuleMessage(payload, messageProperties));
519 }
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536 public FutureMessageResult sendDirectAsync(final String component,
537 String transformers,
538 final MuleMessage message) throws MuleException
539 {
540 Callable call = new Callable()
541 {
542 public Object call() throws Exception
543 {
544 return sendDirect(component, null, message);
545 }
546 };
547
548 FutureMessageResult result = new FutureMessageResult(call);
549
550 if (muleContext.getWorkManager() != null)
551 {
552 result.setExecutor(muleContext.getWorkManager());
553 }
554
555 if (StringUtils.isNotBlank(transformers))
556 {
557 result.setTransformers(TransformerUtils.getTransformers(transformers));
558 }
559
560 result.execute();
561 return result;
562 }
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578 public MuleMessage send(String url, Object payload, Map messageProperties) throws MuleException
579 {
580 return send(url, payload, messageProperties, MuleEvent.TIMEOUT_NOT_SET_VALUE);
581 }
582
583
584
585
586
587
588
589
590
591
592
593
594 public MuleMessage send(String url, MuleMessage message) throws MuleException
595 {
596 return send(url, message, MuleEvent.TIMEOUT_NOT_SET_VALUE);
597 }
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615 public MuleMessage send(String url, Object payload, Map messageProperties, int timeout)
616 throws MuleException
617 {
618 if (messageProperties == null)
619 {
620 messageProperties = new HashMap();
621 }
622 if (messageProperties.get(MuleProperties.MULE_REMOTE_SYNC_PROPERTY) == null)
623 {
624 messageProperties.put(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, "true");
625 }
626 MuleMessage message = new DefaultMuleMessage(payload, messageProperties);
627 return send(url, message, timeout);
628 }
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643 public MuleMessage send(String url, MuleMessage message, int timeout) throws MuleException
644 {
645 MuleEvent event = getEvent(message, url, true);
646 event.setTimeout(timeout);
647
648 try
649 {
650 MuleMessage msg = event.getSession().sendEvent(event);
651 if (msg == null)
652 {
653 msg = new DefaultMuleMessage(NullPayload.getInstance());
654 }
655 return msg;
656 }
657 catch (MuleException e)
658 {
659 throw e;
660 }
661 catch (Exception e)
662 {
663 throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), event.getMessage(),
664 event.getEndpoint(), e);
665 }
666 }
667
668
669
670
671
672
673
674
675
676
677
678
679 public MuleMessage request(String url, long timeout) throws MuleException
680 {
681 InboundEndpoint endpoint = getInboundEndpoint(url);
682 try
683 {
684 MuleMessage message = endpoint.request(timeout);
685 if (message != null && endpoint.getTransformers() != null)
686 {
687 message.applyTransformers(endpoint.getTransformers());
688 }
689 return message;
690 }
691 catch (Exception e)
692 {
693 throw new ReceiveException(endpoint, timeout, e);
694 }
695 }
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710 public MuleMessage request(String url, String transformers, long timeout) throws MuleException
711 {
712 return request(url, TransformerUtils.getTransformers(transformers), timeout);
713 }
714
715
716
717
718
719
720
721
722
723
724
725
726
727 public MuleMessage request(String url, List transformers, long timeout) throws MuleException
728 {
729 MuleMessage message = request(url, timeout);
730 if (message != null && transformers != null)
731 {
732 message.applyTransformers(transformers);
733 }
734 return message;
735 }
736
737
738
739
740
741
742
743
744
745
746 protected MuleEvent getEvent(MuleMessage message, String uri, boolean synchronous)
747 throws MuleException
748 {
749 ImmutableEndpoint endpoint = getOutboundEndpoint(uri);
750 if (!endpoint.getConnector().isStarted() && muleContext.isStarted())
751 {
752 endpoint.getConnector().start();
753 }
754 try
755 {
756 DefaultMuleSession session = new DefaultMuleSession(message,
757 ((AbstractConnector) endpoint.getConnector()).getSessionHandler(), muleContext);
758
759 if (user != null)
760 {
761 message.setProperty(MuleProperties.MULE_USER_PROPERTY, MuleCredentials.createHeader(
762 user.getUsername(), user.getPassword()));
763 }
764 DefaultMuleEvent event = new DefaultMuleEvent(message, endpoint, session, synchronous);
765 return event;
766 }
767 catch (Exception e)
768 {
769 throw new DispatchException(CoreMessages.failedToCreate("Client event"), message, endpoint, e);
770 }
771 }
772
773 protected InboundEndpoint getInboundEndpoint(String uri) throws MuleException
774 {
775
776
777
778
779
780
781 InboundEndpoint endpoint = (InboundEndpoint) inboundEndpointCache.get(uri);
782 if (endpoint == null)
783 {
784 endpoint = muleContext.getRegistry().lookupEndpointFactory().getInboundEndpoint(uri);
785 InboundEndpoint concurrentlyAddedEndpoint = (InboundEndpoint) inboundEndpointCache.putIfAbsent(uri, endpoint);
786 if (concurrentlyAddedEndpoint != null)
787 {
788 return concurrentlyAddedEndpoint;
789 }
790 }
791 return endpoint;
792 }
793
794 protected OutboundEndpoint getOutboundEndpoint(String uri) throws MuleException
795 {
796
797
798
799
800
801
802 OutboundEndpoint endpoint = (OutboundEndpoint) outboundEndpointCache.get(uri);
803 if (endpoint == null)
804 {
805 endpoint = muleContext.getRegistry().lookupEndpointFactory().getOutboundEndpoint(uri);
806 OutboundEndpoint concurrentlyAddedEndpoint = (OutboundEndpoint) outboundEndpointCache.putIfAbsent(uri, endpoint);
807 if (concurrentlyAddedEndpoint != null)
808 {
809 return concurrentlyAddedEndpoint;
810 }
811 }
812 return endpoint;
813 }
814
815 protected ImmutableEndpoint getDefaultClientEndpoint(Service service, Object payload)
816 throws MuleException
817 {
818
819 ImmutableEndpoint endpoint = (ImmutableEndpoint) service.getInboundRouter().getEndpoints().get(0);
820 if (endpoint != null)
821 {
822 if (endpoint.getTransformers() != null)
823 {
824
825
826 if (TransformerUtils.isSourceTypeSupportedByFirst(endpoint.getTransformers(),
827 payload.getClass()))
828 {
829 return endpoint;
830 }
831 else
832 {
833 EndpointBuilder builder = new EndpointURIEndpointBuilder(endpoint, muleContext);
834 builder.setTransformers(new LinkedList());
835 return muleContext.getRegistry().lookupEndpointFactory().getInboundEndpoint(builder);
836 }
837 }
838 else
839 {
840 return endpoint;
841 }
842 }
843 else
844 {
845 EndpointBuilder builder = new EndpointURIEndpointBuilder("vm://mule.client", muleContext);
846 builder.setName("muleClientProvider");
847 endpoint = muleContext.getRegistry().lookupEndpointFactory().getInboundEndpoint(builder);
848 }
849 return endpoint;
850 }
851
852
853
854
855
856
857
858
859
860
861
862
863
864 public void sendNoReceive(String url, Object payload, Map messageProperties) throws MuleException
865 {
866 if (messageProperties == null)
867 {
868 messageProperties = new HashMap();
869 }
870 messageProperties.put(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, "false");
871 MuleMessage message = new DefaultMuleMessage(payload, messageProperties);
872 MuleEvent event = getEvent(message, url, true);
873 try
874 {
875 event.getSession().sendEvent(event);
876 }
877 catch (MuleException e)
878 {
879 throw e;
880 }
881 catch (Exception e)
882 {
883 throw new DispatchException(ClientMessages.failedToDispatchClientEvent(), event.getMessage(),
884 event.getEndpoint(), e);
885 }
886 }
887
888
889
890
891
892
893 public MuleContext getMuleContext()
894 {
895 return muleContext;
896 }
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912 public void registerComponent(Object component, String name, EndpointURI listenerEndpoint)
913 throws MuleException
914 {
915 throw new UnsupportedOperationException("registerComponent");
916
917
918 }
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935 public void registerComponent(Object component,
936 String name,
937 MuleEndpointURI listenerEndpoint,
938 MuleEndpointURI sendEndpoint) throws MuleException
939 {
940 throw new UnsupportedOperationException("registerComponent");
941
942
943 }
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981 public void unregisterComponent(String name) throws MuleException
982 {
983 throw new UnsupportedOperationException("registerComponent");
984
985
986 }
987
988 public RemoteDispatcher getRemoteDispatcher(String serverEndpoint) throws MuleException
989 {
990 RemoteDispatcher rd = new RemoteDispatcher(serverEndpoint);
991 rd.setExecutor(muleContext.getWorkManager());
992 dispatchers.add(rd);
993 return rd;
994 }
995
996 public RemoteDispatcher getRemoteDispatcher(String serverEndpoint, String user, String password)
997 throws MuleException
998 {
999 RemoteDispatcher rd = new RemoteDispatcher(serverEndpoint, new MuleCredentials(user,
1000 password.toCharArray()));
1001 rd.setExecutor(muleContext.getWorkManager());
1002 dispatchers.add(rd);
1003 return rd;
1004 }
1005
1006
1007
1008
1009
1010 public void dispose()
1011 {
1012 synchronized (dispatchers)
1013 {
1014 for (Iterator iterator = dispatchers.iterator(); iterator.hasNext();)
1015 {
1016 RemoteDispatcher remoteDispatcher = (RemoteDispatcher) iterator.next();
1017 remoteDispatcher.dispose();
1018 remoteDispatcher = null;
1019 }
1020 dispatchers.clear();
1021 }
1022
1023
1024 if (muleContext.getConfiguration().isClientMode())
1025 {
1026 logger.info("Stopping Mule...");
1027 muleContext.dispose();
1028 }
1029 }
1030
1031 public void setProperty(String key, Object value)
1032 {
1033 try
1034 {
1035 muleContext.getRegistry().registerObject(key, value);
1036 }
1037 catch (RegistrationException e)
1038 {
1039 logger.error(e);
1040 }
1041 }
1042
1043 public Object getProperty(String key)
1044 {
1045 return muleContext.getRegistry().lookupObject(key);
1046 }
1047
1048 public MuleConfiguration getConfiguration()
1049 {
1050 return muleContext.getConfiguration();
1051 }
1052 }