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