View Javadoc

1   /*
2    * $Id: MuleReceiverServlet.java 12320 2008-07-13 04:58:28Z rossmason $
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.transport.servlet;
12  
13  import org.mule.DefaultMuleMessage;
14  import org.mule.RegistryContext;
15  import org.mule.api.MuleException;
16  import org.mule.api.MuleMessage;
17  import org.mule.api.endpoint.EndpointException;
18  import org.mule.api.lifecycle.InitialisationException;
19  import org.mule.api.transport.MessageReceiver;
20  import org.mule.api.transport.NoReceiverForEndpointException;
21  import org.mule.endpoint.DynamicURIInboundEndpoint;
22  import org.mule.endpoint.MuleEndpointURI;
23  import org.mule.transport.AbstractMessageReceiver;
24  import org.mule.transport.http.HttpConnector;
25  import org.mule.transport.http.HttpConstants;
26  import org.mule.transport.http.HttpMessageReceiver;
27  import org.mule.transport.http.i18n.HttpMessages;
28  import org.mule.transport.service.TransportFactory;
29  import org.mule.transport.servlet.i18n.ServletMessages;
30  import org.mule.util.PropertiesUtils;
31  
32  import java.io.IOException;
33  import java.util.Iterator;
34  import java.util.Map;
35  import java.util.Properties;
36  
37  import javax.servlet.ServletConfig;
38  import javax.servlet.ServletException;
39  import javax.servlet.http.HttpServletRequest;
40  import javax.servlet.http.HttpServletResponse;
41  
42  /**
43   * Receives Http requests via a Servlet and routes the to listeners with servlet://
44   * endpoints
45   * <p/>
46   * There needs to be a ServletConnector configured on the Mule Server, this connector
47   * must have the servletUrl property set that matches the Url for the container that this
48   * Servlet is hosted in, i.e. something like http://192.168.10.21:8888
49   */
50  
51  public class MuleReceiverServlet extends AbstractReceiverServlet
52  {
53      /** Serial version */
54      private static final long serialVersionUID = 6631307373079767439L;
55  
56      protected ServletConnector connector = null;
57  
58      protected void doInit(ServletConfig servletConfig) throws ServletException
59      {
60          String servletConnectorName = servletConfig.getInitParameter(SERVLET_CONNECTOR_NAME_PROPERTY);
61          if (servletConnectorName == null)
62          {
63              connector = (ServletConnector) TransportFactory.getConnectorByProtocol("servlet");
64              if (connector == null)
65              {
66                  throw new ServletException(ServletMessages.noConnectorForProtocolServlet().toString());
67              }
68          }
69          else
70          {
71              connector = (ServletConnector) RegistryContext.getRegistry().lookupConnector(servletConnectorName);
72              if (connector == null)
73              {
74                  throw new ServletException(ServletMessages.noServletConnectorFound(servletConnectorName).toString());
75              }
76          }
77      }
78  
79      protected void doHead(HttpServletRequest request, HttpServletResponse response)
80              throws ServletException, IOException
81      {
82          try
83          {
84              MuleMessage responseMessage = doMethod(request, "HEAD");
85              if (responseMessage != null)
86              {
87                  writeResponse(response, responseMessage);
88              }
89              else
90              {
91                  response.setStatus(HttpConstants.SC_OK);
92              }
93          }
94          catch (Exception e)
95          {
96              handleException(e, e.getMessage(), response);
97          }
98      }
99  
100     protected void doGet(HttpServletRequest request, HttpServletResponse response)
101             throws ServletException, IOException
102     {
103         try
104         {
105             MuleMessage responseMessage = doMethod(request, "GET");
106             writeResponse(response, responseMessage);
107         }
108         catch (RuntimeException e)
109         {
110             throw e;
111         }
112         catch (Exception e)
113         {
114             handleException(e, e.getMessage(), response);
115         }
116     }
117 
118     protected void setupRequestMessage(HttpServletRequest request, MuleMessage requestMessage)
119     {
120         requestMessage.setProperty(HttpConnector.HTTP_REQUEST_PROPERTY, request.getRequestURI());
121     }
122 
123     protected void doPost(HttpServletRequest request, HttpServletResponse response)
124             throws ServletException, IOException
125     {
126         try
127         {
128             MuleMessage responseMessage = doMethod(request, "POST");
129             if (responseMessage != null)
130             {
131                 writeResponse(response, responseMessage);
132             }
133         }
134         catch (RuntimeException e)
135         {
136             throw e;
137         }
138         catch (Exception e)
139         {
140             handleException(e, e.getMessage(), response);
141         }
142     }
143 
144     protected MuleMessage doMethod(HttpServletRequest request, String method)
145         throws MuleException
146     {
147         MessageReceiver receiver = getReceiverForURI(request);
148         
149         MuleMessage requestMessage = new DefaultMuleMessage(new HttpRequestMessageAdapter(request));
150         requestMessage.setProperty(HttpConnector.HTTP_METHOD_PROPERTY, method);
151         
152         setupRequestMessage(request, requestMessage);
153         
154         return routeMessage(receiver, requestMessage, request);
155     }
156 
157     protected MuleMessage routeMessage(MessageReceiver receiver, MuleMessage requestMessage, HttpServletRequest request)
158         throws MuleException
159     {
160         return receiver.routeMessage(requestMessage, true);
161     }
162 
163     protected void doOptions(HttpServletRequest request, HttpServletResponse response)
164             throws ServletException, IOException
165     {
166         try
167         {
168             MuleMessage responseMessage = doMethod(request, "OPTIONS");
169             if (responseMessage != null)
170             {
171                 writeResponse(response, responseMessage);
172             }
173         }
174         catch (Exception e)
175         {
176             handleException(e, e.getMessage(), response);
177         }
178     }
179 
180     protected void doPut(HttpServletRequest request, HttpServletResponse response)
181             throws ServletException, IOException
182     {
183         try
184         {
185             MuleMessage responseMessage = doMethod(request, "PUT");
186             if (responseMessage != null)
187             {
188                 writeResponse(response, responseMessage);
189             }
190         }
191 
192         catch (Exception e)
193         {
194             handleException(e, e.getMessage(), response);
195         }
196     }
197 
198     protected void doDelete(HttpServletRequest request, HttpServletResponse response)
199             throws ServletException, IOException
200     {
201         try
202         {
203             MuleMessage responseMessage = doMethod(request, "DELETE");
204             if (responseMessage != null)
205             {
206                 writeResponse(response, responseMessage);
207             }
208         }
209         catch (Exception e)
210         {
211             handleException(e, e.getMessage(), response);
212         }
213     }
214 
215     protected void doTrace(HttpServletRequest request, HttpServletResponse response)
216             throws ServletException, IOException
217     {
218         try
219         {
220             MuleMessage responseMessage = doMethod(request, "TRACE");
221             if (responseMessage != null)
222             {
223                 writeResponse(response, responseMessage);
224             }
225         }
226         catch (Exception e)
227         {
228             handleException(e, e.getMessage(), response);
229         }
230     }
231 
232     protected void doConnect(HttpServletRequest request, HttpServletResponse response)
233             throws ServletException, IOException
234     {
235         try
236         {
237             MuleMessage responseMessage = doMethod(request, "CONNECT");
238             if (responseMessage != null)
239             {
240                 writeResponse(response, responseMessage);
241             }
242         }
243         catch (Exception e)
244         {
245             handleException(e, e.getMessage(), response);
246         }
247     }
248 
249     protected MessageReceiver getReceiverForURI(HttpServletRequest httpServletRequest)
250             throws EndpointException
251     {
252         String uri = getReceiverName(httpServletRequest);
253         if (uri == null)
254         {
255             throw new EndpointException(
256                     HttpMessages.unableToGetEndpointUri(httpServletRequest.getRequestURI()));
257         }
258 
259         MessageReceiver receiver = (MessageReceiver) getReceivers().get(uri);
260 
261         if (receiver == null)
262         {
263             // Nothing found lets try stripping the path and only use the last
264             // path element
265             int i = uri.lastIndexOf("/");
266             if (i > -1)
267             {
268                 String tempUri = uri.substring(i + 1);
269                 receiver = (AbstractMessageReceiver) getReceivers().get(tempUri);
270             }
271 
272             // Lets see if the uri matches up with the last part of
273             // any of the receiver keys.
274             if (receiver == null)
275             {
276                 receiver = HttpMessageReceiver.findReceiverByStem(connector.getReceivers(), uri);
277             }
278 
279             // This is some bizarre piece of code so the XFire Servlet code works.
280             // We should remove this at some point (see XFireWsdlCallTestCase for a failure
281             // if this code is removed).
282             if (receiver == null)
283             {
284                 receiver = HttpMessageReceiver.findReceiverByStem(connector.getReceivers(), uri);
285             }
286 
287             // This is some bizarre piece of code so the XFire Servlet code works.
288             // We should remove this at some point (see XFireWsdlCallTestCase for a failure
289             // if this code is removed).
290             if (receiver == null)
291             {
292                 Map receivers = getReceivers();
293                 Iterator iter = receivers.keySet().iterator();
294                 while (iter.hasNext())
295                 {
296                     String key = iter.next().toString();
297                     i = key.lastIndexOf("/");
298                     if (i > -1)
299                     {
300                         String key2 = key.substring(i + 1);
301                         if (key2.equals(uri))
302                         {
303                             receiver = (AbstractMessageReceiver) receivers.get(key);
304                             break;
305                         }
306                     }
307                 }
308             }
309 
310             if (receiver == null)
311             {
312                 throw new NoReceiverForEndpointException("No receiver found for endpointUri: " + uri);
313             }
314         }
315         receiver.setEndpoint(new DynamicURIInboundEndpoint(receiver.getEndpoint(), new MuleEndpointURI(
316                 getRequestUrl(httpServletRequest))));
317         try
318         {
319             receiver.getEndpointURI().initialise();
320         }
321         catch (InitialisationException e)
322         {
323             throw new EndpointException(e);
324         }
325         return receiver;
326     }
327 
328     protected String getRequestUrl(HttpServletRequest httpServletRequest)
329     {
330         StringBuffer url = new StringBuffer();
331         url.append(connector.getProtocol().toLowerCase());
332         url.append(":");
333         url.append(httpServletRequest.getScheme());
334         url.append("://");
335         url.append(httpServletRequest.getServerName());
336         url.append(":");
337         url.append(httpServletRequest.getServerPort());
338         url.append("/");
339         url.append(getReceiverName(httpServletRequest));
340         if (httpServletRequest.getQueryString() != null)
341         {
342             url.append("?");
343             url.append(httpServletRequest.getQueryString());
344         }
345         return url.toString();
346     }
347 
348     protected String getReceiverName(HttpServletRequest httpServletRequest)
349     {
350         String name = httpServletRequest.getPathInfo();
351         if (name == null)
352         {
353             name = httpServletRequest.getServletPath();
354             if (name == null)
355             {
356                 name = httpServletRequest.getParameter("endpoint");
357                 if (name == null)
358                 {
359                     Properties params = PropertiesUtils.getPropertiesFromQueryString(httpServletRequest.getQueryString());
360                     name = params.getProperty("endpoint");
361                     if (name == null)
362                     {
363                         return null;
364                     }
365                 }
366             }
367         }
368 
369         if (name.startsWith("/"))
370         {
371             name = name.substring(1);
372         }
373         return name;
374     }
375 
376     protected Map getReceivers()
377     {
378         return connector.getReceivers();
379     }
380 }