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