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