1
2
3
4
5
6
7
8
9
10
11 package org.mule.transport;
12
13 import org.mule.OptimizedRequestContext;
14 import org.mule.RequestContext;
15 import org.mule.api.MuleEvent;
16 import org.mule.api.MuleException;
17 import org.mule.api.MuleMessage;
18 import org.mule.api.config.MuleProperties;
19 import org.mule.api.endpoint.ImmutableEndpoint;
20 import org.mule.api.endpoint.OutboundEndpoint;
21 import org.mule.api.routing.ResponseRouterCollection;
22 import org.mule.api.transaction.Transaction;
23 import org.mule.api.transaction.TransactionException;
24 import org.mule.api.transport.DispatchException;
25 import org.mule.api.transport.MessageDispatcher;
26 import org.mule.context.notification.EndpointMessageNotification;
27 import org.mule.context.notification.SecurityNotification;
28 import org.mule.transaction.TransactionCoordination;
29
30 import javax.resource.spi.work.Work;
31 import javax.resource.spi.work.WorkManager;
32
33
34
35
36 public abstract class AbstractMessageDispatcher extends AbstractConnectable implements MessageDispatcher
37 {
38
39 public AbstractMessageDispatcher(OutboundEndpoint endpoint)
40 {
41 super(endpoint);
42 }
43
44
45
46
47
48
49 public final void dispatch(MuleEvent event) throws DispatchException
50 {
51 event.setSynchronous(false);
52 event.getMessage().setProperty(MuleProperties.MULE_ENDPOINT_PROPERTY,
53 event.getEndpoint().getEndpointURI().toString());
54 event = OptimizedRequestContext.criticalSetEvent(event);
55
56
57 ImmutableEndpoint endpoint = event.getEndpoint();
58 if (endpoint.getSecurityFilter() != null)
59 {
60 try
61 {
62 endpoint.getSecurityFilter().authenticate(event);
63 }
64 catch (org.mule.api.security.SecurityException e)
65 {
66
67 logger.warn("Outbound Request was made but was not authenticated: " + e.getMessage(), e);
68 connector.fireNotification(new SecurityNotification(e,
69 SecurityNotification.SECURITY_AUTHENTICATION_FAILED));
70 connector.handleException(e);
71 return;
72 }
73 catch (MuleException e)
74 {
75 disposeAndLogException();
76 throw new DispatchException(event.getMessage(), event.getEndpoint(), e);
77 }
78 }
79
80 try
81 {
82 Transaction tx = TransactionCoordination.getInstance().getTransaction();
83 if (isDoThreading() && !event.isSynchronous() && tx == null)
84 {
85 connector.getDispatcherWorkManager().scheduleWork(new Worker(event), WorkManager.INDEFINITE, null, connector);
86 }
87 else
88 {
89
90 connectionStrategy.connect(this);
91 doDispatch(event);
92 if (connector.isEnableMessageEvents())
93 {
94 String component = null;
95 if (event.getService() != null)
96 {
97 component = event.getService().getName();
98 }
99 connector.fireNotification(new EndpointMessageNotification(event.getMessage(), event
100 .getEndpoint(), component, EndpointMessageNotification.MESSAGE_DISPATCHED));
101 }
102 }
103 }
104 catch (DispatchException e)
105 {
106 disposeAndLogException();
107 throw e;
108 }
109 catch (Exception e)
110 {
111 disposeAndLogException();
112 throw new DispatchException(event.getMessage(), event.getEndpoint(), e);
113 }
114 }
115
116 public final MuleMessage send(MuleEvent event) throws DispatchException
117 {
118
119 if (isTransactionRollback())
120 {
121 return event.getMessage();
122 }
123
124 event.setSynchronous(true);
125 event.getMessage().setProperty(MuleProperties.MULE_ENDPOINT_PROPERTY,
126 event.getEndpoint().getEndpointURI().getUri().toString());
127 event = OptimizedRequestContext.unsafeSetEvent(event);
128
129
130 ImmutableEndpoint endpoint = event.getEndpoint();
131 if (endpoint.getSecurityFilter() != null)
132 {
133 try
134 {
135 endpoint.getSecurityFilter().authenticate(event);
136 }
137 catch (org.mule.api.security.SecurityException e)
138 {
139 logger.warn("Outbound Request was made but was not authenticated: " + e.getMessage(), e);
140 connector.fireNotification(new SecurityNotification(e,
141 SecurityNotification.SECURITY_AUTHENTICATION_FAILED));
142 connector.handleException(e);
143 return event.getMessage();
144 }
145 catch (MuleException e)
146 {
147 disposeAndLogException();
148 throw new DispatchException(event.getMessage(), event.getEndpoint(), e);
149 }
150 }
151
152 try
153 {
154
155 connectionStrategy.connect(this);
156
157 MuleMessage result = doSend(event);
158 if (connector.isEnableMessageEvents())
159 {
160 String component = null;
161 if (event.getService() != null)
162 {
163 component = event.getService().getName();
164 }
165 connector.fireNotification(new EndpointMessageNotification(event.getMessage(), event.getEndpoint(),
166 component, EndpointMessageNotification.MESSAGE_SENT));
167 }
168
169
170
171
172
173
174
175
176
177
178 return result;
179 }
180 catch (DispatchException e)
181 {
182 disposeAndLogException();
183 throw e;
184 }
185 catch (Exception e)
186 {
187 disposeAndLogException();
188 throw new DispatchException(event.getMessage(), event.getEndpoint(), e);
189 }
190 }
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209 protected boolean useRemoteSync(MuleEvent event)
210 {
211 boolean remoteSync = false;
212 if (event.getEndpoint().getConnector().isRemoteSyncEnabled())
213 {
214 remoteSync = event.getEndpoint().isRemoteSync()
215 || event.getMessage().getBooleanProperty(
216 MuleProperties.MULE_REMOTE_SYNC_PROPERTY, false);
217 if (remoteSync)
218 {
219
220 if (event.getService() != null)
221 {
222 ResponseRouterCollection responseRouters = event.getService().getResponseRouter();
223 if (responseRouters != null && responseRouters.hasEndpoints())
224 {
225 remoteSync = false;
226 }
227 else
228 {
229 remoteSync = true;
230 }
231 }
232 }
233 }
234 if (!remoteSync)
235 {
236 event.getMessage().removeProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY);
237 }
238 return remoteSync;
239 }
240
241 private class Worker implements Work
242 {
243 private MuleEvent event;
244
245 public Worker(MuleEvent event)
246 {
247 this.event = event;
248 }
249
250
251
252
253
254
255 public void run()
256 {
257 try
258 {
259 event = RequestContext.setEvent(event);
260
261 connectionStrategy.connect(AbstractMessageDispatcher.this);
262 AbstractMessageDispatcher.this.doDispatch(event);
263
264 if (connector.isEnableMessageEvents())
265 {
266 String component = null;
267 if (event.getService() != null)
268 {
269 component = event.getService().getName();
270 }
271
272 connector.fireNotification(new EndpointMessageNotification(event.getMessage(), event
273 .getEndpoint(), component, EndpointMessageNotification.MESSAGE_DISPATCHED));
274 }
275 }
276 catch (Exception e)
277 {
278 AbstractMessageDispatcher.this.getConnector().handleException(e);
279 }
280 }
281
282 public void release()
283 {
284
285 }
286 }
287
288
289
290
291
292
293 protected boolean isTransactionRollback()
294 {
295 try
296 {
297 Transaction tx = TransactionCoordination.getInstance().getTransaction();
298 if (tx != null && tx.isRollbackOnly())
299 {
300 return true;
301 }
302 }
303 catch (TransactionException e)
304 {
305
306 logger.warn(e.getMessage());
307 }
308 return false;
309 }
310
311 protected abstract void doDispatch(MuleEvent event) throws Exception;
312
313 protected abstract MuleMessage doSend(MuleEvent event) throws Exception;
314
315 }