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