Coverage Report - org.mule.transport.TransactedPollingMessageReceiver
 
Classes in this File Line Coverage Branch Coverage Complexity
TransactedPollingMessageReceiver
0%
0/38
0%
0/16
0
TransactedPollingMessageReceiver$1
0%
0/6
0%
0/6
0
TransactedPollingMessageReceiver$MessageProcessorWorker
0%
0/14
N/A
0
 
 1  
 /*
 2  
  * $Id: TransactedPollingMessageReceiver.java 19191 2010-08-25 21:05:23Z 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  
 
 11  
 package org.mule.transport;
 12  
 
 13  
 import org.mule.api.MuleException;
 14  
 import org.mule.api.MuleMessage;
 15  
 import org.mule.api.config.ThreadingProfile;
 16  
 import org.mule.api.construct.FlowConstruct;
 17  
 import org.mule.api.endpoint.InboundEndpoint;
 18  
 import org.mule.api.lifecycle.CreateException;
 19  
 import org.mule.api.transaction.TransactionCallback;
 20  
 import org.mule.api.transport.Connector;
 21  
 import org.mule.transaction.TransactionTemplate;
 22  
 
 23  
 import java.util.List;
 24  
 
 25  
 import javax.resource.spi.work.Work;
 26  
 
 27  
 import edu.emory.mathcs.backport.java.util.concurrent.CountDownLatch;
 28  
 
 29  
 /**
 30  
  * The TransactedPollingMessageReceiver is an abstract receiver that handles polling
 31  
  * and transaction management. Derived implementations of these class must be thread
 32  
  * safe as several threads can be started at once for an improved throughput.
 33  
  */
 34  
 public abstract class TransactedPollingMessageReceiver extends AbstractPollingMessageReceiver
 35  
 {
 36  
     /** determines whether messages will be received in a transaction template */
 37  0
     private boolean receiveMessagesInTransaction = true;
 38  
 
 39  
     /** determines whether Multiple receivers are created to improve throughput */
 40  0
     private boolean useMultipleReceivers = true;
 41  
 
 42  
     public TransactedPollingMessageReceiver(Connector connector,
 43  
                                             FlowConstruct flowConstruct,
 44  
                                             final InboundEndpoint endpoint) throws CreateException
 45  
     {
 46  0
         super(connector, flowConstruct, endpoint);
 47  0
         this.setReceiveMessagesInTransaction(endpoint.getTransactionConfig().isTransacted());
 48  0
     }
 49  
 
 50  
     /**
 51  
      * @deprecated please use
 52  
      *             {@link #TransactedPollingMessageReceiver(Connector, FlowConstruct, InboundEndpoint)}
 53  
      *             instead
 54  
      */
 55  
     @Deprecated
 56  
     public TransactedPollingMessageReceiver(Connector connector,
 57  
                                             FlowConstruct flowConstruct,
 58  
                                             final InboundEndpoint endpoint,
 59  
                                             long frequency) throws CreateException
 60  
     {
 61  0
         this(connector, flowConstruct, endpoint);
 62  0
         this.setFrequency(frequency);
 63  0
     }
 64  
 
 65  
     public boolean isReceiveMessagesInTransaction()
 66  
     {
 67  0
         return receiveMessagesInTransaction;
 68  
     }
 69  
 
 70  
     public void setReceiveMessagesInTransaction(boolean useTx)
 71  
     {
 72  0
         receiveMessagesInTransaction = useTx;
 73  0
     }
 74  
 
 75  
     public boolean isUseMultipleTransactedReceivers()
 76  
     {
 77  0
         return useMultipleReceivers;
 78  
     }
 79  
 
 80  
     public void setUseMultipleTransactedReceivers(boolean useMultiple)
 81  
     {
 82  0
         useMultipleReceivers = useMultiple;
 83  0
     }
 84  
 
 85  
     @Override
 86  
     public void doStart() throws MuleException
 87  
     {
 88  
         // Connector property overrides any implied value
 89  0
         this.setUseMultipleTransactedReceivers(connector.isCreateMultipleTransactedReceivers());
 90  
 
 91  0
         ThreadingProfile tp = connector.getReceiverThreadingProfile();
 92  0
         int numReceiversToStart = 1;
 93  
 
 94  0
         if (this.isReceiveMessagesInTransaction() && this.isUseMultipleTransactedReceivers()
 95  
                 && tp.isDoThreading())
 96  
         {
 97  0
             numReceiversToStart = connector.getNumberOfConcurrentTransactedReceivers();
 98  
         }
 99  
 
 100  0
         for (int i = 0; i < numReceiversToStart; i++)
 101  
         {
 102  0
             super.doStart();
 103  
         }
 104  0
     }
 105  
 
 106  
     @Override
 107  
     public void poll() throws Exception
 108  
     {
 109  0
         TransactionTemplate<Object> tt = new TransactionTemplate<Object>(endpoint.getTransactionConfig(), connector.getMuleContext());
 110  
 
 111  0
         if (this.isReceiveMessagesInTransaction())
 112  
         {
 113  
             // Receive messages and process them in a single transaction
 114  
             // Do not enable threading here, but several workers
 115  
             // may have been started
 116  0
             TransactionCallback<Object> cb = new TransactionCallback<Object>()
 117  0
             {
 118  
                 public Object doInTransaction() throws Exception
 119  
                 {
 120  
                     // this is not ideal, but jdbc receiver returns a list of maps, not List<MuleMessage>
 121  0
                     List messages = getMessages();
 122  0
                     if (messages != null && messages.size() > 0)
 123  
                     {
 124  0
                         for (Object message : messages)
 125  
                         {
 126  0
                             processMessage(message);
 127  
                         }
 128  
                     }
 129  0
                     return null;
 130  
                 }
 131  
             };
 132  0
             tt.execute(cb);
 133  0
         }
 134  
         else
 135  
         {
 136  
             // Receive messages and launch a worker for each message
 137  0
             List messages = getMessages();
 138  0
             if (messages != null && messages.size() > 0)
 139  
             {
 140  0
                 final CountDownLatch countdown = new CountDownLatch(messages.size());
 141  0
                 for (Object message : messages)
 142  
                 {
 143  
                     try
 144  
                     {
 145  0
                         this.getWorkManager().scheduleWork(
 146  
                                 new MessageProcessorWorker(tt, countdown, message));
 147  
                     }
 148  0
                     catch (Exception e)
 149  
                     {
 150  0
                         countdown.countDown();
 151  0
                         throw e;
 152  0
                     }
 153  
                 }
 154  0
                 countdown.await();
 155  
             }
 156  
         }
 157  0
     }
 158  
 
 159  
     protected class MessageProcessorWorker implements Work, TransactionCallback
 160  
     {
 161  
         private final TransactionTemplate tt;
 162  
         private final Object message;
 163  
         private final CountDownLatch latch;
 164  
 
 165  
         public MessageProcessorWorker(TransactionTemplate tt, CountDownLatch latch, Object message)
 166  0
         {
 167  0
             this.tt = tt;
 168  0
             this.message = message;
 169  0
             this.latch = latch;
 170  0
         }
 171  
 
 172  
         public void release()
 173  
         {
 174  
             // nothing to do
 175  0
         }
 176  
 
 177  
         public void run()
 178  
         {
 179  
             try
 180  
             {
 181  0
                 tt.execute(this);
 182  
             }
 183  0
             catch (Exception e)
 184  
             {
 185  0
                 connector.getMuleContext().getExceptionListener().handleException(e);
 186  
             }
 187  
             finally
 188  
             {
 189  0
                 latch.countDown();
 190  0
             }
 191  0
         }
 192  
 
 193  
         public Object doInTransaction() throws Exception
 194  
         {
 195  0
             processMessage(message);
 196  0
             return null;
 197  
         }
 198  
 
 199  
     }
 200  
 
 201  
     protected abstract List<MuleMessage> getMessages() throws Exception;
 202  
 
 203  
     protected abstract void processMessage(Object message) throws Exception;
 204  
 
 205  
 }