Coverage Report - org.mule.transport.TransactedPollingMessageReceiver
 
Classes in this File Line Coverage Branch Coverage Complexity
TransactedPollingMessageReceiver
0%
0/38
0%
0/16
1.667
TransactedPollingMessageReceiver$1
0%
0/6
0%
0/6
1.667
TransactedPollingMessageReceiver$MessageProcessorWorker
0%
0/14
N/A
1.667
 
 1  
 /*
 2  
  * $Id: TransactedPollingMessageReceiver.java 12181 2008-06-26 20:05:55Z dirk.olmes $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.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.config.ThreadingProfile;
 15  
 import org.mule.api.endpoint.InboundEndpoint;
 16  
 import org.mule.api.lifecycle.CreateException;
 17  
 import org.mule.api.service.Service;
 18  
 import org.mule.api.transaction.TransactionCallback;
 19  
 import org.mule.api.transport.Connector;
 20  
 import org.mule.transaction.TransactionTemplate;
 21  
 
 22  
 import java.util.Iterator;
 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  
 import edu.emory.mathcs.backport.java.util.concurrent.TimeUnit;
 29  
 
 30  
 /**
 31  
  * The TransactedPollingMessageReceiver is an abstract receiver that handles polling
 32  
  * and transaction management. Derived implementations of these class must be thread
 33  
  * safe as several threads can be started at once for an improveded throuput.
 34  
  */
 35  
 public abstract class TransactedPollingMessageReceiver extends AbstractPollingMessageReceiver
 36  
 {
 37  
     /** determines whether messages will be received in a transaction template */
 38  0
     private boolean receiveMessagesInTransaction = true;
 39  
 
 40  
     /** determines whether Multiple receivers are created to improve throughput */
 41  0
     private boolean useMultipleReceivers = true;
 42  
 
 43  
     public TransactedPollingMessageReceiver(Connector connector,
 44  
                                             Service service,
 45  
                                             final InboundEndpoint endpoint) throws CreateException
 46  
     {
 47  0
         super(connector, service, endpoint);
 48  0
         this.setReceiveMessagesInTransaction(endpoint.getTransactionConfig().isTransacted());
 49  0
     }
 50  
 
 51  
     /**
 52  
      * @deprecated please use
 53  
      *             {@link #TransactedPollingMessageReceiver(Connector,Service,InboundEndpoint,long,TimeUnit)}
 54  
      *             instead
 55  
      */
 56  
     public TransactedPollingMessageReceiver(Connector connector,
 57  
                                             Service service,
 58  
                                             final InboundEndpoint endpoint,
 59  
                                             long frequency) throws CreateException
 60  
     {
 61  0
         this(connector, service, 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  
     public void poll() throws Exception
 107  
     {
 108  0
         TransactionTemplate tt = new TransactionTemplate(endpoint.getTransactionConfig(),
 109  
                 connector.getExceptionListener(), 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 cb = new TransactionCallback()
 117  
             {
 118  0
                 public Object doInTransaction() throws Exception
 119  
                 {
 120  0
                     List messages = getMessages();
 121  0
                     if (messages != null && messages.size() > 0)
 122  
                     {
 123  0
                         for (Iterator it = messages.iterator(); it.hasNext();)
 124  
                         {
 125  0
                             TransactedPollingMessageReceiver.this.processMessage(it.next());
 126  
                         }
 127  
                     }
 128  0
                     return null;
 129  
                 }
 130  
             };
 131  0
             tt.execute(cb);
 132  0
         }
 133  
         else
 134  
         {
 135  
             // Receive messages and launch a worker for each message
 136  0
             List messages = getMessages();
 137  0
             if (messages != null && messages.size() > 0)
 138  
             {
 139  0
                 final CountDownLatch countdown = new CountDownLatch(messages.size());
 140  0
                 for (Iterator it = messages.iterator(); it.hasNext();)
 141  
                 {
 142  
                     try
 143  
                     {
 144  0
                         this.getWorkManager().scheduleWork(
 145  
                                 new MessageProcessorWorker(tt, countdown, it.next()));
 146  
                     }
 147  0
                     catch (Exception e)
 148  
                     {
 149  0
                         countdown.countDown();
 150  0
                         throw e;
 151  0
                     }
 152  
                 }
 153  0
                 countdown.await();
 154  
             }
 155  
         }
 156  0
     }
 157  
 
 158  
     protected class MessageProcessorWorker implements Work, TransactionCallback
 159  
     {
 160  
         private final TransactionTemplate tt;
 161  
         private final Object message;
 162  
         private final CountDownLatch latch;
 163  
 
 164  
         public MessageProcessorWorker(TransactionTemplate tt, CountDownLatch latch, Object message)
 165  0
         {
 166  0
             this.tt = tt;
 167  0
             this.message = message;
 168  0
             this.latch = latch;
 169  0
         }
 170  
 
 171  
         public void release()
 172  
         {
 173  
             // nothing to do
 174  0
         }
 175  
 
 176  
         public void run()
 177  
         {
 178  
             try
 179  
             {
 180  0
                 tt.execute(this);
 181  
             }
 182  0
             catch (Exception e)
 183  
             {
 184  0
                 handleException(e);
 185  
             }
 186  
             finally
 187  
             {
 188  0
                 latch.countDown();
 189  0
             }
 190  0
         }
 191  
 
 192  
         public Object doInTransaction() throws Exception
 193  
         {
 194  0
             TransactedPollingMessageReceiver.this.processMessage(message);
 195  0
             return null;
 196  
         }
 197  
 
 198  
     }
 199  
 
 200  
     protected abstract List getMessages() throws Exception;
 201  
 
 202  
     protected abstract void processMessage(Object message) throws Exception;
 203  
 
 204  
 }