View Javadoc

1   /*
2    * $Id: InboundRouterCollection.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.inbound;
12  
13  import org.mule.config.MuleProperties;
14  import org.mule.management.stats.RouterStatistics;
15  import org.mule.routing.AbstractRouterCollection;
16  import org.mule.umo.MessagingException;
17  import org.mule.umo.UMOEvent;
18  import org.mule.umo.UMOException;
19  import org.mule.umo.UMOMessage;
20  import org.mule.umo.endpoint.UMOEndpoint;
21  import org.mule.umo.routing.RoutingException;
22  import org.mule.umo.routing.UMOInboundRouter;
23  import org.mule.umo.routing.UMOInboundRouterCollection;
24  import org.mule.util.StringMessageUtils;
25  import org.mule.util.StringUtils;
26  
27  import java.util.Iterator;
28  import java.util.List;
29  
30  import edu.emory.mathcs.backport.java.util.concurrent.CopyOnWriteArrayList;
31  
32  /**
33   * <code>InboundRouterCollection</code> is a collection of routers that will be
34   * invoked when an event is received. It is responsible for managing a collection of
35   * routers and also executing the routing logic. Each router must match against the
36   * current event for the event to be routed.
37   */
38  
39  public class InboundRouterCollection extends AbstractRouterCollection implements UMOInboundRouterCollection
40  {
41      private final List endpoints = new CopyOnWriteArrayList();
42  
43      public InboundRouterCollection()
44      {
45          super(RouterStatistics.TYPE_INBOUND);
46      }
47  
48      public UMOMessage route(UMOEvent event) throws MessagingException
49      {
50          // If the endpoint has a logical name, use it, otherwise use the URI.
51          String inboundEndpoint = 
52              // Endpoint identifier (deprecated)
53              event.getEndpoint().getEndpointURI().getEndpointName();
54  
55          if (StringUtils.isBlank(inboundEndpoint))
56          {
57              // Global endpoint
58              inboundEndpoint = event.getEndpoint().getName();
59          }
60          if (StringUtils.isBlank(inboundEndpoint))
61          {
62              // URI
63              inboundEndpoint = event.getEndpoint().getEndpointURI().getUri().toString();
64          }
65          event.getMessage().setProperty(MuleProperties.MULE_ORIGINATING_ENDPOINT_PROPERTY, inboundEndpoint);
66  
67          if (endpoints.size() > 0 && routers.size() == 0)
68          {
69              addRouter(new InboundPassThroughRouter());
70          }
71  
72          String componentName = event.getSession().getComponent().getDescriptor().getName();
73  
74          UMOEvent[] eventsToRoute = null;
75          boolean noRoute = true;
76          boolean match = false;
77          UMOInboundRouter umoInboundRouter = null;
78  
79          for (Iterator iterator = getRouters().iterator(); iterator.hasNext();)
80          {
81              umoInboundRouter = (UMOInboundRouter) iterator.next();
82  
83              if (umoInboundRouter.isMatch(event))
84              {
85                  match = true;
86                  eventsToRoute = umoInboundRouter.process(event);
87                  noRoute = (eventsToRoute == null);
88                  if (!matchAll)
89                  {
90                      break;
91                  }
92              }
93          }
94  
95          // If the stopFurtherProcessing flag has been set
96          // do not route events to the component.
97          // This is the case when using a ForwardingConsumer
98          // inbound router for example.
99          if (!event.isStopFurtherProcessing())
100         {
101             if (noRoute)
102             {
103                 // Update stats
104                 if (getStatistics().isEnabled())
105                 {
106                     getStatistics().incrementNoRoutedMessage();
107                 }
108                 if (!match)
109                 {
110                     if (getCatchAllStrategy() != null)
111                     {
112                         if (logger.isDebugEnabled())
113                         {
114                             logger.debug("Message did not match any routers on: " + componentName
115                                          + " - invoking catch all strategy");
116                         }
117                         if (getStatistics().isEnabled())
118                         {
119                             getStatistics().incrementCaughtMessage();
120                         }
121                         return getCatchAllStrategy().catchMessage(event.getMessage(), event.getSession(),
122                             event.isSynchronous());
123 
124                     }
125                     else
126                     {
127                         logger.warn("Message did not match any routers on: "
128                                     + componentName
129                                     + " and there is no catch all strategy configured on this router.  Disposing message.");
130                         if (logger.isWarnEnabled())
131                         {
132                             try
133                             {
134                                 logger.warn("Message fragment is: "
135                                             + StringMessageUtils.truncate(event.getMessageAsString(), 100,
136                                                 true));
137                             }
138                             catch (UMOException e)
139                             {
140                                 // ignore
141                             }
142                         }
143                     }
144                 }
145             }
146             else
147             {
148                 try
149                 {
150                     UMOMessage messageResult = null;
151                     if (eventsToRoute != null)
152                     {
153                         for (int i = 0; i < eventsToRoute.length; i++)
154                         {
155                             // Set the originating endpoint so we'll know where this event came from further down the pipeline.
156                             if (event.getMessage().getProperty(MuleProperties.MULE_ORIGINATING_ENDPOINT_PROPERTY) == null)
157                             {
158                                 event.getMessage().setProperty(MuleProperties.MULE_ORIGINATING_ENDPOINT_PROPERTY, inboundEndpoint);
159                             }
160 
161                             if (event.isSynchronous())
162                             {
163                                 messageResult = send(eventsToRoute[i]);
164                             }
165                             else
166                             {
167                                 dispatch(eventsToRoute[i]);
168                             }
169                             // Update stats
170                             if (getStatistics().isEnabled())
171                             {
172                                 getStatistics().incrementRoutedMessage(eventsToRoute[i].getEndpoint());
173                             }
174                         }
175                     }
176                     return messageResult;
177                 }
178                 catch (UMOException e)
179                 {
180                     throw new RoutingException(event.getMessage(), event.getEndpoint(), e);
181                 }
182             }
183         }
184         return (eventsToRoute != null && eventsToRoute.length > 0
185                         ? eventsToRoute[eventsToRoute.length - 1].getMessage() : null);
186 
187     }
188 
189     public void dispatch(UMOEvent event) throws UMOException
190     {
191         event.getSession().dispatchEvent(event);
192     }
193 
194     public UMOMessage send(UMOEvent event) throws UMOException
195     {
196 
197         return event.getSession().sendEvent(event);
198     }
199 
200     public void addRouter(UMOInboundRouter router)
201     {
202         routers.add(router);
203     }
204 
205     public UMOInboundRouter removeRouter(UMOInboundRouter router)
206     {
207         if (routers.remove(router))
208         {
209             return router;
210         }
211         else
212         {
213             return null;
214         }
215     }
216 
217     public void addEndpoint(UMOEndpoint endpoint)
218     {
219         if (endpoint != null)
220         {
221             endpoint.setType(UMOEndpoint.ENDPOINT_TYPE_RECEIVER);
222             endpoints.add(endpoint);
223         }
224         else
225         {
226             throw new IllegalArgumentException("endpoint = null");
227         }
228     }
229 
230     public boolean removeEndpoint(UMOEndpoint endpoint)
231     {
232         return endpoints.remove(endpoint);
233     }
234 
235     public List getEndpoints()
236     {
237         return endpoints;
238     }
239 
240     public void setEndpoints(List endpoints)
241     {
242         if (endpoints != null)
243         {
244             // Force all endpoints' type to RECEIVER just in case.
245             for (Iterator it = endpoints.iterator(); it.hasNext();)
246             {
247                 ((UMOEndpoint) it.next()).setType(UMOEndpoint.ENDPOINT_TYPE_RECEIVER);
248             }
249 
250             this.endpoints.clear();
251             this.endpoints.addAll(endpoints);
252         }
253         else
254         {
255             throw new IllegalArgumentException("List of endpoints = null");
256         }
257     }
258 
259     /**
260      * @param name the Endpoint identifier
261      * @return the Endpoint or null if the endpointUri is not registered
262      * @see org.mule.umo.routing.UMOInboundRouterCollection
263      */
264     public UMOEndpoint getEndpoint(String name)
265     {
266         UMOEndpoint endpointDescriptor;
267         for (Iterator iterator = endpoints.iterator(); iterator.hasNext();)
268         {
269             endpointDescriptor = (UMOEndpoint) iterator.next();
270             if (endpointDescriptor.getName().equals(name))
271             {
272                 return endpointDescriptor;
273             }
274         }
275         return null;
276     }
277 }