1
2
3
4
5
6
7
8
9
10
11 package org.mule.extras.client;
12
13 import org.mule.MuleManager;
14 import org.mule.config.MuleProperties;
15 import org.mule.impl.MuleEvent;
16 import org.mule.impl.MuleMessage;
17 import org.mule.impl.MuleSession;
18 import org.mule.impl.MuleSessionHandler;
19 import org.mule.impl.RequestContext;
20 import org.mule.impl.endpoint.MuleEndpoint;
21 import org.mule.impl.internal.notifications.AdminNotification;
22 import org.mule.impl.security.MuleCredentials;
23 import org.mule.providers.AbstractConnector;
24 import org.mule.providers.service.TransportFactory;
25 import org.mule.transformers.wire.SerializationWireFormat;
26 import org.mule.transformers.wire.WireFormat;
27 import org.mule.umo.FutureMessageResult;
28 import org.mule.umo.UMOEvent;
29 import org.mule.umo.UMOException;
30 import org.mule.umo.UMOMessage;
31 import org.mule.umo.endpoint.UMOEndpoint;
32 import org.mule.umo.lifecycle.Disposable;
33 import org.mule.umo.provider.DispatchException;
34 import org.mule.umo.security.UMOCredentials;
35 import org.mule.util.MuleObjectHelper;
36
37 import java.io.ByteArrayInputStream;
38 import java.io.ByteArrayOutputStream;
39 import java.io.InputStream;
40 import java.util.Map;
41
42 import edu.emory.mathcs.backport.java.util.concurrent.Callable;
43 import edu.emory.mathcs.backport.java.util.concurrent.Executor;
44 import org.apache.commons.logging.Log;
45 import org.apache.commons.logging.LogFactory;
46
47
48
49
50
51
52
53 public class RemoteDispatcher implements Disposable
54 {
55
56
57
58
59 protected static final Log logger = LogFactory.getLog(RemoteDispatcher.class);
60
61
62
63
64 private UMOEndpoint serverEndpoint;
65 private UMOCredentials credentials = null;
66
67
68
69
70 private Executor asyncExecutor;
71
72
73
74
75 private WireFormat wireFormat;
76
77 protected RemoteDispatcher(String endpoint, UMOCredentials credentials) throws UMOException
78 {
79 this(endpoint);
80 this.credentials = credentials;
81 }
82
83 protected RemoteDispatcher(String endpoint) throws UMOException
84 {
85 serverEndpoint = new MuleEndpoint(endpoint, true);
86 wireFormat = new SerializationWireFormat();
87 }
88
89 protected void setExecutor(Executor e)
90 {
91 this.asyncExecutor = e;
92 }
93
94
95
96
97
98
99
100
101
102
103
104
105
106 public void dispatchToRemoteComponent(String component, Object payload, Map messageProperties)
107 throws UMOException
108 {
109 doToRemoteComponent(component, payload, messageProperties, false);
110 }
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125 public UMOMessage sendToRemoteComponent(String component, Object payload, Map messageProperties)
126 throws UMOException
127 {
128 return doToRemoteComponent(component, payload, messageProperties, true);
129 }
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148 public FutureMessageResult sendAsyncToRemoteComponent(final String component,
149 String transformers,
150 final Object payload,
151 final Map messageProperties) throws UMOException
152 {
153 Callable callable = new Callable()
154 {
155 public Object call() throws Exception
156 {
157 return doToRemoteComponent(component, payload, messageProperties, true);
158 }
159 };
160
161 FutureMessageResult result = new FutureMessageResult(callable);
162
163 if (asyncExecutor != null)
164 {
165 result.setExecutor(asyncExecutor);
166 }
167
168 if (transformers != null)
169 {
170 result.setTransformer(MuleObjectHelper.getTransformer(transformers, ","));
171 }
172
173 result.execute();
174 return result;
175 }
176
177 public UMOMessage sendRemote(String endpoint, Object payload, Map messageProperties, int timeout)
178 throws UMOException
179 {
180 return doToRemote(endpoint, payload, messageProperties, true, timeout);
181 }
182
183 public UMOMessage sendRemote(String endpoint, Object payload, Map messageProperties) throws UMOException
184 {
185 return doToRemote(endpoint, payload, messageProperties, true, MuleManager.getConfiguration()
186 .getSynchronousEventTimeout());
187 }
188
189 public void dispatchRemote(String endpoint, Object payload, Map messageProperties) throws UMOException
190 {
191 doToRemote(endpoint, payload, messageProperties, false, -1);
192 }
193
194 public FutureMessageResult sendAsyncRemote(final String endpoint,
195 final Object payload,
196 final Map messageProperties) throws UMOException
197 {
198 Callable callable = new Callable()
199 {
200 public Object call() throws Exception
201 {
202 return doToRemote(endpoint, payload, messageProperties, true, -1);
203 }
204 };
205
206 FutureMessageResult result = new FutureMessageResult(callable);
207
208 if (asyncExecutor != null)
209 {
210 result.setExecutor(asyncExecutor);
211 }
212
213 result.execute();
214 return result;
215 }
216
217 public UMOMessage receiveRemote(String endpoint, int timeout) throws UMOException
218 {
219 AdminNotification action = new AdminNotification(null, AdminNotification.ACTION_RECEIVE, endpoint);
220 action.setProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, "true");
221 action.setProperty(MuleProperties.MULE_EVENT_TIMEOUT_PROPERTY, new Long(timeout));
222 UMOMessage result = dispatchAction(action, true, timeout);
223 return result;
224 }
225
226 public FutureMessageResult asyncReceiveRemote(final String endpoint, final int timeout)
227 throws UMOException
228 {
229 Callable callable = new Callable()
230 {
231 public Object call() throws Exception
232 {
233 return receiveRemote(endpoint, timeout);
234 }
235 };
236
237 FutureMessageResult result = new FutureMessageResult(callable);
238
239 if (asyncExecutor != null)
240 {
241 result.setExecutor(asyncExecutor);
242 }
243
244 result.execute();
245 return result;
246 }
247
248 protected UMOMessage doToRemoteComponent(String component,
249 Object payload,
250 Map messageProperties,
251 boolean synchronous) throws UMOException
252 {
253 UMOMessage message = new MuleMessage(payload, messageProperties);
254 message.setBooleanProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, synchronous);
255 setCredentials(message);
256 AdminNotification action = new AdminNotification(message, AdminNotification.ACTION_INVOKE,
257 "mule://" + component);
258 UMOMessage result = dispatchAction(action, synchronous, MuleManager.getConfiguration()
259 .getSynchronousEventTimeout());
260 return result;
261 }
262
263 protected UMOMessage doToRemote(String endpoint,
264 Object payload,
265 Map messageProperties,
266 boolean synchronous,
267 int timeout) throws UMOException
268 {
269 UMOMessage message = new MuleMessage(payload, messageProperties);
270 message.setProperty(MuleProperties.MULE_REMOTE_SYNC_PROPERTY, String.valueOf(synchronous));
271 setCredentials(message);
272 AdminNotification action = new AdminNotification(message, (synchronous
273 ? AdminNotification.ACTION_SEND : AdminNotification.ACTION_DISPATCH), endpoint);
274
275 UMOMessage result = dispatchAction(action, synchronous, timeout);
276 return result;
277 }
278
279 protected UMOMessage dispatchAction(AdminNotification action, boolean synchronous, int timeout)
280 throws UMOException
281 {
282
283 UMOEndpoint endpoint = TransportFactory.createEndpoint(serverEndpoint.getEndpointURI(),
284 UMOEndpoint.ENDPOINT_TYPE_SENDER);
285 endpoint.setRemoteSync(synchronous);
286 updateContext(new MuleMessage(action), endpoint, synchronous);
287
288 ByteArrayOutputStream out = new ByteArrayOutputStream();
289 wireFormat.write(out, action);
290 byte[] payload = out.toByteArray();
291
292 UMOMessage message = action.getMessage();
293
294 if (message == null)
295 {
296 message = new MuleMessage(payload);
297 }
298 else
299 {
300 message = new MuleMessage(payload, message);
301 }
302
303 message.addProperties(action.getProperties());
304 MuleSession session = new MuleSession(message,
305 ((AbstractConnector)endpoint.getConnector()).getSessionHandler());
306
307 UMOEvent event = new MuleEvent(message, endpoint, session, true);
308 event.setTimeout(timeout);
309 if (logger.isDebugEnabled())
310 {
311 logger.debug("MuleClient sending remote call to: " + action.getResourceIdentifier() + ". At "
312 + serverEndpoint.toString() + " . Event is: " + event);
313 }
314
315 UMOMessage result;
316
317 try
318 {
319 if (synchronous)
320 {
321 result = endpoint.send(event);
322 }
323 else
324 {
325 endpoint.dispatch(event);
326 return null;
327 }
328
329 if (result != null)
330 {
331 if (result.getPayload() != null)
332 {
333 Object response;
334 if (result.getPayload() instanceof InputStream)
335 {
336 response = wireFormat.read((InputStream)result.getPayload());
337 }
338 else
339 {
340 ByteArrayInputStream in = new ByteArrayInputStream(result.getPayloadAsBytes());
341 response = wireFormat.read(in);
342 }
343
344 if (response instanceof AdminNotification)
345 {
346 response = ((AdminNotification)response).getMessage();
347 }
348 return (UMOMessage)response;
349 }
350 }
351 }
352 catch (Exception e)
353 {
354 throw new DispatchException(event.getMessage(), event.getEndpoint(), e);
355 }
356
357 if (logger.isDebugEnabled())
358 {
359 logger.debug("Result of MuleClient remote call is: "
360 + (result == null ? "null" : result.getPayload()));
361 }
362
363 return result;
364 }
365
366 public void dispose()
367 {
368
369 }
370
371 protected void setCredentials(UMOMessage message)
372 {
373 if (credentials != null)
374 {
375 message.setProperty(MuleProperties.MULE_USER_PROPERTY, MuleCredentials.createHeader(
376 credentials.getUsername(), credentials.getPassword()));
377 }
378 }
379
380 public WireFormat getWireFormat()
381 {
382 return wireFormat;
383 }
384
385 public void setWireFormat(WireFormat wireFormat)
386 {
387 this.wireFormat = wireFormat;
388 }
389
390 protected void updateContext(UMOMessage message, UMOEndpoint endpoint, boolean synchronous)
391 throws UMOException
392 {
393
394 RequestContext.setEvent(new MuleEvent(message, endpoint, new MuleSession(message,
395 new MuleSessionHandler()), synchronous));
396 }
397 }