Coverage Report - org.mule.transport.AbstractReceiverWorker
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractReceiverWorker
0%
0/28
N/A
0
AbstractReceiverWorker$1
0%
0/27
0%
0/16
0
 
 1  
 /*
 2  
  * $Id: AbstractReceiverWorker.java 20498 2010-12-08 00:27:08Z tcarlson $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSoft, Inc.  All rights reserved.  http://www.mulesoft.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  
 package org.mule.transport;
 11  
 
 12  
 import org.mule.api.MessagingException;
 13  
 import org.mule.api.MuleContext;
 14  
 import org.mule.api.MuleEvent;
 15  
 import org.mule.api.MuleMessage;
 16  
 import org.mule.api.MuleSession;
 17  
 import org.mule.api.endpoint.InboundEndpoint;
 18  
 import org.mule.api.transaction.Transaction;
 19  
 import org.mule.api.transaction.TransactionCallback;
 20  
 import org.mule.api.transaction.TransactionException;
 21  
 import org.mule.api.transport.SessionHandler;
 22  
 import org.mule.session.LegacySessionHandler;
 23  
 import org.mule.session.MuleSessionHandler;
 24  
 import org.mule.transaction.TransactionCoordination;
 25  
 import org.mule.transaction.TransactionTemplate;
 26  
 
 27  
 import java.io.OutputStream;
 28  
 import java.util.ArrayList;
 29  
 import java.util.List;
 30  
 
 31  
 import javax.resource.spi.work.Work;
 32  
 
 33  
 import org.apache.commons.lang.SerializationException;
 34  
 
 35  
 /**
 36  
  * A base Worker used by Transport {@link org.mule.api.transport.MessageReceiver} implementations.
 37  
  */
 38  
 public abstract class AbstractReceiverWorker implements Work
 39  
 {
 40  
     protected List<Object> messages;
 41  
     protected InboundEndpoint endpoint;
 42  
     protected AbstractMessageReceiver receiver;
 43  
     protected OutputStream out;
 44  
 
 45  
     public AbstractReceiverWorker(List<Object> messages, AbstractMessageReceiver receiver)
 46  
     {
 47  0
         this(messages, receiver, null);
 48  0
     }
 49  
 
 50  
     public AbstractReceiverWorker(List<Object> messages, AbstractMessageReceiver receiver, OutputStream out)
 51  0
     {
 52  0
         this.messages = messages;
 53  0
         this.receiver = receiver;
 54  0
         this.endpoint = receiver.getEndpoint();
 55  0
         this.out = out;
 56  0
     }
 57  
 
 58  
     /**
 59  
      * This will run the receiver logic and call {@link #release()} once {@link #doRun()} completes.
 60  
     *
 61  
     */
 62  
     public final void run()
 63  
     {
 64  0
         doRun();
 65  0
         release();
 66  0
     }
 67  
 
 68  
     /**
 69  
      * The actual logic used to receive messages from the underlying transport.  The default implementation
 70  
      * will execute the processing of messages within a TransactionTemplate.  This template will manage the
 71  
      * transaction lifecycle for the list of messages associated with this receiver worker.
 72  
      */
 73  
     protected void doRun()
 74  
     {
 75  
         //  MuleContext is used down the line for
 76  
         // getTransactionManager() (XaTransactionFactory) and getQueueManager() (VMTransaction)
 77  0
         final MuleContext muleContext = receiver.getConnector().getMuleContext();
 78  0
         TransactionTemplate tt = new TransactionTemplate(endpoint.getTransactionConfig(), muleContext);
 79  
 
 80  
         // Receive messages and process them in a single transaction
 81  
         // Do not enable threading here, but serveral workers
 82  
         // may have been started
 83  0
         TransactionCallback<?> cb = new TransactionCallback()
 84  0
         {
 85  
             public Object doInTransaction() throws Exception
 86  
             {
 87  0
                 Transaction tx = TransactionCoordination.getInstance().getTransaction();
 88  0
                 if (tx != null)
 89  
                 {
 90  0
                     bindTransaction(tx);
 91  
                 }
 92  0
                 List<Object> results = new ArrayList<Object>(messages.size());
 93  
 
 94  0
                 for (Object payload : messages)
 95  
                 {
 96  0
                     payload = preProcessMessage(payload);
 97  0
                     if (payload != null)
 98  
                     {
 99  0
                         MuleMessage muleMessage = receiver.createMuleMessage(payload, endpoint.getEncoding());
 100  0
                         preRouteMuleMessage(muleMessage);
 101  
 
 102  
                         // TODO Move getSessionHandler() to the Connector interface
 103  
                         SessionHandler handler;
 104  0
                         if (endpoint.getConnector() instanceof AbstractConnector)
 105  
                         {
 106  0
                             handler = ((AbstractConnector) endpoint.getConnector()).getSessionHandler();
 107  
                         }
 108  
                         else
 109  
                         {
 110  0
                             handler = new MuleSessionHandler();
 111  
                         }
 112  
                         MuleSession session;
 113  
                         try
 114  
                         {
 115  0
                             session = handler.retrieveSessionInfoFromMessage(muleMessage);
 116  
                         }
 117  0
                         catch (SerializationException e)
 118  
                         {
 119  
                             // EE-1820 Support message headers generated by previous Mule versions
 120  0
                             session = new LegacySessionHandler().retrieveSessionInfoFromMessage(muleMessage);
 121  0
                         }
 122  
                         
 123  
                         MuleEvent resultEvent;
 124  0
                         if (session != null)
 125  
                         {
 126  0
                             resultEvent = receiver.routeMessage(muleMessage, session, tx, out);
 127  
                         }
 128  
                         else
 129  
                         {
 130  0
                             resultEvent = receiver.routeMessage(muleMessage, tx, out);
 131  
                         }
 132  0
                         MuleMessage result = resultEvent == null ?  null : resultEvent.getMessage();
 133  0
                         if (result != null)
 134  
                         {
 135  0
                             payload = postProcessMessage(result);
 136  0
                             if (payload != null)
 137  
                             {
 138  0
                                 results.add(payload);
 139  
                             }
 140  
                         }
 141  0
                     }
 142  
                 }
 143  0
                 return results;
 144  
             }
 145  
         };
 146  
 
 147  
         try
 148  
         {
 149  0
             List results = (List) tt.execute(cb);
 150  0
             handleResults(results);
 151  
         }
 152  0
         catch (MessagingException e)
 153  
         {
 154  0
             receiver.getFlowConstruct().getExceptionListener().handleException(e, e.getEvent());
 155  
         }
 156  0
         catch (Exception e)
 157  
         {
 158  0
             muleContext.getExceptionListener().handleException(e);
 159  
         }
 160  
         finally
 161  
         {
 162  0
             messages.clear();
 163  0
         }
 164  0
     }
 165  
 
 166  
     /**
 167  
      * This callback is called before a message is routed into Mule and can be used by the worker to set connection
 168  
      * specific properties to message before it gets routed
 169  
      *
 170  
      * @param message the next message to be processed
 171  
      * @throws Exception
 172  
      */
 173  
     protected void preRouteMuleMessage(MuleMessage message) throws Exception
 174  
     {
 175  
         //no op
 176  0
     }
 177  
 
 178  
     /**
 179  
      * Template method used to bind the resources of this receiver to the transaction.  Only transactional
 180  
      * transports need implment this method
 181  
      * @param tx the current transaction or null if there is no transaction
 182  
      * @throws TransactionException
 183  
      */
 184  
     protected abstract void bindTransaction(Transaction tx) throws TransactionException;
 185  
 
 186  
     /**
 187  
      * When Mule has finished processing the current messages, there may be zero or more messages to process
 188  
      * by the receiver if request/response messaging is being used. The result(s) should be passed back to the callee.
 189  
      * @param messages a list of messages.  This argument will not be null
 190  
      * @throws Exception
 191  
      */
 192  
     protected void handleResults(List messages) throws Exception
 193  
     {
 194  
         //no op
 195  0
     }
 196  
 
 197  
     /**
 198  
      * Before a message is passed into Mule this callback is called and can be used by the worker to inspect the
 199  
      * message before it gets sent to Mule
 200  
      * @param message the next message to be processed
 201  
      * @return the message to be processed. If Null is returned the message will not get processed.
 202  
      * @throws Exception
 203  
      */
 204  
     protected Object preProcessMessage(Object message) throws Exception
 205  
     {
 206  
         //no op
 207  0
         return message;
 208  
     }
 209  
 
 210  
     /**
 211  
      * If a result is returned back this method will get called before the message is added to te list of
 212  
      * results (these are later passed to {@link #handleResults(java.util.List)})
 213  
      * @param message the result message, this will never be null
 214  
      * @return the message to add to the list of results. If null is returned nothing is added to the
 215  
      * list of results
 216  
      * @throws Exception
 217  
      */
 218  
     protected MuleMessage postProcessMessage(MuleMessage message) throws Exception
 219  
     {
 220  
         //no op
 221  0
         return message;
 222  
     }
 223  
 
 224  
 
 225  
     /**
 226  
      * This method is called once this worker is no longer required.  Any resources *only* associated with
 227  
      * this worker should be cleaned up here.
 228  
      */
 229  
     public void release()
 230  
     {
 231  
         // no op
 232  0
     }
 233  
 }