1
2
3
4
5
6
7
8
9
10
11 package org.mule.processor;
12
13 import org.mule.api.MessagingException;
14 import org.mule.api.MuleEvent;
15 import org.mule.api.MuleException;
16 import org.mule.api.MuleRuntimeException;
17 import org.mule.api.config.ThreadingProfile;
18 import org.mule.api.context.WorkManager;
19 import org.mule.api.context.WorkManagerSource;
20 import org.mule.api.lifecycle.Startable;
21 import org.mule.api.lifecycle.Stoppable;
22 import org.mule.api.processor.MessageProcessor;
23 import org.mule.config.i18n.CoreMessages;
24 import org.mule.work.AbstractMuleEventWork;
25 import org.mule.work.MuleWorkManager;
26
27 import javax.resource.spi.work.WorkEvent;
28 import javax.resource.spi.work.WorkListener;
29
30
31
32
33
34
35
36
37 public class AsyncInterceptingMessageProcessor extends AbstractInterceptingMessageProcessor
38 implements WorkListener, Startable, Stoppable
39 {
40 protected WorkManagerSource workManagerSource;
41 protected boolean doThreading = true;
42 protected WorkManager workManager;
43
44 public AsyncInterceptingMessageProcessor(WorkManagerSource workManagerSource)
45 {
46 this.workManagerSource = workManagerSource;
47 }
48
49 @Deprecated
50 public AsyncInterceptingMessageProcessor(WorkManagerSource workManagerSource, boolean doThreading)
51 {
52 this.workManagerSource = workManagerSource;
53 this.doThreading = doThreading;
54 }
55
56 public AsyncInterceptingMessageProcessor(ThreadingProfile threadingProfile,
57 String name,
58 int shutdownTimeout)
59 {
60 this.doThreading = threadingProfile.isDoThreading();
61 workManager = threadingProfile.createWorkManager(name, shutdownTimeout);
62 workManagerSource = new WorkManagerSource()
63 {
64 public WorkManager getWorkManager() throws MuleException
65 {
66 return workManager;
67 }
68 };
69 }
70
71 public void start() throws MuleException
72 {
73 if (workManager != null)
74 {
75 workManager.start();
76 }
77 }
78
79 public void stop() throws MuleException
80 {
81 if (workManager != null)
82 {
83 workManager.dispose();
84 }
85 }
86
87 public MuleEvent process(MuleEvent event) throws MuleException
88 {
89 if (next == null)
90 {
91 return event;
92 }
93 else if (isProcessAsync(event))
94 {
95 processNextAsync(event);
96 return null;
97 }
98 else
99 {
100 return processNext(event);
101 }
102 }
103
104 protected boolean isProcessAsync(MuleEvent event) throws MessagingException
105 {
106
107 if (event.getEndpoint().getTransactionConfig().isTransacted())
108 {
109 throw new MessagingException(CoreMessages.asyncDoesNotSupportTransactions(), event);
110 }
111 return doThreading;
112 }
113
114 protected void processNextAsync(MuleEvent event) throws MuleException
115 {
116 try
117 {
118 workManagerSource.getWorkManager().scheduleWork(new AsyncMessageProcessorWorker(event),
119 WorkManager.INDEFINITE, null, this);
120 }
121 catch (Exception e)
122 {
123 new MessagingException(CoreMessages.errorSchedulingMessageProcessorForAsyncInvocation(next),
124 event, e);
125 }
126 }
127
128 public void workAccepted(WorkEvent event)
129 {
130 this.handleWorkException(event, "workAccepted");
131 }
132
133 public void workRejected(WorkEvent event)
134 {
135 this.handleWorkException(event, "workRejected");
136 }
137
138 public void workStarted(WorkEvent event)
139 {
140 this.handleWorkException(event, "workStarted");
141 }
142
143 public void workCompleted(WorkEvent event)
144 {
145 this.handleWorkException(event, "workCompleted");
146 }
147
148 protected void handleWorkException(WorkEvent event, String type)
149 {
150 if (event == null)
151 {
152 return;
153 }
154
155 Throwable e = event.getException();
156
157 if (e == null)
158 {
159 return;
160 }
161
162 if (e.getCause() != null)
163 {
164 e = e.getCause();
165 }
166
167 logger.error("Work caused exception on '" + type + "'. Work being executed was: "
168 + event.getWork().toString());
169 throw new MuleRuntimeException(CoreMessages.errorInvokingMessageProcessorAsynchronously(next), e);
170 }
171
172 class AsyncMessageProcessorWorker extends AbstractMuleEventWork
173 {
174 public AsyncMessageProcessorWorker(MuleEvent event)
175 {
176 super(event);
177 }
178
179 @Override
180 protected void doRun()
181 {
182 try
183 {
184 processNext(event);
185 }
186 catch (MuleException e)
187 {
188 event.getFlowConstruct().getExceptionListener().handleException(e, event);
189 }
190 }
191 }
192
193 }