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.MessageExchangePattern;
16 import org.mule.api.FutureMessageResult;
17 import org.mule.api.MuleContext;
18 import org.mule.api.MuleEvent;
19 import org.mule.api.MuleException;
20 import org.mule.api.MuleMessage;
21 import org.mule.api.MuleSession;
22 import org.mule.api.config.ConfigurationBuilder;
23 import org.mule.api.config.ConfigurationException;
24 import org.mule.api.config.MuleConfiguration;
25 import org.mule.api.config.MuleProperties;
26 import org.mule.api.context.MuleContextBuilder;
27 import org.mule.api.endpoint.EndpointBuilder;
28 import org.mule.api.endpoint.EndpointURI;
29 import org.mule.api.endpoint.InboundEndpoint;
30 import org.mule.api.endpoint.OutboundEndpoint;
31 import org.mule.api.lifecycle.Disposable;
32 import org.mule.api.lifecycle.InitialisationException;
33 import org.mule.api.registry.RegistrationException;
34 import org.mule.api.registry.ServiceException;
35 import org.mule.api.service.Service;
36 import org.mule.api.transformer.Transformer;
37 import org.mule.api.transport.ReceiveException;
38 import org.mule.client.DefaultLocalMuleClient;
39 import org.mule.config.DefaultMuleConfiguration;
40 import org.mule.config.i18n.CoreMessages;
41 import org.mule.config.spring.SpringXmlConfigurationBuilder;
42 import org.mule.context.DefaultMuleContextBuilder;
43 import org.mule.context.DefaultMuleContextFactory;
44 import org.mule.endpoint.EndpointURIEndpointBuilder;
45 import org.mule.endpoint.MuleEndpointURI;
46 import org.mule.security.MuleCredentials;
47 import org.mule.service.ServiceCompositeMessageSource;
48 import org.mule.session.DefaultMuleSession;
49 import org.mule.transformer.TransformerUtils;
50 import org.mule.transport.NullPayload;
51 import org.mule.util.StringUtils;
52
53 import java.util.ArrayList;
54 import java.util.HashMap;
55 import java.util.Iterator;
56 import java.util.LinkedList;
57 import java.util.List;
58 import java.util.Map;
59 import java.util.concurrent.Callable;
60 import java.util.concurrent.ConcurrentHashMap;
61 import 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(
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, MessageExchangePattern.ONE_WAY);
270 endpoint.process(event);
271 }
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286 public MuleMessage sendDirect(String component, String transformers, Object payload, Map messageProperties)
287 throws MuleException
288 {
289 MuleMessage message = new DefaultMuleMessage(payload, messageProperties, muleContext);
290 return sendDirect(component, transformers, message);
291 }
292
293
294
295
296
297
298
299
300
301
302
303
304 public MuleMessage sendDirect(String componentName, String transformers, MuleMessage message)
305 throws MuleException
306 {
307 Service service = muleContext.getRegistry().lookupService(componentName);
308 if (service == null)
309 {
310 throw new ServiceException(CoreMessages.objectNotRegistered("Service", componentName));
311 }
312 List<Transformer> trans = null;
313 if (transformers != null)
314 {
315 trans = TransformerUtils.getTransformers(transformers, muleContext);
316 }
317
318 MuleSession session = new DefaultMuleSession(service, muleContext);
319 InboundEndpoint endpoint = getDefaultClientEndpoint(service, message.getPayload(), true);
320 MuleEvent event = new DefaultMuleEvent(message, endpoint, session);
321
322 if (logger.isDebugEnabled())
323 {
324 logger.debug("MuleClient sending event direct to: " + componentName + ". MuleEvent is: " + event);
325 }
326
327 MuleEvent resultEvent = service.sendEvent(event);
328 MuleMessage result = resultEvent == null ? null : resultEvent.getMessage();
329 if (logger.isDebugEnabled())
330 {
331 logger.debug("Result of MuleClient sendDirect is: "
332 + (result == null ? "null" : result.getPayload()));
333 }
334
335 if (result != null && trans != null)
336 {
337 result.applyTransformers(resultEvent, trans);
338 }
339 return result;
340 }
341
342
343
344
345
346
347
348
349
350
351
352 public void dispatchDirect(String component, Object payload, Map messageProperties) throws MuleException
353 {
354 dispatchDirect(component, new DefaultMuleMessage(payload, messageProperties, muleContext));
355 }
356
357
358
359
360
361
362
363
364
365 public void dispatchDirect(String componentName, MuleMessage message) throws MuleException
366 {
367 Service service = muleContext.getRegistry().lookupService(componentName);
368 if (service == null)
369 {
370 throw new ServiceException(CoreMessages.objectNotRegistered("Service", componentName));
371 }
372 MuleSession session = new DefaultMuleSession(service, muleContext);
373 InboundEndpoint endpoint = getDefaultClientEndpoint(service, message.getPayload(), false);
374 MuleEvent event = new DefaultMuleEvent(message, endpoint, session);
375
376 if (logger.isDebugEnabled())
377 {
378 logger.debug("MuleClient dispatching event direct to: " + componentName + ". MuleEvent is: " + event);
379 }
380
381 service.dispatchEvent(event);
382 }
383
384
385
386
387
388
389
390
391
392
393
394
395
396 public FutureMessageResult sendAsync(final String url, final Object payload, final Map messageProperties)
397 throws MuleException
398 {
399 return sendAsync(url, payload, messageProperties, 0);
400 }
401
402
403
404
405
406
407
408
409
410
411
412 public FutureMessageResult sendAsync(final String url, final MuleMessage message) throws MuleException
413 {
414 return sendAsync(url, message, MuleEvent.TIMEOUT_NOT_SET_VALUE);
415 }
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430 public FutureMessageResult sendAsync(final String url,
431 final Object payload,
432 final Map messageProperties,
433 final int timeout) throws MuleException
434 {
435 return sendAsync(url, new DefaultMuleMessage(payload, messageProperties, muleContext), timeout);
436 }
437
438
439
440
441
442
443
444
445
446
447
448
449 public FutureMessageResult sendAsync(final String url, final MuleMessage message, final int timeout)
450 throws MuleException
451 {
452 Callable call = new Callable()
453 {
454 public Object call() throws Exception
455 {
456 return send(url, message, timeout);
457 }
458 };
459
460 FutureMessageResult result = new FutureMessageResult(call, muleContext);
461
462 if (muleContext.getWorkManager() != null)
463 {
464 result.setExecutor(muleContext.getWorkManager());
465 }
466
467 result.execute();
468 return result;
469 }
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487 public FutureMessageResult sendDirectAsync(final String component,
488 String transformers,
489 final Object payload,
490 final Map messageProperties) throws MuleException
491 {
492 return sendDirectAsync(component, transformers, new DefaultMuleMessage(payload, messageProperties, muleContext));
493 }
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510 public FutureMessageResult sendDirectAsync(final String component,
511 String transformers,
512 final MuleMessage message) throws MuleException
513 {
514 Callable call = new Callable()
515 {
516 public Object call() throws Exception
517 {
518 return sendDirect(component, null, message);
519 }
520 };
521
522 FutureMessageResult result = new FutureMessageResult(call, muleContext);
523
524 if (muleContext.getWorkManager() != null)
525 {
526 result.setExecutor(muleContext.getWorkManager());
527 }
528
529 if (StringUtils.isNotBlank(transformers))
530 {
531 result.setTransformers(TransformerUtils.getTransformers(transformers, muleContext));
532 }
533
534 result.execute();
535 return result;
536 }
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552 public MuleMessage send(String url, Object payload, Map messageProperties) throws MuleException
553 {
554 return send(url, payload, messageProperties, MuleEvent.TIMEOUT_NOT_SET_VALUE);
555 }
556
557
558
559
560
561
562
563
564
565
566
567
568 public MuleMessage send(String url, MuleMessage message) throws MuleException
569 {
570 return send(url, message, MuleEvent.TIMEOUT_NOT_SET_VALUE);
571 }
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589 public MuleMessage send(String url, Object payload, Map messageProperties, int timeout)
590 throws MuleException
591 {
592 if (messageProperties == null)
593 {
594 messageProperties = new HashMap();
595 }
596 if (messageProperties.get(MuleProperties.MULE_REMOTE_SYNC_PROPERTY) == null)
597 {
598
599 messageProperties = new HashMap(messageProperties);
600 messageProperties.put(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, "true");
601 }
602 MuleMessage message = new DefaultMuleMessage(payload, messageProperties, muleContext);
603 return send(url, message, timeout);
604 }
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619 public MuleMessage send(String url, MuleMessage message, int timeout) throws MuleException
620 {
621 OutboundEndpoint endpoint =
622 getOutboundEndpoint(url, MessageExchangePattern.REQUEST_RESPONSE, timeout);
623
624 MuleEvent event = getEvent(message, MessageExchangePattern.REQUEST_RESPONSE);
625
626 MuleEvent response = endpoint.process(event);
627 if (response != null)
628 {
629 return response.getMessage();
630 }
631 else
632 {
633 return new DefaultMuleMessage(NullPayload.getInstance(), muleContext);
634 }
635 }
636
637
638
639
640
641
642
643
644
645
646
647
648 public MuleMessage request(String url, long timeout) throws MuleException
649 {
650 InboundEndpoint endpoint = getInboundEndpoint(url);
651 try
652 {
653 return endpoint.request(timeout);
654 }
655 catch (Exception e)
656 {
657 throw new ReceiveException(endpoint, timeout, e);
658 }
659 }
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674 public MuleMessage request(String url, String transformers, long timeout) throws MuleException
675 {
676 return request(url, TransformerUtils.getTransformers(transformers, muleContext), timeout);
677 }
678
679
680
681
682
683
684
685
686
687
688
689
690
691 public MuleMessage request(String url, List transformers, long timeout) throws MuleException
692 {
693 return request(url, timeout);
694 }
695
696 protected MuleEvent getEvent(MuleMessage message, MessageExchangePattern exchangePattern) throws MuleException
697 {
698 DefaultMuleSession session = new DefaultMuleSession(new DefaultLocalMuleClient.MuleClientFlowConstruct(muleContext), muleContext);
699
700 if (user != null)
701 {
702 message.setOutboundProperty(MuleProperties.MULE_USER_PROPERTY, MuleCredentials.createHeader(user.getUsername(), user.getPassword()));
703 }
704 return new DefaultMuleEvent(message, exchangePattern, session);
705 }
706
707 protected InboundEndpoint getInboundEndpoint(String uri) throws MuleException
708 {
709
710
711
712
713
714
715 InboundEndpoint endpoint = (InboundEndpoint) inboundEndpointCache.get(uri);
716 if (endpoint == null)
717 {
718 endpoint = muleContext.getEndpointFactory().getInboundEndpoint(uri);
719 InboundEndpoint concurrentlyAddedEndpoint = (InboundEndpoint) inboundEndpointCache.putIfAbsent(uri, endpoint);
720 if (concurrentlyAddedEndpoint != null)
721 {
722 return concurrentlyAddedEndpoint;
723 }
724 }
725 return endpoint;
726 }
727
728 protected OutboundEndpoint getOutboundEndpoint(String uri, MessageExchangePattern exchangePattern,
729 Integer responseTimeout) throws MuleException
730 {
731
732
733
734
735
736
737 String key = String.format("%1s:%2s:%3s", uri, exchangePattern, responseTimeout);
738 OutboundEndpoint endpoint = (OutboundEndpoint) outboundEndpointCache.get(key);
739 if (endpoint == null)
740 {
741 EndpointBuilder endpointBuilder =
742 muleContext.getEndpointFactory().getEndpointBuilder(uri);
743 endpointBuilder.setExchangePattern(exchangePattern);
744 if (responseTimeout != null && responseTimeout > 0)
745 {
746 endpointBuilder.setResponseTimeout(responseTimeout.intValue());
747 }
748 endpoint = muleContext.getEndpointFactory().getOutboundEndpoint(endpointBuilder);
749 OutboundEndpoint concurrentlyAddedEndpoint =
750 (OutboundEndpoint) outboundEndpointCache.putIfAbsent(key, endpoint);
751 if (concurrentlyAddedEndpoint != null)
752 {
753 return concurrentlyAddedEndpoint;
754 }
755 }
756 return endpoint;
757 }
758
759 protected InboundEndpoint getDefaultClientEndpoint(Service service, Object payload, boolean sync)
760 throws MuleException
761 {
762 if (!(service.getMessageSource() instanceof ServiceCompositeMessageSource))
763 {
764 throw new IllegalStateException(
765 "Only 'CompositeMessageSource' is supported with MuleClient.sendDirect() and MuleClient.dispatchDirect()");
766 }
767
768
769 InboundEndpoint endpoint = ((ServiceCompositeMessageSource) service.getMessageSource()).getEndpoints().get(0);
770 if (endpoint != null)
771 {
772 if (endpoint.getTransformers() != null)
773 {
774
775
776 if (TransformerUtils.isSourceTypeSupportedByFirst(endpoint.getTransformers(),
777 payload.getClass()))
778 {
779 return endpoint;
780 }
781 else
782 {
783 EndpointBuilder builder = new EndpointURIEndpointBuilder(endpoint);
784 builder.setTransformers(new LinkedList());
785 builder.setExchangePattern(MessageExchangePattern.REQUEST_RESPONSE);
786 return muleContext.getEndpointFactory().getInboundEndpoint(builder);
787 }
788 }
789 else
790 {
791 return endpoint;
792 }
793 }
794 else
795 {
796 EndpointBuilder builder = new EndpointURIEndpointBuilder("vm://mule.client", muleContext);
797 builder.setName("muleClientProvider");
798 endpoint = muleContext.getEndpointFactory().getInboundEndpoint(builder);
799 }
800 return endpoint;
801 }
802
803
804
805
806
807
808
809
810
811
812
813
814
815 public void sendNoReceive(String url, Object payload, Map<String, Object> messageProperties) throws MuleException
816 {
817 if (messageProperties == null)
818 {
819 messageProperties = new HashMap<String, Object>();
820 }
821 messageProperties.put(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, "false");
822 MuleMessage message = new DefaultMuleMessage(payload, messageProperties, muleContext);
823
824 OutboundEndpoint endpoint =
825 getOutboundEndpoint(url, MessageExchangePattern.REQUEST_RESPONSE, null);
826 MuleEvent event = getEvent(message, MessageExchangePattern.REQUEST_RESPONSE);
827 endpoint.process(event);
828 }
829
830
831
832
833
834
835 public MuleContext getMuleContext()
836 {
837 return muleContext;
838 }
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854 @Deprecated
855 public void registerComponent(Object component, String name, EndpointURI listenerEndpoint)
856 throws MuleException
857 {
858 throw new UnsupportedOperationException("registerComponent");
859 }
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876 @Deprecated
877 public void registerComponent(Object component,
878 String name,
879 MuleEndpointURI listenerEndpoint,
880 MuleEndpointURI sendEndpoint) throws MuleException
881 {
882 throw new UnsupportedOperationException("registerComponent");
883 }
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899 @Deprecated
900 public void unregisterComponent(String name) throws MuleException
901 {
902 throw new UnsupportedOperationException("registerComponent");
903 }
904
905 public RemoteDispatcher getRemoteDispatcher(String serverEndpoint) throws MuleException
906 {
907 RemoteDispatcher rd = new RemoteDispatcher(serverEndpoint, muleContext);
908 rd.setExecutor(muleContext.getWorkManager());
909 dispatchers.add(rd);
910 return rd;
911 }
912
913 public RemoteDispatcher getRemoteDispatcher(String serverEndpoint, String user, String password)
914 throws MuleException
915 {
916 RemoteDispatcher rd = new RemoteDispatcher(serverEndpoint, new MuleCredentials(user,
917 password.toCharArray()), muleContext);
918 rd.setExecutor(muleContext.getWorkManager());
919 dispatchers.add(rd);
920 return rd;
921 }
922
923
924
925
926
927 @Override
928 public void dispose()
929 {
930 synchronized (dispatchers)
931 {
932 for (Iterator iterator = dispatchers.iterator(); iterator.hasNext();)
933 {
934 RemoteDispatcher remoteDispatcher = (RemoteDispatcher) iterator.next();
935 remoteDispatcher.dispose();
936 remoteDispatcher = null;
937 }
938 dispatchers.clear();
939 }
940
941
942 if (muleContext.getConfiguration().isClientMode())
943 {
944 logger.info("Stopping Mule...");
945 muleContext.dispose();
946 }
947 }
948
949 public void setProperty(String key, Object value)
950 {
951 try
952 {
953 muleContext.getRegistry().registerObject(key, value);
954 }
955 catch (RegistrationException e)
956 {
957 logger.error(e);
958 }
959 }
960
961 public Object getProperty(String key)
962 {
963 return muleContext.getRegistry().lookupObject(key);
964 }
965
966 public MuleConfiguration getConfiguration()
967 {
968 return muleContext.getConfiguration();
969 }
970 }