1
2
3
4
5
6
7
8
9
10
11 package org.mule.routing.outbound;
12
13 import org.mule.MuleManager;
14 import org.mule.config.MuleProperties;
15 import org.mule.routing.AbstractRouter;
16 import org.mule.routing.CorrelationPropertiesExtractor;
17 import org.mule.umo.UMOException;
18 import org.mule.umo.UMOMessage;
19 import org.mule.umo.UMOSession;
20 import org.mule.umo.UMOTransactionConfig;
21 import org.mule.umo.endpoint.UMOEndpoint;
22 import org.mule.umo.endpoint.UMOImmutableEndpoint;
23 import org.mule.umo.routing.UMOOutboundRouter;
24 import org.mule.util.ClassUtils;
25 import org.mule.util.StringMessageUtils;
26 import org.mule.util.SystemUtils;
27 import org.mule.util.properties.PropertyExtractor;
28
29 import java.util.Iterator;
30 import java.util.List;
31
32 import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList;
33 import org.apache.commons.logging.Log;
34 import org.apache.commons.logging.LogFactory;
35
36
37
38
39
40
41
42
43 public abstract class AbstractOutboundRouter extends AbstractRouter implements UMOOutboundRouter
44 {
45 public static final int ENABLE_CORRELATION_IF_NOT_SET = 0;
46 public static final int ENABLE_CORRELATION_ALWAYS = 1;
47 public static final int ENABLE_CORRELATION_NEVER = 2;
48
49
50
51 protected transient Log logger = LogFactory.getLog(getClass());
52
53 protected List endpoints = new CopyOnWriteArrayList();
54
55 protected String replyTo = null;
56
57 protected int enableCorrelation = ENABLE_CORRELATION_IF_NOT_SET;
58
59 protected PropertyExtractor propertyExtractor = new CorrelationPropertiesExtractor();
60
61 protected UMOTransactionConfig transactionConfig;
62
63 public void dispatch(UMOSession session, UMOMessage message, UMOEndpoint endpoint) throws UMOException
64 {
65 setMessageProperties(session, message, endpoint);
66
67 if (logger.isDebugEnabled())
68 {
69 try
70 {
71 logger.debug("Message being sent to: " + endpoint.getEndpointURI() + " Message payload: \n"
72 + StringMessageUtils.truncate(message.getPayloadAsString(), 100, false));
73 }
74 catch (Exception e)
75 {
76 logger.debug("Message being sent to: " + endpoint.getEndpointURI()
77 + " Message payload: \n(unable to retrieve payload: " + e.getMessage());
78 }
79 }
80
81 session.dispatchEvent(message, endpoint);
82 if (getRouterStatistics() != null)
83 {
84 if (getRouterStatistics().isEnabled())
85 {
86 getRouterStatistics().incrementRoutedMessage(endpoint);
87 }
88 }
89 }
90
91 public UMOMessage send(UMOSession session, UMOMessage message, UMOEndpoint endpoint) throws UMOException
92 {
93 if (replyTo != null)
94 {
95 logger.debug("event was dispatched synchronously, but there is a ReplyTo endpoint set, so using asynchronous dispatch");
96 dispatch(session, message, endpoint);
97 return null;
98 }
99
100 this.setMessageProperties(session, message, endpoint);
101
102 if (logger.isDebugEnabled())
103 {
104 logger.debug("Message being sent to: " + endpoint.getEndpointURI());
105 logger.debug(message);
106 }
107
108 if (logger.isTraceEnabled())
109 {
110 try
111 {
112 logger.trace("Message payload: \n" + message.getPayloadAsString());
113 }
114 catch (Exception e)
115 {
116
117 }
118 }
119
120 UMOMessage result = session.sendEvent(message, endpoint);
121
122 if (getRouterStatistics() != null)
123 {
124 if (getRouterStatistics().isEnabled())
125 {
126 getRouterStatistics().incrementRoutedMessage(endpoint);
127 }
128 }
129
130 if (logger.isDebugEnabled())
131 {
132 logger.debug("Response message from sending to: " + endpoint.getEndpointURI());
133 logger.debug(result);
134 }
135
136 if (logger.isTraceEnabled())
137 {
138 try
139 {
140 logger.trace("Message payload: \n" + result.getPayloadAsString());
141 }
142 catch (Exception e)
143 {
144
145 }
146 }
147
148 return result;
149 }
150
151 protected void setMessageProperties(UMOSession session, UMOMessage message, UMOEndpoint endpoint)
152 {
153 if (replyTo != null)
154 {
155
156
157 message.setReplyTo(replyTo);
158 message.setProperty(MuleProperties.MULE_REPLY_TO_REQUESTOR_PROPERTY, session.getComponent()
159 .getDescriptor()
160 .getName());
161 if (logger.isDebugEnabled())
162 {
163 logger.debug("Setting replyTo=" + replyTo + " for outbound endpoint: "
164 + endpoint.getEndpointURI());
165 }
166 }
167 if (enableCorrelation != ENABLE_CORRELATION_NEVER)
168 {
169 boolean correlationSet = message.getCorrelationId() != null;
170 if (correlationSet && (enableCorrelation == ENABLE_CORRELATION_IF_NOT_SET))
171 {
172 if (logger.isDebugEnabled())
173 {
174 logger.debug("CorrelationId is already set to '" + message.getCorrelationId()
175 + "' , not setting it again");
176 }
177 return;
178 }
179 else if (correlationSet)
180 {
181 if (logger.isDebugEnabled())
182 {
183 logger.debug("CorrelationId is already set to '" + message.getCorrelationId()
184 + "', but router is configured to overwrite it");
185 }
186 }
187 else
188 {
189 if (logger.isDebugEnabled())
190 {
191 logger.debug("No CorrelationId is set on the message, will set a new Id");
192 }
193 }
194
195 String correlation;
196 Object o = propertyExtractor.getProperty(MuleProperties.MULE_CORRELATION_ID_PROPERTY, message);
197 if (logger.isDebugEnabled())
198 {
199 logger.debug("Extracted correlation Id as: " + o);
200 }
201 correlation = o.toString();
202
203 if (logger.isDebugEnabled())
204 {
205 StringBuffer buf = new StringBuffer();
206 buf.append("Setting Correlation info on Outbound router for endpoint: ").append(
207 endpoint.getEndpointURI());
208 buf.append(SystemUtils.LINE_SEPARATOR).append("Id=").append(correlation);
209
210
211 logger.debug(buf.toString());
212 }
213 message.setCorrelationId(correlation);
214
215
216 }
217 }
218
219 public List getEndpoints()
220 {
221 return endpoints;
222 }
223
224 public void setEndpoints(List endpoints)
225 {
226
227 for (Iterator iterator = endpoints.iterator(); iterator.hasNext();)
228 {
229 UMOEndpoint umoEndpoint = (UMOEndpoint) iterator.next();
230 addEndpoint(umoEndpoint);
231 }
232 }
233
234 public void addEndpoint(UMOEndpoint endpoint)
235 {
236
237 endpoints.add(endpoint);
238 }
239
240 public boolean removeEndpoint(UMOImmutableEndpoint endpoint)
241 {
242 return endpoints.remove(endpoint);
243 }
244
245 public String getReplyTo()
246 {
247 return replyTo;
248 }
249
250 public void setReplyTo(String replyTo)
251 {
252 if (replyTo != null)
253 {
254 this.replyTo = MuleManager.getInstance().lookupEndpointIdentifier(replyTo, replyTo);
255 }
256 else
257 {
258 this.replyTo = null;
259 }
260 }
261
262 public int getEnableCorrelation()
263 {
264 return enableCorrelation;
265 }
266
267 public void setEnableCorrelation(int enableCorrelation)
268 {
269 this.enableCorrelation = enableCorrelation;
270 }
271
272 public void setEnableCorrelationAsString(String enableCorrelation)
273 {
274 if (enableCorrelation != null)
275 {
276 if (enableCorrelation.equals("ALWAYS"))
277 {
278 this.enableCorrelation = ENABLE_CORRELATION_ALWAYS;
279 }
280 else if (enableCorrelation.equals("NEVER"))
281 {
282 this.enableCorrelation = ENABLE_CORRELATION_NEVER;
283 }
284 else if (enableCorrelation.equals("IF_NOT_SET"))
285 {
286 this.enableCorrelation = ENABLE_CORRELATION_IF_NOT_SET;
287 }
288 else
289 {
290 throw new IllegalArgumentException("Value for enableCorrelation not recognised: "
291 + enableCorrelation);
292 }
293 }
294 }
295
296 public PropertyExtractor getPropertyExtractor()
297 {
298 return propertyExtractor;
299 }
300
301 public void setPropertyExtractor(PropertyExtractor propertyExtractor)
302 {
303 this.propertyExtractor = propertyExtractor;
304 }
305
306 public void setPropertyExtractorAsString(String className)
307 {
308 try
309 {
310 this.propertyExtractor = (PropertyExtractor) ClassUtils.instanciateClass(className, null,
311 getClass());
312 }
313 catch (Exception ex)
314 {
315 throw (IllegalArgumentException) new IllegalArgumentException(
316 "Couldn't instanciate property extractor class " + className
317 ).initCause(ex);
318 }
319 }
320
321 public UMOTransactionConfig getTransactionConfig()
322 {
323 return transactionConfig;
324 }
325
326 public void setTransactionConfig(UMOTransactionConfig transactionConfig)
327 {
328 this.transactionConfig = transactionConfig;
329 }
330
331 public boolean isDynamicEndpoints()
332 {
333 return false;
334 }
335 }