View Javadoc

1   /*
2    * $Id: AbstractOutboundRouter.java 7976 2007-08-21 14:26:13Z dirk.olmes $
3    * --------------------------------------------------------------------------------------
4    * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
5    *
6    * The software in this package is published under the terms of the CPAL v1.0
7    * license, a copy of which has been included with this distribution in the
8    * LICENSE.txt file.
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   * <code>AbstractOutboundRouter</code> is a base router class that tracks
38   * statistics about message processing through the router.
39   * 
40   * @author <a href="mailto:ross.mason@symphonysoft.com">Ross Mason</a>
41   * @version $Revision: 7976 $
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       * logger used by this class
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                 // ignore
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                 // ignore
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             // if replyTo is set we'll probably want the correlationId set as
156             // well
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                 // buf.append(", ").append("Seq=").append(seq);
210                 // buf.append(", ").append("Group Size=").append(group);
211                 logger.debug(buf.toString());
212             }
213             message.setCorrelationId(correlation);
214             // message.setCorrelationGroupSize(group);
215             // message.setCorrelationSequence(seq);
216         }
217     }
218 
219     public List getEndpoints()
220     {
221         return endpoints;
222     }
223 
224     public void setEndpoints(List endpoints)
225     {
226         // this.endpoints = new CopyOnWriteArrayList(endpoints);
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         //TODO RM** endpoint.setType(UMOEndpoint.ENDPOINT_TYPE_SENDER);
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 }