Coverage Report - org.mule.transport.jdbc.JdbcMessageReceiver
 
Classes in this File Line Coverage Branch Coverage Complexity
JdbcMessageReceiver
72%
51/71
31%
17/54
4.167
 
 1  
 /*
 2  
  * $Id: JdbcMessageReceiver.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.jdbc;
 12  
 
 13  
 import org.mule.DefaultMuleMessage;
 14  
 import org.mule.api.MuleMessage;
 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.Transaction;
 19  
 import org.mule.api.transport.Connector;
 20  
 import org.mule.api.transport.MessageAdapter;
 21  
 import org.mule.transaction.TransactionCoordination;
 22  
 import org.mule.transaction.XaTransactionFactory;
 23  
 import org.mule.transport.ConnectException;
 24  
 import org.mule.transport.TransactedPollingMessageReceiver;
 25  
 import org.mule.transport.jdbc.i18n.JdbcMessages;
 26  
 import org.mule.util.ArrayUtils;
 27  
 import org.mule.util.MapUtils;
 28  
 
 29  
 import java.sql.Connection;
 30  
 import java.sql.SQLException;
 31  
 import java.util.ArrayList;
 32  
 import java.util.List;
 33  
 
 34  
 /** TODO */
 35  
 public class JdbcMessageReceiver extends TransactedPollingMessageReceiver
 36  
 {
 37  
 
 38  
     public static final String RECEIVE_MESSAGE_IN_TRANSCTION = "receiveMessageInTransaction";
 39  
     public static final String RECEIVE_MESSAGES_IN_XA_TRANSCTION = "receiveMessagesInXaTransaction";
 40  
     
 41  
     protected JdbcConnector connector;
 42  
     protected String readStmt;
 43  
     protected String ackStmt;
 44  
     protected List readParams;
 45  
     protected List ackParams;
 46  12
     public boolean receiveMessagesInXaTransaction = false;
 47  
     
 48  
     public JdbcMessageReceiver(Connector connector,
 49  
                                Service service,
 50  
                                InboundEndpoint endpoint,
 51  
                                String readStmt,
 52  
                                String ackStmt) throws CreateException
 53  
     {
 54  12
         super(connector, service, endpoint);
 55  12
         this.setFrequency(((JdbcConnector) connector).getPollingFrequency());
 56  
 
 57  12
         boolean transactedEndpoint = endpoint.getTransactionConfig().isTransacted();
 58  12
         boolean xaTransactedEndpoint = (transactedEndpoint &&
 59  
             endpoint.getTransactionConfig().getFactory() instanceof XaTransactionFactory);
 60  
         
 61  12
         boolean receiveMessageInTransaction = MapUtils.getBooleanValue(endpoint.getProperties(),
 62  
             RECEIVE_MESSAGE_IN_TRANSCTION, false);
 63  12
         this.setReceiveMessagesInTransaction(receiveMessageInTransaction && transactedEndpoint);
 64  12
         if (receiveMessageInTransaction && !transactedEndpoint)
 65  
         {
 66  0
             logger.warn(JdbcMessages.forcePropertyNoTransaction(RECEIVE_MESSAGE_IN_TRANSCTION, "transaction"));
 67  0
             receiveMessageInTransaction = false;
 68  
         }
 69  
         
 70  12
         receiveMessagesInXaTransaction = MapUtils.getBooleanValue(endpoint.getProperties(),
 71  
             RECEIVE_MESSAGES_IN_XA_TRANSCTION, false);
 72  12
         if (receiveMessagesInXaTransaction && !receiveMessageInTransaction)
 73  
         {
 74  0
             logger.warn(JdbcMessages.forceProperty(RECEIVE_MESSAGES_IN_XA_TRANSCTION, RECEIVE_MESSAGE_IN_TRANSCTION));
 75  0
             receiveMessagesInXaTransaction = false;
 76  
         }
 77  12
         else if (receiveMessagesInXaTransaction && isReceiveMessagesInTransaction() && !xaTransactedEndpoint)
 78  
         {
 79  0
             logger.warn(JdbcMessages.forcePropertyNoTransaction(RECEIVE_MESSAGES_IN_XA_TRANSCTION, "XA transaction"));
 80  0
             receiveMessagesInXaTransaction = false;
 81  
         }
 82  
     
 83  
         
 84  12
         this.connector = (JdbcConnector) connector;
 85  12
         this.setReceiveMessagesInTransaction(endpoint.getTransactionConfig().isTransacted()
 86  
             && !this.connector.isTransactionPerMessage());
 87  
         
 88  12
         this.readParams = new ArrayList();
 89  12
         this.readStmt = this.connector.parseStatement(readStmt, this.readParams);
 90  12
         this.ackParams = new ArrayList();
 91  12
         this.ackStmt = this.connector.parseStatement(ackStmt, this.ackParams);
 92  12
     }
 93  
 
 94  
     protected void doDispose()
 95  
     {
 96  
         // template method
 97  24
     }
 98  
 
 99  
     protected void doConnect() throws Exception
 100  
     {
 101  10
         Connection con = null;
 102  
         try
 103  
         {
 104  10
             con = this.connector.getConnection();
 105  
         }
 106  0
         catch (Exception e)
 107  
         {
 108  0
             throw new ConnectException(e, this);
 109  
         }
 110  
         finally
 111  
         {
 112  10
             JdbcUtils.close(con);
 113  10
         }
 114  10
     }
 115  
 
 116  
     protected void doDisconnect() throws ConnectException
 117  
     {
 118  
         // noop
 119  10
     }
 120  
 
 121  
     public void processMessage(Object message) throws Exception
 122  
     {
 123  2
         Connection con = null;
 124  2
         Transaction tx = TransactionCoordination.getInstance().getTransaction();
 125  
         try
 126  
         {
 127  2
             con = this.connector.getConnection();
 128  2
             MessageAdapter msgAdapter = this.connector.getMessageAdapter(message);
 129  2
             MuleMessage umoMessage = new DefaultMuleMessage(msgAdapter);
 130  2
             if (this.ackStmt != null)
 131  
             {
 132  2
                 Object[] ackParams = connector.getParams(endpoint, this.ackParams, umoMessage, this.endpoint.getEndpointURI().getAddress());
 133  2
                 if (logger.isDebugEnabled())
 134  
                 {
 135  0
                     logger.debug("SQL UPDATE: " + ackStmt + ", params = " + ArrayUtils.toString(ackParams));
 136  
                 }
 137  2
                 int nbRows = connector.getQueryRunner().update(con, this.ackStmt, ackParams);
 138  2
                 if (nbRows != 1)
 139  
                 {
 140  2
                     logger.warn("Row count for ack should be 1 and not " + nbRows);
 141  
                 }
 142  
             }
 143  2
             routeMessage(umoMessage, tx, tx != null || endpoint.isSynchronous());
 144  
 
 145  
         }
 146  0
         catch (Exception ex)
 147  
         {
 148  0
             if (tx != null)
 149  
             {
 150  0
                 tx.setRollbackOnly();
 151  
             }
 152  
 
 153  
             // rethrow
 154  0
             throw ex;
 155  
         }
 156  
         finally
 157  
         {
 158  2
             if (endpoint.getMuleContext().getTransactionManager() != null || tx == null)
 159  
             {
 160  
                 // We are running in an XA transaction.
 161  
                 // This call is required here for compatibility with strict XA
 162  
                 // DataSources
 163  
                 // implementations, as is the case for WebSphere AS and Weblogic.
 164  
                 // Failure to do it here may result in a connection leak.
 165  
                 // The close() call will NOT close the connection, neither will it
 166  
                 // return it to the pool.
 167  
                 // It will notify the XA driver's ConnectionEventListener that the XA
 168  
                 // connection
 169  
                 // is no longer used by the application and is ready for the 2PC
 170  
                 // commit.
 171  2
                 JdbcUtils.close(con);
 172  
             }
 173  
         }
 174  2
     }
 175  
 
 176  
     public List getMessages() throws Exception
 177  
     {
 178  2
         Connection con = null;
 179  
         try
 180  
         {
 181  
             try
 182  
             {
 183  2
                 con = this.connector.getConnection();
 184  
             }
 185  0
             catch (SQLException e)
 186  
             {
 187  0
                 throw new ConnectException(e, this);
 188  2
             }
 189  
 
 190  2
             Object[] readParams = connector.getParams(endpoint, this.readParams, null, this.endpoint.getEndpointURI().getAddress());
 191  2
             if (logger.isDebugEnabled())
 192  
             {
 193  0
                 logger.debug("SQL QUERY: " + readStmt + ", params = " + ArrayUtils.toString(readParams));
 194  
             }
 195  2
             Object results = connector.getQueryRunner().query(con, this.readStmt, readParams,
 196  
                     connector.getResultSetHandler());
 197  
 
 198  2
             List resultList = (List) results;
 199  2
             if (resultList != null && resultList.size() > 1 && isReceiveMessagesInTransaction() && !receiveMessagesInXaTransaction)
 200  
             {
 201  0
                 logger.warn(JdbcMessages.moreThanOneMessageInTransaction(RECEIVE_MESSAGE_IN_TRANSCTION, RECEIVE_MESSAGES_IN_XA_TRANSCTION));
 202  0
                 List singleResultList = new ArrayList(1);
 203  0
                 singleResultList.add(resultList);
 204  0
                 return singleResultList;
 205  
             }
 206  
             
 207  2
             return resultList;
 208  
         }
 209  
         finally
 210  
         {
 211  2
             if (TransactionCoordination.getInstance().getTransaction() == null)
 212  
             {
 213  2
                 JdbcUtils.close(con);
 214  
             }
 215  
         }
 216  
     }
 217  
 
 218  
 }