Coverage Report - org.mule.transport.servlet.MuleReceiverServlet
 
Classes in this File Line Coverage Branch Coverage Complexity
MuleReceiverServlet
0%
0/132
0%
0/50
0
 
 1  
 /*
 2  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.com
 3  
  * The software in this package is published under the terms of the CPAL v1.0
 4  
  * license, a copy of which has been included with this distribution in the
 5  
  * LICENSE.txt file.
 6  
  */
 7  
 package org.mule.transport.servlet;
 8  
 
 9  
 import org.mule.api.MuleEvent;
 10  
 import org.mule.api.MuleException;
 11  
 import org.mule.api.MuleMessage;
 12  
 import org.mule.api.endpoint.EndpointException;
 13  
 import org.mule.api.endpoint.EndpointURI;
 14  
 import org.mule.api.endpoint.InboundEndpoint;
 15  
 import org.mule.api.lifecycle.InitialisationException;
 16  
 import org.mule.api.transport.MessageReceiver;
 17  
 import org.mule.api.transport.NoReceiverForEndpointException;
 18  
 import org.mule.api.transport.PropertyScope;
 19  
 import org.mule.endpoint.DynamicURIInboundEndpoint;
 20  
 import org.mule.endpoint.MuleEndpointURI;
 21  
 import org.mule.routing.filters.WildcardFilter;
 22  
 import org.mule.transport.http.HttpConnector;
 23  
 import org.mule.transport.http.HttpConstants;
 24  
 import org.mule.transport.http.HttpMessageReceiver;
 25  
 import org.mule.transport.http.i18n.HttpMessages;
 26  
 import org.mule.transport.service.TransportFactory;
 27  
 import org.mule.transport.servlet.i18n.ServletMessages;
 28  
 import org.mule.util.PropertiesUtils;
 29  
 
 30  
 import java.io.IOException;
 31  
 import java.util.Map;
 32  
 import java.util.Properties;
 33  
 
 34  
 import javax.servlet.ServletException;
 35  
 import javax.servlet.http.HttpServletRequest;
 36  
 import javax.servlet.http.HttpServletResponse;
 37  
 
 38  
 /**
 39  
  * Receives Http requests via a Servlet and routes them to listeners with servlet://
 40  
  * endpoints
 41  
  * <p/>
 42  
  */
 43  0
 public class MuleReceiverServlet extends AbstractReceiverServlet
 44  
 {
 45  
     /**
 46  
      * Serial version
 47  
      */
 48  
     private static final long serialVersionUID = 6631307373079767439L;
 49  
 
 50  0
     protected ServletConnector connector = null;
 51  
 
 52  0
     private boolean useCachedHttpServletRequest = false;
 53  
 
 54  
     @Override
 55  
     protected void doInit() throws ServletException
 56  
     {
 57  0
         connector = getOrCreateServletConnector(getServletConfig().getInitParameter(SERVLET_CONNECTOR_NAME_PROPERTY));
 58  0
     }
 59  
 
 60  
     protected ServletConnector getOrCreateServletConnector(String name) throws ServletException
 61  
     {
 62  
         ServletConnector servletConnector;
 63  0
         if (name == null)
 64  
         {
 65  0
             servletConnector = (ServletConnector) new TransportFactory(muleContext).getConnectorByProtocol("servlet");
 66  0
             if (servletConnector == null)
 67  
             {
 68  0
                 servletConnector = new ServletConnector(muleContext);
 69  0
                 servletConnector.setName("_generatedServletConnector");
 70  
                 try
 71  
                 {
 72  0
                     muleContext.getRegistry().registerConnector(servletConnector);
 73  
                 }
 74  0
                 catch (MuleException e)
 75  
                 {
 76  0
                     throw new ServletException("Failed to register the ServletConnector", e);
 77  0
                 }
 78  
             }
 79  
         }
 80  
         else
 81  
         {
 82  0
             servletConnector = (ServletConnector) muleContext.getRegistry().lookupConnector(name);
 83  0
             if (servletConnector == null)
 84  
             {
 85  0
                 throw new ServletException(ServletMessages.noServletConnectorFound(name).toString());
 86  
             }
 87  
         }
 88  0
         this.useCachedHttpServletRequest = servletConnector.isUseCachedHttpServletRequest();
 89  0
         return servletConnector;
 90  
     }
 91  
 
 92  
     protected void setupRequestMessage(HttpServletRequest request,
 93  
                                        MuleMessage requestMessage,
 94  
                                        MessageReceiver receiver)
 95  
     {
 96  
 
 97  0
         EndpointURI uri = receiver.getEndpointURI();
 98  0
         String reqUri = request.getRequestURI();
 99  0
         requestMessage.setProperty(HttpConnector.HTTP_REQUEST_PATH_PROPERTY, reqUri, PropertyScope.INBOUND);
 100  
 
 101  0
         String queryString = request.getQueryString();
 102  0
         if (queryString != null)
 103  
         {
 104  0
             reqUri += "?" + queryString;
 105  
         }
 106  
 
 107  0
         requestMessage.setProperty(HttpConnector.HTTP_REQUEST_PROPERTY, reqUri, PropertyScope.INBOUND);
 108  
 
 109  
         String path;
 110  0
         if ("servlet".equals(uri.getScheme()))
 111  
         {
 112  0
             path = HttpConnector.normalizeUrl(request.getContextPath());
 113  0
             if ("/".equals(path))
 114  
             {
 115  0
                 path = HttpConnector.normalizeUrl(request.getServletPath());
 116  
             }
 117  
             else
 118  
             {
 119  0
                 path = path + HttpConnector.normalizeUrl(request.getServletPath());
 120  
             }
 121  
 
 122  0
             String pathPart2 = uri.getAddress();
 123  
 
 124  0
             if (!path.endsWith("/"))
 125  
             {
 126  
                 // "/foo" + "bar"
 127  0
                 path = path + HttpConnector.normalizeUrl(pathPart2);
 128  
             }
 129  0
             else if (pathPart2.startsWith("/"))
 130  
             {
 131  
                 // "/foo/" + "/bar"
 132  0
                 path = path + pathPart2.substring(1);
 133  
             }
 134  
             else
 135  
             {
 136  
                 // "/foo/" + "bar"
 137  0
                 path = path + pathPart2;
 138  
             }
 139  0
         }
 140  
         else
 141  
         {
 142  
             // The Jetty transport has normal paths
 143  0
             path = HttpConnector.normalizeUrl(uri.getPath());
 144  
         }
 145  
 
 146  0
         requestMessage.setProperty(HttpConnector.HTTP_CONTEXT_PATH_PROPERTY, path, PropertyScope.INBOUND);
 147  
 
 148  
         // Call this to keep API compatability
 149  0
         setupRequestMessage(request, requestMessage);
 150  0
     }
 151  
 
 152  
 
 153  
     protected void setupRequestMessage(HttpServletRequest request, MuleMessage requestMessage)
 154  
     {
 155  
         // template method
 156  0
     }
 157  
 
 158  
 
 159  
     // The service() method cannot be overriden blindly as explained below.
 160  
     //
 161  
     // Until we use a version of the servlet spec that supports the PATCH method, we
 162  
     // have to override service() nevertheless to avoid super's implementation
 163  
     // barfing on a PATCH request.
 164  
     @Override
 165  
     protected void service(HttpServletRequest request, HttpServletResponse response)
 166  
         throws ServletException, IOException
 167  
     {
 168  0
         String method = request.getMethod();
 169  0
         if (method.equalsIgnoreCase(HttpConstants.METHOD_PATCH))
 170  
         {
 171  0
             doAllMethods(request, response);
 172  
         }
 173  
         else
 174  
         {
 175  0
             super.service(request, response);
 176  
         }
 177  0
     }
 178  
 
 179  
     // We cannot override the service method and maintain MuleRESTServletReceiver
 180  
     // functionality. See MULE-4806.
 181  
 
 182  
     @Override
 183  
     protected void doGet(HttpServletRequest req, HttpServletResponse resp)
 184  
         throws ServletException, IOException
 185  
     {
 186  0
         doAllMethods(req, resp);
 187  0
     }
 188  
 
 189  
     @Override
 190  
     protected void doPost(HttpServletRequest req, HttpServletResponse resp)
 191  
         throws ServletException, IOException
 192  
     {
 193  0
         doAllMethods(req, resp);
 194  0
     }
 195  
 
 196  
     @Override
 197  
     protected void doHead(HttpServletRequest req, HttpServletResponse resp)
 198  
         throws ServletException, IOException
 199  
     {
 200  0
         doAllMethods(req, resp);
 201  0
     }
 202  
     @Override
 203  
     protected void doDelete(HttpServletRequest req, HttpServletResponse resp)
 204  
         throws ServletException, IOException
 205  
     {
 206  0
         doAllMethods(req, resp);
 207  0
     }
 208  
 
 209  
     @Override
 210  
     protected void doPut(HttpServletRequest req, HttpServletResponse resp)
 211  
         throws ServletException, IOException
 212  
     {
 213  0
         doAllMethods(req, resp);
 214  0
     }
 215  
     @Override
 216  
     protected void doOptions(HttpServletRequest req, HttpServletResponse resp)
 217  
         throws ServletException, IOException
 218  
     {
 219  0
         doAllMethods(req, resp);
 220  0
     }
 221  
     @Override
 222  
     protected void doTrace(HttpServletRequest req, HttpServletResponse resp)
 223  
         throws ServletException, IOException
 224  
     {
 225  0
         doAllMethods(req, resp);
 226  0
     }
 227  
 
 228  
     protected void doAllMethods(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
 229  
     {
 230  
         try
 231  
         {
 232  0
             if (this.useCachedHttpServletRequest)
 233  
             {
 234  0
                 request = new CachedHttpServletRequest(request);
 235  
             }
 236  0
             MessageReceiver receiver = getReceiverForURI(request);
 237  
 
 238  0
             MuleMessage requestMessage = receiver.createMuleMessage(request);
 239  0
             requestMessage.setProperty(HttpConnector.HTTP_METHOD_PROPERTY, request.getMethod(), PropertyScope.INBOUND);
 240  
 
 241  0
             setupRequestMessage(request, requestMessage, receiver);
 242  
 
 243  0
             MuleEvent event = routeMessage(receiver, requestMessage, request);
 244  0
             MuleMessage result = event == null ? null : event.getMessage();
 245  0
             writeResponse(response, result);
 246  
         }
 247  0
         catch (Exception e)
 248  
         {
 249  0
             handleException(e, ServletMessages.failedToProcessRequest().getMessage(), response);
 250  0
         }
 251  0
     }
 252  
 
 253  
     protected MuleEvent routeMessage(MessageReceiver receiver, MuleMessage requestMessage, HttpServletRequest request)
 254  
             throws MuleException
 255  
     {
 256  0
         return receiver.routeMessage(requestMessage);
 257  
     }
 258  
 
 259  
     protected MessageReceiver getReceiverForURI(HttpServletRequest httpServletRequest)
 260  
             throws EndpointException
 261  
     {
 262  0
         String uri = getReceiverName(httpServletRequest);
 263  0
         if (uri == null)
 264  
         {
 265  0
             throw new EndpointException(
 266  
                     HttpMessages.unableToGetEndpointUri(httpServletRequest.getRequestURI()));
 267  
         }
 268  
 
 269  0
         MessageReceiver receiver = getReceivers().get(uri);
 270  
 
 271  
         // Lets see if the uri matches up with the last part of
 272  
         // any of the receiver keys.
 273  0
         if (receiver == null)
 274  
         {
 275  0
             receiver = HttpMessageReceiver.findReceiverByStem(connector.getReceivers(), uri);
 276  
         }
 277  
 
 278  0
         if (receiver == null)
 279  
         {
 280  0
             receiver = matchReceiverByWildcard(uri, receiver);
 281  
         }
 282  
 
 283  0
         if (receiver == null)
 284  
         {
 285  0
             throw new NoReceiverForEndpointException(uri);
 286  
         }
 287  
 
 288  0
         InboundEndpoint endpoint = receiver.getEndpoint();
 289  
 
 290  
         // Ensure that this receiver is using a dynamic (mutable) endpoint
 291  0
         if (!(endpoint instanceof DynamicURIInboundEndpoint))
 292  
         {
 293  0
             endpoint = new DynamicURIInboundEndpoint(receiver.getEndpoint());
 294  0
             receiver.setEndpoint(endpoint);
 295  
         }
 296  
 
 297  
         // Tell the dynamic endpoint about our new URL
 298  
         //Note we don't use the servlet: prefix since we need to be dealing with the raw endpoint here
 299  0
         EndpointURI epURI = new MuleEndpointURI(getRequestUrl(httpServletRequest), muleContext);
 300  
 
 301  
         try
 302  
         {
 303  0
             epURI.initialise();
 304  0
             epURI.getParams().setProperty("servlet.endpoint", "true");
 305  0
             ((DynamicURIInboundEndpoint) endpoint).setEndpointURI(epURI);
 306  
         }
 307  0
         catch (InitialisationException e)
 308  
         {
 309  0
             throw new EndpointException(e);
 310  0
         }
 311  0
         return receiver;
 312  
     }
 313  
 
 314  
     protected MessageReceiver matchReceiverByWildcard(String uri, MessageReceiver receiver)
 315  
     {
 316  
         // Now match wild cards
 317  0
         for (Object key : getReceivers().keySet())
 318  
         {
 319  0
             if (new WildcardFilter(key.toString()).accept(uri))
 320  
             {
 321  0
                 receiver = connector.getReceivers().get(key);
 322  0
                 break;
 323  
             }
 324  
         }
 325  0
         return receiver;
 326  
     }
 327  
 
 328  
     protected String getRequestUrl(HttpServletRequest httpServletRequest)
 329  
     {
 330  0
         StringBuffer url = new StringBuffer();
 331  
 
 332  0
         url.append(httpServletRequest.getScheme());
 333  0
         url.append("://");
 334  0
         url.append(httpServletRequest.getServerName());
 335  0
         url.append(":");
 336  0
         url.append(httpServletRequest.getServerPort());
 337  0
         url.append(httpServletRequest.getServletPath());
 338  
 
 339  0
         String pathInfo = httpServletRequest.getPathInfo();
 340  0
         if (pathInfo != null)
 341  
         {
 342  0
             url.append(pathInfo);
 343  
         }
 344  
 
 345  0
         String queryString = httpServletRequest.getQueryString();
 346  0
         if (queryString != null)
 347  
         {
 348  0
             url.append("?");
 349  0
             url.append(queryString);
 350  
         }
 351  0
         return url.toString();
 352  
     }
 353  
 
 354  
     protected String getReceiverName(HttpServletRequest httpServletRequest)
 355  
     {
 356  0
         String name = httpServletRequest.getPathInfo();
 357  0
         if (name == null)
 358  
         {
 359  0
             name = httpServletRequest.getServletPath();
 360  0
             if (name == null)
 361  
             {
 362  0
                 name = httpServletRequest.getParameter("endpoint");
 363  0
                 if (name == null)
 364  
                 {
 365  0
                     Properties params = PropertiesUtils.getPropertiesFromQueryString(httpServletRequest.getQueryString());
 366  0
                     name = params.getProperty("endpoint");
 367  0
                     if (name == null)
 368  
                     {
 369  0
                         return null;
 370  
                     }
 371  
                 }
 372  
             }
 373  
         }
 374  
 
 375  0
         if (name.startsWith("/"))
 376  
         {
 377  0
             name = name.substring(1);
 378  
         }
 379  0
         return name;
 380  
     }
 381  
 
 382  
     protected Map<Object, MessageReceiver> getReceivers()
 383  
     {
 384  0
         return connector.getReceivers();
 385  
     }
 386  
 }