Coverage Report - org.mule.transport.servlet.jetty.JettyContinuationsReceiverServlet
 
Classes in this File Line Coverage Branch Coverage Complexity
JettyContinuationsReceiverServlet
0%
0/41
0%
0/14
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.jetty;
 8  
 
 9  
 import org.mule.DefaultMuleEvent;
 10  
 import org.mule.api.MessagingException;
 11  
 import org.mule.api.MuleEvent;
 12  
 import org.mule.api.MuleMessage;
 13  
 import org.mule.api.transport.MessageReceiver;
 14  
 import org.mule.api.transport.PropertyScope;
 15  
 import org.mule.transport.http.HttpConnector;
 16  
 
 17  
 import java.io.IOException;
 18  
 
 19  
 import javax.servlet.ServletException;
 20  
 import javax.servlet.http.HttpServletRequest;
 21  
 import javax.servlet.http.HttpServletResponse;
 22  
 
 23  
 import org.mortbay.util.ajax.Continuation;
 24  
 import org.mortbay.util.ajax.ContinuationSupport;
 25  
 
 26  0
 public class JettyContinuationsReceiverServlet extends JettyReceiverServlet
 27  
 {
 28  
     // mutex used to make sure that the continuation is not resumed before it is suspended. 
 29  0
     private Object mutex = new Object();
 30  
     
 31  
     @Override
 32  
     protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
 33  
     {
 34  
         try
 35  
         {
 36  0
             MuleMessage responseMessage = null;
 37  
             
 38  0
             synchronized (mutex)
 39  
             {
 40  0
                 Continuation continuation = ContinuationSupport.getContinuation(request, mutex);
 41  
                 
 42  0
                 if (!continuation.isPending())
 43  
                 {
 44  
                     // case where we are processing this request for the first time (suspend has not been called)
 45  
                     
 46  0
                     MessageReceiver receiver = getReceiverForURI(request);
 47  
                     
 48  0
                     MuleMessage requestMessage = receiver.createMuleMessage(request);
 49  0
                     requestMessage.setProperty(HttpConnector.HTTP_METHOD_PROPERTY, request.getMethod(), PropertyScope.INBOUND);
 50  
     
 51  0
                     ContinuationsReplyTo continuationsReplyTo = new ContinuationsReplyTo(continuation, mutex);
 52  
                     //This will allow Mule to continue the response once the service has do its processing
 53  0
                     requestMessage.setReplyTo(continuationsReplyTo);
 54  0
                     setupRequestMessage(request, requestMessage, receiver);
 55  
                     
 56  0
                     if (receiver instanceof JettyHttpMessageReceiver)
 57  
                     {
 58  
                         //we force asynchronous in the {@link #routeMessage} method
 59  0
                         JettyHttpMessageReceiver jettyReceiver = (JettyHttpMessageReceiver) receiver;
 60  0
                         jettyReceiver.routeMessageAsync(requestMessage, continuationsReplyTo);
 61  
                         
 62  
                         // suspend indefinitely
 63  
                         //TODO: perhaps we can make this configurable just like Http's keepSocketAlive is
 64  0
                         continuation.suspend(0L);
 65  0
                     }
 66  
                     else
 67  
                     {
 68  0
                         responseMessage = receiver.routeMessage(requestMessage).getMessage();
 69  0
                         writeResponse(response, responseMessage);
 70  
                     }
 71  0
                 }
 72  
                 else
 73  
                 {
 74  
                     // case where we are processing this request for the second time. 
 75  0
                     if (continuation.isResumed())
 76  
                     {
 77  
                         // the continuation was resumed so the response should be there
 78  0
                         Object r = continuation.getObject();
 79  
                         // response object is either a MuleMessage of an Exception if there was an error
 80  0
                         if (r instanceof MuleMessage)
 81  
                         {
 82  0
                             responseMessage = (MuleMessage) r;
 83  
                             // clear the object because jetty reuses continuations for the same connection
 84  0
                             continuation.setObject(null);
 85  
                             
 86  0
                             writeResponse(response, responseMessage);
 87  
                         }
 88  0
                         else if (r instanceof Exception)
 89  
                         {
 90  0
                             if (r instanceof MessagingException)
 91  
                             {
 92  
                                 // Reset access control on the MuleEvent because its message's owner is a different thread
 93  
                                 // Otherwise when the message is modified during exception handling, it will fail
 94  0
                                 MessagingException me = (MessagingException) r;
 95  0
                                 MuleEvent event = me.getEvent();
 96  0
                                 if (event instanceof DefaultMuleEvent)
 97  
                                 {
 98  0
                                     ((DefaultMuleEvent) event).resetAccessControl();
 99  
                                 }
 100  
                             }
 101  0
                             throw (Exception) r;
 102  
                         }
 103  
                     }
 104  
                 }
 105  0
             }
 106  
         }
 107  0
         catch (RuntimeException e)
 108  
         {
 109  
             // Jetty continuations throw a subclass of RuntimeException when suspend is don't treat them as errors
 110  0
             throw new ServletException(e);
 111  
         }
 112  0
         catch (Exception e)
 113  
         {
 114  0
             String message = e.getMessage();
 115  0
             handleException(e, message, response);
 116  0
         }
 117  0
     }
 118  
 }