1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport;
12
13 import org.mule.MessageExchangePattern;
14 import org.mule.api.MuleContext;
15 import org.mule.api.MuleEvent;
16 import org.mule.api.MuleException;
17 import org.mule.api.MuleMessage;
18 import org.mule.api.MuleRuntimeException;
19 import org.mule.api.config.MuleProperties;
20 import org.mule.api.config.ThreadingProfile;
21 import org.mule.api.construct.FlowConstruct;
22 import org.mule.api.context.WorkManager;
23 import org.mule.api.context.WorkManagerSource;
24 import org.mule.api.context.notification.ServerNotification;
25 import org.mule.api.context.notification.ServerNotificationHandler;
26 import org.mule.api.endpoint.EndpointURI;
27 import org.mule.api.endpoint.ImmutableEndpoint;
28 import org.mule.api.endpoint.InboundEndpoint;
29 import org.mule.api.endpoint.OutboundEndpoint;
30 import org.mule.api.lifecycle.CreateException;
31 import org.mule.api.lifecycle.InitialisationException;
32 import org.mule.api.lifecycle.LifecycleCallback;
33 import org.mule.api.lifecycle.LifecycleException;
34 import org.mule.api.lifecycle.LifecycleState;
35 import org.mule.api.processor.MessageProcessor;
36 import org.mule.api.registry.ServiceException;
37 import org.mule.api.registry.ServiceType;
38 import org.mule.api.retry.RetryCallback;
39 import org.mule.api.retry.RetryContext;
40 import org.mule.api.retry.RetryPolicyTemplate;
41 import org.mule.api.transformer.Transformer;
42 import org.mule.api.transport.Connectable;
43 import org.mule.api.transport.Connector;
44 import org.mule.api.transport.ConnectorException;
45 import org.mule.api.transport.DispatchException;
46 import org.mule.api.transport.MessageDispatcher;
47 import org.mule.api.transport.MessageDispatcherFactory;
48 import org.mule.api.transport.MessageReceiver;
49 import org.mule.api.transport.MessageRequester;
50 import org.mule.api.transport.MessageRequesterFactory;
51 import org.mule.api.transport.MuleMessageFactory;
52 import org.mule.api.transport.ReplyToHandler;
53 import org.mule.api.transport.SessionHandler;
54 import org.mule.config.i18n.CoreMessages;
55 import org.mule.config.i18n.MessageFactory;
56 import org.mule.context.notification.ConnectionNotification;
57 import org.mule.context.notification.EndpointMessageNotification;
58 import org.mule.context.notification.OptimisedNotificationHandler;
59 import org.mule.endpoint.outbound.OutboundNotificationMessageProcessor;
60 import org.mule.model.streaming.DelegatingInputStream;
61 import org.mule.processor.OptionalAsyncInterceptingMessageProcessor;
62 import org.mule.processor.chain.DefaultMessageProcessorChainBuilder;
63 import org.mule.routing.filters.WildcardFilter;
64 import org.mule.session.SerializeAndEncodeSessionHandler;
65 import org.mule.transformer.TransformerUtils;
66 import org.mule.transport.service.TransportFactory;
67 import org.mule.transport.service.TransportServiceDescriptor;
68 import org.mule.transport.service.TransportServiceException;
69 import org.mule.util.ClassUtils;
70 import org.mule.util.CollectionUtils;
71 import org.mule.util.ObjectNameHelper;
72 import org.mule.util.ObjectUtils;
73 import org.mule.util.StringUtils;
74 import org.mule.util.concurrent.NamedThreadFactory;
75 import org.mule.util.concurrent.ThreadNameHelper;
76
77 import java.io.IOException;
78 import java.io.InputStream;
79 import java.io.OutputStream;
80 import java.text.MessageFormat;
81 import java.util.ArrayList;
82 import java.util.Collections;
83 import java.util.Iterator;
84 import java.util.List;
85 import java.util.Map;
86 import java.util.Properties;
87
88 import javax.resource.spi.work.WorkEvent;
89 import javax.resource.spi.work.WorkListener;
90
91 import edu.emory.mathcs.backport.java.util.concurrent.ConcurrentHashMap;
92 import edu.emory.mathcs.backport.java.util.concurrent.ScheduledExecutorService;
93 import edu.emory.mathcs.backport.java.util.concurrent.ScheduledThreadPoolExecutor;
94 import edu.emory.mathcs.backport.java.util.concurrent.ThreadFactory;
95 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
96 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicBoolean;
97 import edu.emory.mathcs.backport.java.util.concurrent.atomic.AtomicReference;
98 import org.apache.commons.logging.Log;
99 import org.apache.commons.logging.LogFactory;
100 import org.apache.commons.pool.KeyedPoolableObjectFactory;
101 import org.apache.commons.pool.impl.GenericKeyedObjectPool;
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129 public abstract class AbstractConnector implements Connector, WorkListener
130 {
131
132
133
134 public static final int DEFAULT_NUM_CONCURRENT_TX_RECEIVERS = 4;
135
136 private static final long SCHEDULER_FORCED_SHUTDOWN_TIMEOUT = 5000l;
137
138 public static final String PROPERTY_POLLING_FREQUENCY = "pollingFrequency";
139
140
141
142
143 protected final Log logger = LogFactory.getLog(getClass());
144
145
146
147
148 protected volatile String name;
149
150
151
152
153 protected volatile MessageDispatcherFactory dispatcherFactory;
154
155
156
157
158 protected volatile MessageRequesterFactory requesterFactory;
159
160
161
162
163 protected MuleMessageFactory muleMessageFactory;
164
165
166
167
168 protected volatile ConfigurableKeyedObjectPool dispatchers;
169
170
171
172
173 protected volatile ConfigurableKeyedObjectPoolFactory dispatcherPoolFactory;
174
175
176
177
178 protected final GenericKeyedObjectPool requesters = new GenericKeyedObjectPool();
179
180
181
182
183 @SuppressWarnings("unchecked")
184 protected final Map<Object, MessageReceiver> receivers = new ConcurrentHashMap
185
186
187
188
189 private volatile ThreadingProfile dispatcherThreadingProfile;
190
191
192
193
194 private volatile ThreadingProfile requesterThreadingProfile;
195
196
197
198
199 private volatile ThreadingProfile receiverThreadingProfile;
200
201
202
203
204 protected volatile boolean createMultipleTransactedReceivers = true;
205
206
207
208
209 protected volatile int numberOfConcurrentTransactedReceivers = DEFAULT_NUM_CONCURRENT_TX_RECEIVERS;
210
211 private RetryPolicyTemplate retryPolicyTemplate;
212
213
214
215
216
217
218 private boolean dynamicNotification = false;
219 private ServerNotificationHandler cachedNotificationHandler;
220
221 private final List<String> supportedProtocols;
222
223
224
225
226 private final AtomicReference
227
228
229
230
231 private final AtomicReference
232
233
234
235
236 private final AtomicReference
237
238
239
240
241 private ScheduledExecutorService scheduler;
242
243
244
245
246 protected volatile TransportServiceDescriptor serviceDescriptor;
247
248
249
250
251
252 protected volatile Properties serviceOverrides;
253
254
255
256
257
258 protected volatile SessionHandler sessionHandler = new SerializeAndEncodeSessionHandler();
259
260 protected MuleContext muleContext;
261
262 protected ConnectorLifecycleManager lifecycleManager;
263
264
265 protected AtomicBoolean connected = new AtomicBoolean(false);
266
267
268
269
270
271
272 protected boolean startOnConnect = false;
273
274
275
276
277
278
279
280
281
282 protected boolean initialStateStopped = false;
283
284
285
286 private boolean validateConnections = true;
287
288 public AbstractConnector(MuleContext context)
289 {
290 muleContext = context;
291 lifecycleManager = new ConnectorLifecycleManager(this);
292
293 setDynamicNotification(false);
294 updateCachedNotificationHandler();
295
296
297 supportedProtocols = new ArrayList<String>();
298 supportedProtocols.add(getProtocol().toLowerCase());
299
300
301
302
303
304
305 requesters.setTestOnBorrow(false);
306 requesters.setTestOnReturn(true);
307 }
308
309 public String getName()
310 {
311 return name;
312 }
313
314 public void setName(String newName)
315 {
316 if (newName == null)
317 {
318 throw new IllegalArgumentException(CoreMessages.objectIsNull("Connector name").toString());
319 }
320
321 if (logger.isDebugEnabled())
322 {
323 logger.debug("Set Connector name to: " + newName);
324 }
325
326 name = newName;
327 }
328
329
330
331
332
333 ConnectorLifecycleManager getLifecycleManager()
334 {
335 return lifecycleManager;
336 }
337
338 public LifecycleState getLifecycleState()
339 {
340 return lifecycleManager.getState();
341 }
342
343 public final synchronized void initialise() throws InitialisationException
344 {
345 try
346 {
347 lifecycleManager.fireInitialisePhase(new LifecycleCallback<Connector>()
348 {
349 public void onTransition(String phaseName, Connector object) throws MuleException
350 {
351 if (retryPolicyTemplate == null)
352 {
353 retryPolicyTemplate = (RetryPolicyTemplate) muleContext.getRegistry().lookupObject(
354 MuleProperties.OBJECT_DEFAULT_RETRY_POLICY_TEMPLATE);
355 }
356
357 if (dispatcherPoolFactory == null) {
358 dispatcherPoolFactory = new DefaultConfigurableKeyedObjectPoolFactory();
359 }
360
361 dispatchers = dispatcherPoolFactory.createObjectPool();
362 if (dispatcherFactory != null) {
363 dispatchers.setFactory(getWrappedDispatcherFactory(dispatcherFactory));
364 }
365
366
367 initFromServiceDescriptor();
368
369 configureDispatcherPool();
370 setMaxRequestersActive(getRequesterThreadingProfile().getMaxThreadsActive());
371
372 doInitialise();
373
374 try
375 {
376 initWorkManagers();
377 }
378 catch (MuleException e)
379 {
380 throw new LifecycleException(e, this);
381 }
382 }
383 });
384 }
385 catch (InitialisationException e)
386 {
387 throw e;
388 }
389 catch (LifecycleException e)
390 {
391 throw new InitialisationException(e, this);
392 }
393 catch (MuleException e)
394 {
395 e.printStackTrace();
396 }
397 }
398
399 public final synchronized void start() throws MuleException
400 {
401 if (isInitialStateStopped())
402 {
403 logger.info("Connector not started because 'initialStateStopped' is true");
404 return;
405 }
406
407 lifecycleManager.fireStartPhase(new LifecycleCallback<Connector>()
408 {
409 public void onTransition(String phaseName, Connector object) throws MuleException
410 {
411
412
413 if (!isConnected())
414 {
415 startOnConnect = true;
416
417
418 try
419 {
420 connect();
421 }
422 catch (Exception e)
423 {
424 throw new LifecycleException(e, this);
425 }
426 }
427 else
428 {
429
430 startAfterConnect();
431 }
432 }
433 });
434
435 }
436
437 protected synchronized void startAfterConnect() throws MuleException
438 {
439 if (logger.isInfoEnabled())
440 {
441 logger.info("Starting: " + this);
442 }
443
444
445 scheduler = createScheduler();
446
447 try
448 {
449 initWorkManagers();
450 }
451 catch (MuleException e)
452 {
453 throw new InitialisationException(e, this);
454 }
455
456 if (!isStarted())
457 {
458 doStart();
459 }
460
461 if (receivers != null)
462 {
463 for (MessageReceiver receiver : receivers.values())
464 {
465 final List<MuleException> errors = new ArrayList<MuleException>();
466 try
467 {
468 if (logger.isDebugEnabled())
469 {
470 logger.debug("Starting receiver on endpoint: "
471 + receiver.getEndpoint().getEndpointURI());
472 }
473 if (receiver.getFlowConstruct().getLifecycleState().isStarted())
474 {
475 receiver.start();
476 }
477 }
478 catch (MuleException e)
479 {
480 logger.error(e);
481 errors.add(e);
482 }
483
484 if (!errors.isEmpty())
485 {
486
487
488
489
490
491 throw errors.get(0);
492 }
493 }
494 }
495
496 }
497
498
499 public final synchronized void stop() throws MuleException
500 {
501 lifecycleManager.fireStopPhase(new LifecycleCallback<Connector>()
502 {
503 public void onTransition(String phaseName, Connector object) throws MuleException
504 {
505
506 shutdownScheduler();
507
508 doStop();
509
510
511
512 if (receivers != null)
513 {
514 for (MessageReceiver receiver : receivers.values())
515 {
516 if (logger.isDebugEnabled())
517 {
518 logger.debug("Stopping receiver on endpoint: " + receiver.getEndpoint().getEndpointURI());
519 }
520 receiver.stop();
521 }
522 }
523
524 if (isConnected())
525 {
526 try
527 {
528 disconnect();
529 }
530 catch (Exception e)
531 {
532
533
534
535 logger.error("Failed to disconnect: " + e.getMessage(), e);
536 }
537 }
538
539
540
541 disposeWorkManagers();
542
543
544 clearDispatchers();
545 clearRequesters();
546
547
548 scheduler = null;
549 }
550 });
551 }
552
553 public final synchronized void dispose()
554 {
555 try
556 {
557 if (lifecycleManager.getState().isStarted())
558 {
559 stop();
560 }
561 lifecycleManager.fireDisposePhase(new LifecycleCallback<Connector>()
562 {
563 public void onTransition(String phaseName, Connector object) throws MuleException
564 {
565 doDispose();
566 disposeReceivers();
567 }
568 });
569 }
570 catch (MuleException e)
571 {
572 logger.warn("Failed to dispose connector: " + name, e);
573 }
574 }
575
576 public final boolean isStarted()
577 {
578 return lifecycleManager.getState().isStarted();
579 }
580
581 public boolean isInitialised()
582 {
583 return lifecycleManager.getState().isInitialised();
584 }
585
586 public boolean isStopped()
587 {
588 return lifecycleManager.getState().isStopped();
589 }
590
591
592
593
594
595
596 protected void configureDispatcherPool()
597 {
598
599
600 int maxDispatchersActive = getDispatcherThreadingProfile().getMaxThreadsActive();
601
602
603
604
605
606
607 if (ThreadingProfile.WHEN_EXHAUSTED_RUN == getDispatcherThreadingProfile().getPoolExhaustedAction())
608 {
609 maxDispatchersActive++;
610 }
611 setMaxDispatchersActive(maxDispatchersActive);
612 }
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627 public MuleMessageFactory createMuleMessageFactory() throws CreateException
628 {
629 try
630 {
631 return serviceDescriptor.createMuleMessageFactory();
632 }
633 catch (TransportServiceException tse)
634 {
635 throw new CreateException(CoreMessages.failedToCreate("MuleMessageFactory"), tse, this);
636 }
637 }
638
639 protected void shutdownScheduler()
640 {
641 if (scheduler != null)
642 {
643
644 scheduler.shutdown();
645 try
646 {
647
648 if (!scheduler.awaitTermination(muleContext.getConfiguration().getShutdownTimeout(),
649 TimeUnit.MILLISECONDS))
650 {
651
652
653 List outstanding = scheduler.shutdownNow();
654
655 if (!scheduler.awaitTermination(SCHEDULER_FORCED_SHUTDOWN_TIMEOUT, TimeUnit.MILLISECONDS))
656 {
657 logger.warn(MessageFormat.format(
658 "Pool {0} did not terminate in time; {1} work items were cancelled.", name,
659 outstanding.isEmpty() ? "No" : Integer.toString(outstanding.size())));
660 }
661 else
662 {
663 if (!outstanding.isEmpty())
664 {
665 logger.warn(MessageFormat.format(
666 "Pool {0} terminated; {1} work items were cancelled.", name,
667 Integer.toString(outstanding.size())));
668 }
669 }
670
671 }
672 }
673 catch (InterruptedException ie)
674 {
675
676 scheduler.shutdownNow();
677
678 Thread.currentThread().interrupt();
679 }
680 finally
681 {
682 scheduler = null;
683 }
684 }
685 }
686
687 protected void initWorkManagers() throws MuleException
688 {
689 if (receiverWorkManager.get() == null)
690 {
691
692 final String threadPrefix = ThreadNameHelper.receiver(muleContext, getName());
693 WorkManager newWorkManager = this.getReceiverThreadingProfile().createWorkManager(
694 threadPrefix, muleContext.getConfiguration().getShutdownTimeout());
695
696 if (receiverWorkManager.compareAndSet(null, newWorkManager))
697 {
698 newWorkManager.start();
699 }
700 }
701 if (dispatcherWorkManager.get() == null)
702 {
703 ThreadingProfile dispatcherThreadingProfile = this.getDispatcherThreadingProfile();
704 if (dispatcherThreadingProfile.getMuleContext() == null)
705 {
706 dispatcherThreadingProfile.setMuleContext(muleContext);
707 }
708
709 final String threadPrefix = ThreadNameHelper.dispatcher(muleContext, getName());
710 WorkManager newWorkManager = dispatcherThreadingProfile.createWorkManager(
711 threadPrefix, muleContext.getConfiguration().getShutdownTimeout());
712
713 if (dispatcherWorkManager.compareAndSet(null, newWorkManager))
714 {
715 newWorkManager.start();
716 }
717 }
718 if (requesterWorkManager.get() == null)
719 {
720 final String threadPrefix = ThreadNameHelper.requester(muleContext, getName());
721 WorkManager newWorkManager = this.getRequesterThreadingProfile().createWorkManager(
722 threadPrefix, muleContext.getConfiguration().getShutdownTimeout());
723
724 if (requesterWorkManager.compareAndSet(null, newWorkManager))
725 {
726 newWorkManager.start();
727 }
728 }
729 }
730
731 protected void disposeWorkManagers()
732 {
733 WorkManager workManager;
734
735 logger.debug("Disposing dispatcher work manager");
736 workManager = (WorkManager) dispatcherWorkManager.get();
737 if (workManager != null)
738 {
739 workManager.dispose();
740 }
741 dispatcherWorkManager.set(null);
742
743 logger.debug("Disposing requester work manager");
744 workManager = (WorkManager) requesterWorkManager.get();
745 if (workManager != null)
746 {
747 workManager.dispose();
748 }
749 requesterWorkManager.set(null);
750
751 logger.debug("Disposing receiver work manager");
752 workManager = (WorkManager) receiverWorkManager.get();
753 if (workManager != null)
754 {
755 workManager.dispose();
756 }
757 receiverWorkManager.set(null);
758 }
759
760 protected void disposeReceivers()
761 {
762 if (receivers != null)
763 {
764 logger.debug("Disposing Receivers");
765
766 for (MessageReceiver receiver : receivers.values())
767 {
768 try
769 {
770 this.destroyReceiver(receiver, receiver.getEndpoint());
771 }
772 catch (Throwable e)
773 {
774
775 logger.error("Failed to destroy receiver: " + receiver, e);
776 }
777 }
778
779 receivers.clear();
780 logger.debug("Receivers Disposed");
781 }
782 }
783
784 protected void clearDispatchers()
785 {
786 if (dispatchers != null)
787 {
788 logger.debug("Clearing Dispatcher pool");
789 synchronized (dispatchers)
790 {
791 dispatchers.clear();
792 }
793 logger.debug("Dispatcher pool cleared");
794 }
795 }
796
797 protected void clearRequesters()
798 {
799 if (requesters != null)
800 {
801 logger.debug("Clearing Requester pool");
802 requesters.clear();
803 logger.debug("Requester pool cleared");
804 }
805 }
806
807 public boolean isDisposed()
808 {
809 return lifecycleManager.getState().isDisposed();
810 }
811
812 public void handleException(Exception exception)
813 {
814 muleContext.getExceptionListener().handleException(exception);
815 }
816
817 public void exceptionThrown(Exception e)
818 {
819 handleException(e);
820 }
821
822
823
824
825 public MessageDispatcherFactory getDispatcherFactory()
826 {
827 return dispatcherFactory;
828 }
829
830
831
832
833 public void setDispatcherFactory(MessageDispatcherFactory dispatcherFactory)
834 {
835 KeyedPoolableObjectFactory poolFactory = getWrappedDispatcherFactory(dispatcherFactory);
836
837 if (dispatchers != null) {
838 this.dispatchers.setFactory(poolFactory);
839 }
840
841
842
843 this.dispatcherFactory = dispatcherFactory;
844 }
845
846 private KeyedPoolableObjectFactory getWrappedDispatcherFactory(MessageDispatcherFactory dispatcherFactory)
847 {
848 KeyedPoolableObjectFactory poolFactory;
849 if (dispatcherFactory instanceof KeyedPoolableObjectFactory)
850 {
851 poolFactory = (KeyedPoolableObjectFactory) dispatcherFactory;
852 }
853 else
854 {
855
856 poolFactory = new KeyedPoolMessageDispatcherFactoryAdapter(dispatcherFactory);
857 }
858
859 return poolFactory;
860 }
861
862
863
864
865 public MessageRequesterFactory getRequesterFactory()
866 {
867 return requesterFactory;
868 }
869
870
871
872
873 public void setRequesterFactory(MessageRequesterFactory requesterFactory)
874 {
875 KeyedPoolableObjectFactory poolFactory;
876
877 if (requesterFactory instanceof KeyedPoolableObjectFactory)
878 {
879 poolFactory = (KeyedPoolableObjectFactory) requesterFactory;
880 }
881 else
882 {
883
884 poolFactory = new KeyedPoolMessageRequesterFactoryAdapter(requesterFactory);
885 }
886
887 requesters.setFactory(poolFactory);
888
889
890
891 this.requesterFactory = requesterFactory;
892 }
893
894
895
896
897
898
899
900
901 public MuleMessageFactory getMuleMessageFactory() throws CreateException
902 {
903 if (muleMessageFactory == null)
904 {
905 muleMessageFactory = createMuleMessageFactory();
906 }
907 return muleMessageFactory;
908 }
909
910
911
912
913
914
915
916
917
918
919
920
921
922 public boolean isInitialStateStopped()
923 {
924 return initialStateStopped;
925 }
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942 public void setInitialStateStopped(boolean initialStateStopped)
943 {
944 this.initialStateStopped = initialStateStopped;
945 }
946
947
948
949
950
951
952
953 public int getMaxDispatchersActive()
954 {
955 checkDispatchersInitialised();
956 return this.dispatchers.getMaxActive();
957 }
958
959
960
961
962
963 private void checkDispatchersInitialised()
964 {
965 if (dispatchers == null)
966 {
967 throw new IllegalStateException("Dispatchers pool was not initialised");
968 }
969 }
970
971
972
973
974
975
976
977 public int getMaxTotalDispatchers()
978 {
979 checkDispatchersInitialised();
980 return this.dispatchers.getMaxTotal();
981 }
982
983
984
985
986
987
988
989 public void setMaxDispatchersActive(int maxActive)
990 {
991 checkDispatchersInitialised();
992 this.dispatchers.setMaxActive(maxActive);
993
994 this.dispatchers.setMaxIdle(maxActive);
995
996
997 this.dispatchers.setMaxTotal(20 * maxActive);
998 }
999
1000 private MessageDispatcher getDispatcher(OutboundEndpoint endpoint) throws MuleException
1001 {
1002 if (!isStarted())
1003 {
1004 throw new LifecycleException(CoreMessages.lifecycleErrorCannotUseConnector(getName(),
1005 lifecycleManager.getCurrentPhase()), this);
1006 }
1007
1008 if (endpoint == null)
1009 {
1010 throw new IllegalArgumentException("Endpoint must not be null");
1011 }
1012
1013 if (!supportsProtocol(endpoint.getConnector().getProtocol()))
1014 {
1015 throw new IllegalArgumentException(CoreMessages.connectorSchemeIncompatibleWithEndpointScheme(
1016 this.getProtocol(), endpoint.getEndpointURI().toString()).getMessage());
1017 }
1018
1019 MessageDispatcher dispatcher = null;
1020 try
1021 {
1022 if (logger.isDebugEnabled())
1023 {
1024 logger.debug("Borrowing a dispatcher for endpoint: " + endpoint.getEndpointURI());
1025 }
1026
1027 dispatcher = (MessageDispatcher) dispatchers.borrowObject(endpoint);
1028
1029 if (logger.isDebugEnabled())
1030 {
1031 logger.debug("Borrowed a dispatcher for endpoint: " + endpoint.getEndpointURI() + " = "
1032 + dispatcher.toString());
1033 }
1034
1035 return dispatcher;
1036 }
1037 catch (Exception ex)
1038 {
1039 throw new ConnectorException(CoreMessages.connectorCausedError(), this, ex);
1040 }
1041 finally
1042 {
1043 try
1044 {
1045 if (logger.isDebugEnabled())
1046 {
1047 logger.debug("Borrowed dispatcher: " + ObjectUtils.toString(dispatcher, "null"));
1048 }
1049 }
1050 catch (Exception ex)
1051 {
1052 throw new ConnectorException(CoreMessages.connectorCausedError(), this, ex);
1053 }
1054 }
1055 }
1056
1057 private void returnDispatcher(OutboundEndpoint endpoint, MessageDispatcher dispatcher)
1058 {
1059 if (endpoint != null && dispatcher != null)
1060 {
1061 if (logger.isDebugEnabled())
1062 {
1063 logger.debug("Returning dispatcher for endpoint: " + endpoint.getEndpointURI() + " = "
1064 + dispatcher.toString());
1065 }
1066
1067 try
1068 {
1069 dispatchers.returnObject(endpoint, dispatcher);
1070 }
1071 catch (Exception e)
1072 {
1073
1074
1075 logger.error("Failed to dispose dispatcher for endpoint: " + endpoint
1076 + ". This will cause a memory leak. Please report to", e);
1077 }
1078
1079 }
1080 }
1081
1082
1083
1084
1085
1086
1087
1088 public int getMaxRequestersActive()
1089 {
1090 return this.requesters.getMaxActive();
1091 }
1092
1093
1094
1095
1096
1097
1098
1099 public void setMaxRequestersActive(int maxActive)
1100 {
1101 this.requesters.setMaxActive(maxActive);
1102
1103 this.requesters.setMaxIdle(maxActive);
1104
1105
1106 this.requesters.setMaxTotal(20 * maxActive);
1107 }
1108
1109 private MessageRequester getRequester(InboundEndpoint endpoint) throws MuleException
1110 {
1111 if (!isStarted())
1112 {
1113 throw new LifecycleException(CoreMessages.lifecycleErrorCannotUseConnector(getName(),
1114 lifecycleManager.getCurrentPhase()), this);
1115 }
1116
1117 if (endpoint == null)
1118 {
1119 throw new IllegalArgumentException("Endpoint must not be null");
1120 }
1121
1122 if (!supportsProtocol(endpoint.getConnector().getProtocol()))
1123 {
1124 throw new IllegalArgumentException(CoreMessages.connectorSchemeIncompatibleWithEndpointScheme(
1125 this.getProtocol(), endpoint.getEndpointURI().toString()).getMessage());
1126 }
1127
1128 MessageRequester requester = null;
1129 try
1130 {
1131 if (logger.isDebugEnabled())
1132 {
1133 logger.debug("Borrowing a requester for endpoint: " + endpoint.getEndpointURI());
1134 }
1135
1136 requester = (MessageRequester) requesters.borrowObject(endpoint);
1137
1138 if (logger.isDebugEnabled())
1139 {
1140 logger.debug("Borrowed a requester for endpoint: " + endpoint.getEndpointURI() + " = "
1141 + requester.toString());
1142 }
1143
1144 return requester;
1145 }
1146 catch (Exception ex)
1147 {
1148 throw new ConnectorException(CoreMessages.connectorCausedError(), this, ex);
1149 }
1150 finally
1151 {
1152 try
1153 {
1154 if (logger.isDebugEnabled())
1155 {
1156 logger.debug("Borrowed requester: " + ObjectUtils.toString(requester, "null"));
1157 }
1158 }
1159 catch (Exception ex)
1160 {
1161 throw new ConnectorException(CoreMessages.connectorCausedError(), this, ex);
1162 }
1163 }
1164 }
1165
1166 private void returnRequester(InboundEndpoint endpoint, MessageRequester requester)
1167 {
1168 if (endpoint != null && requester != null)
1169 {
1170 if (logger.isDebugEnabled())
1171 {
1172 logger.debug("Returning requester for endpoint: " + endpoint.getEndpointURI() + " = "
1173 + requester.toString());
1174 }
1175
1176 try
1177 {
1178 requesters.returnObject(endpoint, requester);
1179 }
1180 catch (Exception e)
1181 {
1182
1183
1184 logger.error("Failed to dispose requester for endpoint: " + endpoint
1185 + ". This will cause a memory leak. Please report to", e);
1186 }
1187 }
1188
1189 }
1190
1191 public void registerListener(InboundEndpoint endpoint,
1192 MessageProcessor messageProcessorChain,
1193 FlowConstruct flowConstruct) throws Exception
1194 {
1195 if (endpoint == null)
1196 {
1197 throw new IllegalArgumentException("The endpoint cannot be null when registering a listener");
1198 }
1199
1200 if (messageProcessorChain == null)
1201 {
1202 throw new IllegalArgumentException("The messageProcessorChain cannot be null when registering a listener");
1203 }
1204
1205 EndpointURI endpointUri = endpoint.getEndpointURI();
1206 if (endpointUri == null)
1207 {
1208 throw new ConnectorException(CoreMessages.endpointIsNullForListener(), this);
1209 }
1210
1211 logger.info("Registering listener: " + flowConstruct.getName() + " on endpointUri: "
1212 + endpointUri.toString());
1213
1214 if (getReceiver(flowConstruct, endpoint) != null)
1215 {
1216 throw new ConnectorException(CoreMessages.listenerAlreadyRegistered(endpointUri), this);
1217 }
1218
1219 MessageReceiver receiver = createReceiver(flowConstruct, endpoint);
1220 receiver.setListener(messageProcessorChain);
1221
1222 Object receiverKey = getReceiverKey(flowConstruct, endpoint);
1223 receiver.setReceiverKey(receiverKey.toString());
1224
1225 receiver.initialise();
1226 receivers.put(receiverKey, receiver);
1227
1228 if (isConnected())
1229 {
1230 receiver.connect();
1231 }
1232
1233 if (isStarted())
1234 {
1235 receiver.start();
1236 }
1237 }
1238
1239
1240
1241
1242
1243
1244
1245
1246 protected Object getReceiverKey(FlowConstruct flowConstruct, InboundEndpoint endpoint)
1247 {
1248 return StringUtils.defaultIfEmpty(endpoint.getEndpointURI().getFilterAddress(),
1249 endpoint.getEndpointURI().getAddress());
1250 }
1251
1252 public final void unregisterListener(InboundEndpoint endpoint, FlowConstruct flowConstruct) throws Exception
1253 {
1254 if (endpoint == null)
1255 {
1256 throw new IllegalArgumentException("The endpoint must not be null when you unregister a listener");
1257 }
1258
1259 EndpointURI endpointUri = endpoint.getEndpointURI();
1260 if (endpointUri == null)
1261 {
1262 throw new IllegalArgumentException(
1263 "The endpointUri must not be null when you unregister a listener");
1264 }
1265
1266 if (logger.isInfoEnabled())
1267 {
1268 logger.info("Removing listener on endpointUri: " + endpointUri);
1269 }
1270
1271 if (receivers != null && !receivers.isEmpty())
1272 {
1273 MessageReceiver receiver = receivers.remove(getReceiverKey(flowConstruct, endpoint));
1274 if (receiver != null)
1275 {
1276 if (isConnected())
1277 {
1278 receiver.disconnect();
1279 }
1280
1281 if (isStarted())
1282 {
1283 receiver.stop();
1284 }
1285 destroyReceiver(receiver, endpoint);
1286 doUnregisterListener(flowConstruct, endpoint, receiver);
1287 }
1288 }
1289 }
1290
1291 protected void doUnregisterListener(FlowConstruct flowConstruct, InboundEndpoint endpoint, MessageReceiver receiver)
1292 {
1293
1294 }
1295
1296
1297
1298
1299
1300
1301 public ThreadingProfile getDispatcherThreadingProfile()
1302 {
1303 if (dispatcherThreadingProfile == null && muleContext != null)
1304 {
1305 dispatcherThreadingProfile = muleContext.getDefaultMessageDispatcherThreadingProfile();
1306 }
1307 return dispatcherThreadingProfile;
1308 }
1309
1310
1311
1312
1313
1314
1315
1316 public void setDispatcherThreadingProfile(ThreadingProfile dispatcherThreadingProfile)
1317 {
1318 this.dispatcherThreadingProfile = dispatcherThreadingProfile;
1319 }
1320
1321
1322
1323
1324
1325
1326 public ThreadingProfile getRequesterThreadingProfile()
1327 {
1328 if (requesterThreadingProfile == null && muleContext != null)
1329 {
1330 requesterThreadingProfile = muleContext.getDefaultMessageRequesterThreadingProfile();
1331 }
1332 return requesterThreadingProfile;
1333 }
1334
1335
1336
1337
1338
1339
1340
1341 public void setRequesterThreadingProfile(ThreadingProfile requesterThreadingProfile)
1342 {
1343 this.requesterThreadingProfile = requesterThreadingProfile;
1344 }
1345
1346
1347
1348
1349
1350
1351 public ThreadingProfile getReceiverThreadingProfile()
1352 {
1353 if (receiverThreadingProfile == null && muleContext != null)
1354 {
1355 receiverThreadingProfile = muleContext.getDefaultMessageReceiverThreadingProfile();
1356 }
1357 return receiverThreadingProfile;
1358 }
1359
1360
1361
1362
1363
1364
1365
1366 public void setReceiverThreadingProfile(ThreadingProfile receiverThreadingProfile)
1367 {
1368 this.receiverThreadingProfile = receiverThreadingProfile;
1369 }
1370
1371 public void destroyReceiver(MessageReceiver receiver, ImmutableEndpoint endpoint) throws Exception
1372 {
1373 receiver.dispose();
1374 }
1375
1376 protected abstract void doInitialise() throws InitialisationException;
1377
1378
1379
1380
1381 protected abstract void doDispose();
1382
1383
1384
1385
1386
1387
1388 protected abstract void doStart() throws MuleException;
1389
1390
1391
1392
1393
1394
1395 protected abstract void doStop() throws MuleException;
1396
1397 public List<Transformer> getDefaultInboundTransformers(ImmutableEndpoint endpoint)
1398 {
1399 if (serviceDescriptor == null)
1400 {
1401 throw new RuntimeException("serviceDescriptor not initialized");
1402 }
1403 return TransformerUtils.getDefaultInboundTransformers(serviceDescriptor, endpoint);
1404 }
1405
1406 public List<Transformer> getDefaultResponseTransformers(ImmutableEndpoint endpoint)
1407 {
1408 if (serviceDescriptor == null)
1409 {
1410 throw new RuntimeException("serviceDescriptor not initialized");
1411 }
1412 return TransformerUtils.getDefaultResponseTransformers(serviceDescriptor, endpoint);
1413 }
1414
1415 public List<Transformer> getDefaultOutboundTransformers(ImmutableEndpoint endpoint)
1416 {
1417 if (serviceDescriptor == null)
1418 {
1419 throw new RuntimeException("serviceDescriptor not initialized");
1420 }
1421 return TransformerUtils.getDefaultOutboundTransformers(serviceDescriptor, endpoint);
1422 }
1423
1424
1425
1426
1427
1428
1429 public ReplyToHandler getReplyToHandler(ImmutableEndpoint endpoint)
1430 {
1431 return new DefaultReplyToHandler(getDefaultResponseTransformers(endpoint), muleContext);
1432 }
1433
1434
1435
1436
1437
1438
1439 public void fireNotification(ServerNotification notification)
1440 {
1441 cachedNotificationHandler.fireNotification(notification);
1442 }
1443
1444 public boolean isResponseEnabled()
1445 {
1446 return false;
1447 }
1448
1449 public MessageReceiver getReceiver(FlowConstruct flowConstruct, InboundEndpoint endpoint)
1450 {
1451 if (receivers != null)
1452 {
1453 Object key = getReceiverKey(flowConstruct, endpoint);
1454 if (key != null)
1455 {
1456 return receivers.get(key);
1457 }
1458 else
1459 {
1460 throw new RuntimeException("getReceiverKey() returned a null key");
1461 }
1462 }
1463 else
1464 {
1465 throw new RuntimeException("Connector has not been initialized.");
1466 }
1467 }
1468
1469
1470
1471
1472
1473
1474 public Map<Object, MessageReceiver> getReceivers()
1475 {
1476 return Collections.unmodifiableMap(receivers);
1477 }
1478
1479 public MessageReceiver lookupReceiver(String key)
1480 {
1481 if (key != null)
1482 {
1483 return receivers.get(key);
1484 }
1485 else
1486 {
1487 throw new IllegalArgumentException("Receiver key must not be null");
1488 }
1489 }
1490
1491 public MessageReceiver[] getReceivers(String wildcardExpression)
1492 {
1493 WildcardFilter filter = new WildcardFilter(wildcardExpression);
1494 filter.setCaseSensitive(false);
1495
1496 List<MessageReceiver> found = new ArrayList<MessageReceiver>();
1497
1498 for (Map.Entry<Object, MessageReceiver> e : receivers.entrySet())
1499 {
1500 if (filter.accept(e.getKey()))
1501 {
1502 found.add(e.getValue());
1503 }
1504 }
1505
1506 return CollectionUtils.toArrayOfComponentType(found, MessageReceiver.class);
1507 }
1508
1509 public void connect() throws Exception
1510 {
1511 if (lifecycleManager.getState().isDisposed())
1512 {
1513 throw new LifecycleException(CoreMessages.lifecycleErrorCannotUseConnector(getName(),
1514 lifecycleManager.getCurrentPhase()), this);
1515 }
1516
1517 if (isConnected())
1518 {
1519 return;
1520 }
1521
1522 if (logger.isDebugEnabled())
1523 {
1524 logger.debug("Connecting: " + this);
1525 }
1526
1527 RetryCallback callback = new RetryCallback()
1528 {
1529 public void doWork(RetryContext context) throws Exception
1530 {
1531
1532 if (validateConnections && context.getLastFailure() instanceof ConnectException)
1533 {
1534 Connectable failed = ((ConnectException) context.getLastFailure()).getFailed();
1535 if (!failed.validateConnection(context).isOk())
1536 {
1537 throw new ConnectException(
1538 MessageFactory.createStaticMessage("Still unable to connect to resource " + failed.getClass().getName()),
1539 context.getLastFailure(), failed);
1540 }
1541 }
1542 doConnect();
1543 setConnected(true);
1544
1545 logger.info("Connected: " + getWorkDescription());
1546
1547 if (startOnConnect)
1548 {
1549 startAfterConnect();
1550 }
1551 }
1552
1553 public String getWorkDescription()
1554 {
1555 return getConnectionDescription();
1556 }
1557 };
1558
1559 retryPolicyTemplate.execute(callback, muleContext.getWorkManager());
1560 }
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571 public RetryContext validateConnection(RetryContext retryContext)
1572 {
1573 retryContext.setOk();
1574 return retryContext;
1575 }
1576
1577 public void disconnect() throws Exception
1578 {
1579 startOnConnect = isStarted();
1580
1581 try
1582 {
1583 if (receivers != null)
1584 {
1585 for (MessageReceiver receiver : receivers.values())
1586 {
1587 if (logger.isDebugEnabled())
1588 {
1589 logger.debug("Disconnecting receiver on endpoint: "
1590 + receiver.getEndpoint().getEndpointURI());
1591 }
1592 receiver.disconnect();
1593 }
1594 }
1595 this.doDisconnect();
1596 }
1597 finally
1598 {
1599 if (receivers != null)
1600 {
1601 for (MessageReceiver receiver : receivers.values())
1602 {
1603
1604 if (receiver instanceof AbstractMessageReceiver
1605 && ((AbstractMessageReceiver) receiver).isStarted())
1606 {
1607 if (logger.isDebugEnabled())
1608 {
1609 logger.debug("Stopping receiver on endpoint: "
1610 + receiver.getEndpoint().getEndpointURI());
1611 }
1612 receiver.stop();
1613 }
1614 }
1615 }
1616 }
1617
1618 connected.set(false);
1619 if (logger.isInfoEnabled())
1620 {
1621 logger.info("Disconnected: " + this.getConnectionDescription());
1622 }
1623 this.fireNotification(new ConnectionNotification(this, getConnectEventId(),
1624 ConnectionNotification.CONNECTION_DISCONNECTED));
1625 }
1626
1627 public String getConnectionDescription()
1628 {
1629 return this.toString();
1630 }
1631
1632 public final boolean isConnected()
1633 {
1634 return connected.get();
1635 }
1636
1637 public final void setConnected(boolean flag)
1638 {
1639 connected.set(flag);
1640 }
1641
1642
1643
1644
1645
1646
1647 protected abstract void doConnect() throws Exception;
1648
1649
1650
1651
1652
1653
1654
1655 protected abstract void doDisconnect() throws Exception;
1656
1657
1658
1659
1660
1661
1662 protected String getConnectEventId()
1663 {
1664 return getName();
1665 }
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676 public boolean isCreateMultipleTransactedReceivers()
1677 {
1678 return createMultipleTransactedReceivers;
1679 }
1680
1681
1682
1683
1684
1685
1686
1687 public void setCreateMultipleTransactedReceivers(boolean createMultipleTransactedReceivers)
1688 {
1689 this.createMultipleTransactedReceivers = createMultipleTransactedReceivers;
1690 }
1691
1692
1693
1694
1695
1696
1697
1698 public int getNumberOfConcurrentTransactedReceivers()
1699 {
1700 return this.numberOfConcurrentTransactedReceivers;
1701 }
1702
1703
1704
1705
1706
1707 public void setNumberOfConcurrentTransactedReceivers(int count)
1708 {
1709 this.numberOfConcurrentTransactedReceivers = count;
1710 }
1711
1712 public void setDynamicNotification(boolean dynamic)
1713 {
1714 dynamicNotification = dynamic;
1715 }
1716
1717 protected void updateCachedNotificationHandler()
1718 {
1719 if (null != muleContext)
1720 {
1721 if (dynamicNotification)
1722 {
1723 cachedNotificationHandler = muleContext.getNotificationManager();
1724 }
1725 else
1726 {
1727 cachedNotificationHandler = new OptimisedNotificationHandler(
1728 muleContext.getNotificationManager(), EndpointMessageNotification.class);
1729 }
1730 }
1731 }
1732
1733 public boolean isEnableMessageEvents()
1734 {
1735 return cachedNotificationHandler.isNotificationEnabled(EndpointMessageNotification.class);
1736 }
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748 public void registerSupportedProtocol(String protocol)
1749 {
1750 protocol = protocol.toLowerCase();
1751 if (protocol.startsWith(getProtocol().toLowerCase()))
1752 {
1753 registerSupportedProtocolWithoutPrefix(protocol);
1754 }
1755 else
1756 {
1757 supportedProtocols.add(getProtocol().toLowerCase() + ":" + protocol);
1758 }
1759 }
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770 public void registerSupportedMetaProtocol(String protocol)
1771 {
1772 supportedProtocols.add(protocol.toLowerCase() + ":" + getProtocol().toLowerCase());
1773
1774 }
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788 protected void registerSupportedProtocolWithoutPrefix(String protocol)
1789 {
1790 supportedProtocols.add(protocol.toLowerCase());
1791 }
1792
1793 public void unregisterSupportedProtocol(String protocol)
1794 {
1795 protocol = protocol.toLowerCase();
1796 if (protocol.startsWith(getProtocol().toLowerCase()))
1797 {
1798 supportedProtocols.remove(protocol);
1799 }
1800 else
1801 {
1802 supportedProtocols.remove(getProtocol().toLowerCase() + ":" + protocol);
1803 }
1804 }
1805
1806
1807
1808
1809 public boolean supportsProtocol(String protocol)
1810 {
1811 return supportedProtocols.contains(protocol.toLowerCase());
1812 }
1813
1814
1815
1816
1817
1818
1819 public List getSupportedProtocols()
1820 {
1821 return Collections.unmodifiableList(supportedProtocols);
1822 }
1823
1824
1825
1826
1827
1828
1829 public void setSupportedProtocols(List supportedProtocols)
1830 {
1831 for (Iterator iterator = supportedProtocols.iterator(); iterator.hasNext();)
1832 {
1833 String s = (String) iterator.next();
1834 registerSupportedProtocol(s);
1835 }
1836 }
1837
1838
1839
1840
1841 protected WorkManager getReceiverWorkManager() throws MuleException
1842 {
1843 return (WorkManager) receiverWorkManager.get();
1844 }
1845
1846
1847
1848
1849
1850
1851 protected WorkManager getDispatcherWorkManager() throws MuleException
1852 {
1853 return (WorkManager) dispatcherWorkManager.get();
1854 }
1855
1856
1857
1858
1859
1860
1861 protected WorkManager getRequesterWorkManager() throws MuleException
1862 {
1863 return (WorkManager) requesterWorkManager.get();
1864 }
1865
1866
1867
1868
1869
1870
1871 public ScheduledExecutorService getScheduler()
1872 {
1873 return scheduler;
1874 }
1875
1876 protected ScheduledExecutorService createScheduler()
1877 {
1878
1879
1880 ThreadFactory threadFactory = new NamedThreadFactory(this.getName() + ".scheduler", this.getClass()
1881 .getClassLoader());
1882 ScheduledThreadPoolExecutor newExecutor = new ScheduledThreadPoolExecutor(4, threadFactory);
1883 newExecutor.setExecuteExistingDelayedTasksAfterShutdownPolicy(false);
1884 newExecutor.setKeepAliveTime(this.getReceiverThreadingProfile().getThreadTTL(), TimeUnit.MILLISECONDS);
1885 newExecutor.allowCoreThreadTimeOut(true);
1886 return newExecutor;
1887 }
1888
1889
1890
1891
1892
1893
1894 public SessionHandler getSessionHandler()
1895 {
1896 return sessionHandler;
1897 }
1898
1899
1900
1901
1902
1903
1904 public void setSessionHandler(SessionHandler sessionHandler)
1905 {
1906 this.sessionHandler = sessionHandler;
1907 }
1908
1909 public void workAccepted(WorkEvent event)
1910 {
1911 this.handleWorkException(event, "workAccepted");
1912 }
1913
1914 public void workRejected(WorkEvent event)
1915 {
1916 this.handleWorkException(event, "workRejected");
1917 }
1918
1919 public void workStarted(WorkEvent event)
1920 {
1921 this.handleWorkException(event, "workStarted");
1922 }
1923
1924 public void workCompleted(WorkEvent event)
1925 {
1926 this.handleWorkException(event, "workCompleted");
1927 }
1928
1929 protected void handleWorkException(WorkEvent event, String type)
1930 {
1931 if (event == null)
1932 {
1933 return;
1934 }
1935
1936 Throwable e = event.getException();
1937
1938 if (e == null)
1939 {
1940 return;
1941 }
1942
1943 if (e.getCause() != null)
1944 {
1945 e = e.getCause();
1946 }
1947
1948 logger.error("Work caused exception on '" + type + "'. Work being executed was: "
1949 + event.getWork().toString());
1950
1951 if (e instanceof Exception)
1952 {
1953 this.handleException((Exception) e);
1954 }
1955 else
1956 {
1957 throw new MuleRuntimeException(CoreMessages.connectorCausedError(this.getName()), e);
1958 }
1959 }
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970 protected void setupDispatchReturn(final OutboundEndpoint endpoint,
1971 final MessageDispatcher dispatcher,
1972 MuleMessage result)
1973 {
1974 if (result != null && result.getPayload() instanceof InputStream)
1975 {
1976 DelegatingInputStream is = new DelegatingInputStream((InputStream) result.getPayload())
1977 {
1978 @Override
1979 public void close() throws IOException
1980 {
1981 try
1982 {
1983 super.close();
1984 }
1985 finally
1986 {
1987 returnDispatcher(endpoint, dispatcher);
1988 }
1989 }
1990 };
1991 result.setPayload(is);
1992 }
1993 else
1994 {
1995
1996 this.returnDispatcher(endpoint, dispatcher);
1997 }
1998 }
1999
2000 public MuleMessage request(String uri, long timeout) throws Exception
2001 {
2002 return request(getMuleContext().getEndpointFactory().getInboundEndpoint(uri),
2003 timeout);
2004 }
2005
2006 public MuleMessage request(InboundEndpoint endpoint, long timeout) throws Exception
2007 {
2008 MessageRequester requester = null;
2009 MuleMessage result = null;
2010
2011 try
2012 {
2013 requester = this.getRequester(endpoint);
2014 result = requester.request(timeout);
2015 return result;
2016 }
2017 finally
2018 {
2019 setupRequestReturn(endpoint, requester, result);
2020 }
2021 }
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032 protected void setupRequestReturn(final InboundEndpoint endpoint,
2033 final MessageRequester requester,
2034 MuleMessage result)
2035 {
2036 if (result != null && result.getPayload() instanceof InputStream)
2037 {
2038 DelegatingInputStream is = new DelegatingInputStream((InputStream) result.getPayload())
2039 {
2040 @Override
2041 public void close() throws IOException
2042 {
2043 try
2044 {
2045 super.close();
2046 }
2047 finally
2048 {
2049 returnRequester(endpoint, requester);
2050 }
2051 }
2052 };
2053 result.setPayload(is);
2054 }
2055 else
2056 {
2057
2058 this.returnRequester(endpoint, requester);
2059 }
2060 }
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076 public void initialiseFromUrl(EndpointURI endpointUri) throws InitialisationException
2077 {
2078 if (!supportsProtocol(endpointUri.getFullScheme()))
2079 {
2080 throw new InitialisationException(CoreMessages.schemeNotCompatibleWithConnector(
2081 endpointUri.getFullScheme(), this.getClass()), this);
2082 }
2083 Properties props = new Properties();
2084 props.putAll(endpointUri.getParams());
2085
2086 if (endpointUri.getUserInfo() != null)
2087 {
2088 props.setProperty("username", endpointUri.getUser());
2089 String passwd = endpointUri.getPassword();
2090 if (passwd != null)
2091 {
2092 props.setProperty("password", passwd);
2093 }
2094 }
2095 String host = endpointUri.getHost();
2096 if (host != null)
2097 {
2098 props.setProperty("hostname", host);
2099 props.setProperty("host", host);
2100 }
2101 if (endpointUri.getPort() > -1)
2102 {
2103 props.setProperty("port", String.valueOf(endpointUri.getPort()));
2104 }
2105
2106 org.mule.util.BeanUtils.populateWithoutFail(this, props, true);
2107
2108 setName(new ObjectNameHelper(muleContext).getConnectorName(this));
2109
2110 }
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120 protected synchronized void initFromServiceDescriptor() throws InitialisationException
2121 {
2122 try
2123 {
2124 serviceDescriptor = (TransportServiceDescriptor) muleContext.getRegistry()
2125 .lookupServiceDescriptor(ServiceType.TRANSPORT, getProtocol().toLowerCase(), serviceOverrides);
2126 if (serviceDescriptor == null)
2127 {
2128 throw new ServiceException(CoreMessages.noServiceTransportDescriptor(getProtocol()));
2129 }
2130
2131 if (logger.isDebugEnabled())
2132 {
2133 logger.debug("Loading DispatcherFactory for connector: " + getName() + " ("
2134 + getClass().getName() + ")");
2135 }
2136
2137 MessageDispatcherFactory df = serviceDescriptor.createDispatcherFactory();
2138 if (df != null)
2139 {
2140 this.setDispatcherFactory(df);
2141 }
2142 else if (logger.isDebugEnabled())
2143 {
2144 logger.debug("Transport '" + getProtocol() + "' will not support outbound endpoints: ");
2145 }
2146
2147 if (logger.isDebugEnabled())
2148 {
2149 logger.debug("Loading RequesterFactory for connector: " + getName() + " ("
2150 + getClass().getName() + ")");
2151 }
2152
2153 MessageRequesterFactory rf = serviceDescriptor.createRequesterFactory();
2154 if (rf != null)
2155 {
2156 this.setRequesterFactory(rf);
2157 }
2158 else if (logger.isDebugEnabled())
2159 {
2160 logger.debug("Transport '" + getProtocol() + "' will not support requests: ");
2161 }
2162
2163 sessionHandler = serviceDescriptor.createSessionHandler();
2164 }
2165 catch (Exception e)
2166 {
2167 throw new InitialisationException(e, this);
2168 }
2169 }
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179 protected TransportServiceDescriptor getServiceDescriptor()
2180 {
2181 if (serviceDescriptor == null)
2182 {
2183 throw new IllegalStateException("This connector has not yet been initialised: " + name);
2184 }
2185 return serviceDescriptor;
2186 }
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201 protected MessageReceiver createReceiver(FlowConstruct flowConstruct, InboundEndpoint endpoint) throws Exception
2202 {
2203 return getServiceDescriptor().createMessageReceiver(this, flowConstruct, endpoint);
2204 }
2205
2206
2207
2208
2209
2210
2211
2212 public Map getServiceOverrides()
2213 {
2214 return serviceOverrides;
2215 }
2216
2217
2218
2219
2220
2221
2222 public void setServiceOverrides(Map serviceOverrides)
2223 {
2224 this.serviceOverrides = new Properties();
2225 this.serviceOverrides.putAll(serviceOverrides);
2226 }
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240 public OutputStream getOutputStream(OutboundEndpoint endpoint, MuleEvent event) throws MuleException
2241 {
2242 throw new UnsupportedOperationException(CoreMessages.streamingNotSupported(this.getProtocol()).toString());
2243 }
2244
2245 public MuleContext getMuleContext()
2246 {
2247 return muleContext;
2248 }
2249
2250 @Override
2251 public String toString()
2252 {
2253 final StringBuffer sb = new StringBuffer(120);
2254 final String nl = System.getProperty("line.separator");
2255 sb.append(ClassUtils.getSimpleName(this.getClass()));
2256
2257 sb.append(nl);
2258 sb.append("{");
2259 sb.append(nl);
2260 sb.append(" name=").append(name);
2261 sb.append(nl);
2262 sb.append(" lifecycle=").append(
2263 lifecycleManager == null ? "<not in lifecycle>" : lifecycleManager.getCurrentPhase());
2264 sb.append(nl);
2265 sb.append(" this=").append(Integer.toHexString(System.identityHashCode(this)));
2266 sb.append(nl);
2267 sb.append(" numberOfConcurrentTransactedReceivers=").append(numberOfConcurrentTransactedReceivers);
2268 sb.append(nl);
2269 sb.append(" createMultipleTransactedReceivers=").append(createMultipleTransactedReceivers);
2270 sb.append(nl);
2271 sb.append(" connected=").append(connected);
2272 sb.append(nl);
2273 sb.append(" supportedProtocols=").append(supportedProtocols);
2274 sb.append(nl);
2275 sb.append(" serviceOverrides=");
2276 if (serviceOverrides != null)
2277 {
2278 for (Map.Entry<Object, Object> entry : serviceOverrides.entrySet())
2279 {
2280 sb.append(nl);
2281 sb.append(" ").append(String.format("%s=%s", entry.getKey(), entry.getValue()));
2282 }
2283 }
2284 else
2285 {
2286 sb.append("<none>");
2287 }
2288 sb.append(nl);
2289 sb.append('}');
2290 sb.append(nl);
2291 return sb.toString();
2292 }
2293
2294 public RetryPolicyTemplate getRetryPolicyTemplate()
2295 {
2296 return retryPolicyTemplate;
2297 }
2298
2299 public void setRetryPolicyTemplate(RetryPolicyTemplate retryPolicyTemplate)
2300 {
2301 this.retryPolicyTemplate = retryPolicyTemplate;
2302 }
2303
2304
2305
2306
2307 public boolean isValidateConnections()
2308 {
2309 return validateConnections;
2310 }
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326 public void setValidateConnections(final boolean validateConnections)
2327 {
2328 this.validateConnections = validateConnections;
2329 }
2330
2331
2332
2333
2334
2335
2336
2337 public void setDispatcherPoolWhenExhaustedAction(byte whenExhaustedAction)
2338 {
2339 checkDispatchersInitialised();
2340 dispatchers.setWhenExhaustedAction(whenExhaustedAction);
2341 }
2342
2343
2344
2345
2346
2347 public void setDispatcherPoolMaxWait(int maxWait)
2348 {
2349 checkDispatchersInitialised();
2350 dispatchers.setMaxWait(maxWait);
2351 }
2352
2353
2354
2355
2356 public void setDispatcherPoolFactory(ConfigurableKeyedObjectPoolFactory dispatcherPoolFactory)
2357 {
2358 this.dispatcherPoolFactory = dispatcherPoolFactory;
2359 }
2360
2361 public ConfigurableKeyedObjectPoolFactory getDispatcherPoolFactory()
2362 {
2363 return dispatcherPoolFactory;
2364 }
2365
2366
2367
2368
2369
2370 public void setRequesterPoolWhenExhaustedAction(byte whenExhaustedAction)
2371 {
2372 requesters.setWhenExhaustedAction(whenExhaustedAction);
2373 }
2374
2375
2376
2377
2378
2379 public void setRequesterPoolMaxWait(int maxWait)
2380 {
2381 requesters.setMaxWait(maxWait);
2382 }
2383
2384 public MessageProcessor createDispatcherMessageProcessor(OutboundEndpoint endpoint) throws MuleException
2385 {
2386 if (endpoint.getExchangePattern().hasResponse() || !getDispatcherThreadingProfile().isDoThreading())
2387 {
2388 return new DispatcherMessageProcessor();
2389 }
2390 else
2391 {
2392 DefaultMessageProcessorChainBuilder builder = new DefaultMessageProcessorChainBuilder();
2393 builder.chain(new OptionalAsyncInterceptingMessageProcessor(new WorkManagerSource()
2394 {
2395 public WorkManager getWorkManager() throws MuleException
2396 {
2397 return getDispatcherWorkManager();
2398 }
2399 }));
2400 builder.chain(new DispatcherMessageProcessor());
2401 return builder.build();
2402 }
2403 }
2404
2405 public MessageExchangePattern getDefaultExchangePattern()
2406 {
2407 try
2408 {
2409 return serviceDescriptor.getDefaultExchangePattern();
2410 }
2411 catch (TransportServiceException tse)
2412 {
2413 throw new MuleRuntimeException(tse);
2414 }
2415 }
2416
2417 public List<MessageExchangePattern> getInboundExchangePatterns()
2418 {
2419 try
2420 {
2421 return serviceDescriptor.getInboundExchangePatterns();
2422 }
2423 catch (TransportServiceException tse)
2424 {
2425 throw new MuleRuntimeException(tse);
2426 }
2427 }
2428
2429 public List<MessageExchangePattern> getOutboundExchangePatterns()
2430 {
2431 try
2432 {
2433 return serviceDescriptor.getOutboundExchangePatterns();
2434 }
2435 catch (TransportServiceException tse)
2436 {
2437 throw new MuleRuntimeException(tse);
2438 }
2439 }
2440
2441 class DispatcherMessageProcessor implements MessageProcessor
2442 {
2443 private MessageProcessor notificationMessageProcessor;
2444
2445 public MuleEvent process(MuleEvent event) throws MuleException
2446 {
2447 OutboundEndpoint endpoint = (OutboundEndpoint) event.getEndpoint();
2448 MessageDispatcher dispatcher = null;
2449 try
2450 {
2451 dispatcher = getDispatcher(endpoint);
2452 MuleEvent result = dispatcher.process(event);
2453
2454
2455 if (notificationMessageProcessor == null)
2456 {
2457 notificationMessageProcessor = new OutboundNotificationMessageProcessor(endpoint);
2458 }
2459 notificationMessageProcessor.process(event);
2460 return result;
2461
2462 }
2463 catch (DispatchException dex)
2464 {
2465 throw dex;
2466 }
2467 catch (MuleException ex)
2468 {
2469 throw new DispatchException(event, endpoint, ex);
2470 }
2471 finally
2472 {
2473 returnDispatcher(endpoint, dispatcher);
2474 }
2475 }
2476
2477 @Override
2478 public String toString()
2479 {
2480 return ObjectUtils.toString(this);
2481 }
2482 };
2483 }