@Override protected void doTearDown() throws Exception { Transaction tx = TransactionCoordination.getInstance().getTransaction(); if (tx != null) { TransactionCoordination.getInstance().unbindTransaction(tx); } }
public Object process(Object a) throws Exception { if (TransactionCoordination.getInstance().getTransaction() == null) { success = false; logger.error("Transction is null"); } return a; }
QueueSession getQueueSession() throws InitialisationException { QueueManager qm = MuleManager.getInstance().getQueueManager(); UMOTransaction tx = TransactionCoordination.getInstance().getTransaction(); if (tx != null) { if (tx.hasResource(qm)) { if (logger.isDebugEnabled()) { logger.debug("Retrieving queue session from current transaction"); } return (QueueSession) tx.getResource(qm); } } if (logger.isDebugEnabled()) { logger.debug("Retrieving new queue session from queue manager"); } QueueSession session = qm.getQueueSession(); if (tx != null) { logger.debug("Binding queue session to current transaction"); try { tx.bindResource(qm, session); } catch (TransactionException e) { throw new RuntimeException("Could not bind queue session to current transaction", e); } } return session; }
public Connection getConnection() throws Exception { Transaction tx = TransactionCoordination.getInstance().getTransaction(); if (tx != null) { if (tx.hasResource(dataSource)) { logger.debug("Retrieving connection from current transaction: " + tx); return (Connection) tx.getResource(dataSource); } } logger.debug("Retrieving new connection from data source"); Connection con; try { con = dataSource.getConnection(); } catch (Exception e) { throw new ConnectException(e, this); } if (tx != null) { logger.debug("Binding connection " + con + " to current transaction: " + tx); try { tx.bindResource(dataSource, con); } catch (TransactionException e) { JdbcUtils.close(con); throw new RuntimeException("Could not bind connection to current transaction: " + tx, e); } } return con; }
/** * If there is a current transaction this method will mark it for rollback This method should not * be called if an event is routed from this exception handler to an endpoint that should take * part in the current transaction */ protected void markTransactionForRollback() { UMOTransaction tx = TransactionCoordination.getInstance().getTransaction(); try { if (tx != null) tx.setRollbackOnly(); } catch (TransactionException e) { logException(e); } }
@Override public void testSendToOneWayTx() throws Exception { MuleClient client = muleContext.getClient(); try { client.send("vm://oneway-tx-in", "a", null); fail("Exception expected"); } catch (Exception e) { TransactionCoordination.getInstance().getTransaction().rollback(); } }
/* * (non-Javadoc) * * @see org.mule.providers.AbstractMessageDispatcher#doDispatch(org.mule.umo.UMOEvent) */ protected void doDispatch(UMOEvent event) throws Exception { if (logger.isDebugEnabled()) { logger.debug("Dispatch event: " + event); } UMOImmutableEndpoint endpoint = event.getEndpoint(); String writeStmt = endpoint.getEndpointURI().getAddress(); String str; if ((str = this.connector.getQuery(endpoint, writeStmt)) != null) { writeStmt = str; } if (StringUtils.isEmpty(writeStmt)) { throw new IllegalArgumentException("Write statement should not be null"); } if (!"insert".equalsIgnoreCase(writeStmt.substring(0, 6)) && !"update".equalsIgnoreCase(writeStmt.substring(0, 6)) && !"delete".equalsIgnoreCase(writeStmt.substring(0, 6))) { throw new IllegalArgumentException( "Write statement should be an insert / update / delete sql statement"); } List paramNames = new ArrayList(); writeStmt = JdbcUtils.parseStatement(writeStmt, paramNames); Object[] paramValues = JdbcUtils.getParams(endpoint, paramNames, event.getTransformedMessage()); UMOTransaction tx = TransactionCoordination.getInstance().getTransaction(); Connection con = null; try { con = this.connector.getConnection(); int nbRows = connector.createQueryRunner().update(con, writeStmt, paramValues); if (nbRows != 1) { logger.warn("Row count for write should be 1 and not " + nbRows); } if (tx == null) { JdbcUtils.commitAndClose(con); } logger.debug("Event dispatched succesfuly"); } catch (Exception e) { logger.debug("Error dispatching event: " + e.getMessage(), e); if (tx == null) { JdbcUtils.rollbackAndClose(con); } throw e; } }
public void processMessage(Object message) throws Exception { Connection con = null; UMOTransaction tx = TransactionCoordination.getInstance().getTransaction(); try { con = this.connector.getConnection(); if (this.ackStmt != null) { Object[] ackParams = JdbcUtils.getParams(getEndpointURI(), this.ackParams, message); int nbRows = new QueryRunner().update(con, this.ackStmt, ackParams); if (nbRows != 1) { logger.warn("Row count for ack should be 1 and not " + nbRows); } } UMOMessageAdapter msgAdapter = this.connector.getMessageAdapter(message); UMOMessage umoMessage = new MuleMessage(msgAdapter); routeMessage(umoMessage, tx, tx != null || endpoint.isSynchronous()); } finally { if (tx == null) { JdbcUtils.close(con); } } }
private MuleMessage dispatchMessage(MuleEvent event) throws Exception { Session session = null; MessageProducer producer = null; MessageConsumer consumer = null; Destination replyTo = null; boolean transacted = false; boolean cached = false; boolean useReplyToDestination; final Transaction muleTx = TransactionCoordination.getInstance().getTransaction(); if (logger.isDebugEnabled()) { logger.debug( "dispatching on endpoint: " + event.getEndpoint().getEndpointURI() + ". MuleEvent id is: " + event.getId() + ". Outbound transformers are: " + event.getEndpoint().getTransformers()); } // assume session is transacted first, and thus, managed boolean sessionManaged = true; try { session = connector.getSessionFromTransaction(); if (session != null) { transacted = true; } // Should we be caching sessions? Note this is not part of the JMS spec. // and is turned off by default. else if (event .getMessage() .getBooleanProperty( JmsConstants.CACHE_JMS_SESSIONS_PROPERTY, connector.isCacheJmsSessions())) { sessionManaged = false; cached = true; if (cachedSession != null) { session = cachedSession; } else { session = connector.getSession(event.getEndpoint()); cachedSession = session; } } else { // by now we're running with a different connector and connection sessionManaged = muleTx != null && muleTx.isXA(); session = connector.getSession(event.getEndpoint()); if (event.getEndpoint().getTransactionConfig().isTransacted()) { transacted = true; } } // If a transaction is running, we can not receive any messages // in the same transaction using a replyTo destination useReplyToDestination = returnResponse(event) && !transacted; boolean topic = connector.getTopicResolver().isTopic(event.getEndpoint(), true); Destination dest = connector.getJmsSupport().createDestination(session, endpoint); producer = connector.getJmsSupport().createProducer(session, dest, topic); preTransformMessage(event.getMessage()); Object message = event.transformMessage(); if (!(message instanceof Message)) { throw new DispatchException( JmsMessages.checkTransformer("JMS message", message.getClass(), connector.getName()), event.getMessage(), event.getEndpoint()); } Message msg = (Message) message; MuleMessage eventMsg = event.getMessage(); replyTo = getReplyToDestination(msg, session, event, useReplyToDestination, topic); // Set the replyTo property if (replyTo != null) { msg.setJMSReplyTo(replyTo); } // Allow overrides to alter the message if necessary processMessage(msg, event); // QoS support String ttlString = (String) eventMsg.removeProperty(JmsConstants.TIME_TO_LIVE_PROPERTY); String priorityString = (String) eventMsg.removeProperty(JmsConstants.PRIORITY_PROPERTY); String persistentDeliveryString = (String) eventMsg.removeProperty(JmsConstants.PERSISTENT_DELIVERY_PROPERTY); long ttl = StringUtils.isNotBlank(ttlString) ? NumberUtils.toLong(ttlString) : Message.DEFAULT_TIME_TO_LIVE; int priority = StringUtils.isNotBlank(priorityString) ? NumberUtils.toInt(priorityString) : Message.DEFAULT_PRIORITY; boolean persistent = StringUtils.isNotBlank(persistentDeliveryString) ? BooleanUtils.toBoolean(persistentDeliveryString) : connector.isPersistentDelivery(); // If we are honouring the current QoS message headers we need to use the ones set on the // current message if (connector.isHonorQosHeaders()) { Object priorityProp = eventMsg.getProperty(JmsConstants.JMS_PRIORITY); Object deliveryModeProp = eventMsg.getProperty(JmsConstants.JMS_DELIVERY_MODE); if (priorityProp != null) { priority = NumberUtils.toInt(priorityProp); } if (deliveryModeProp != null) { persistent = NumberUtils.toInt(deliveryModeProp) == DeliveryMode.PERSISTENT; } } if (logger.isDebugEnabled()) { logger.debug("Sending message of type " + ClassUtils.getSimpleName(msg.getClass())); logger.debug( "Sending JMS Message type " + msg.getJMSType() + "\n JMSMessageID=" + msg.getJMSMessageID() + "\n JMSCorrelationID=" + msg.getJMSCorrelationID() + "\n JMSDeliveryMode=" + (persistent ? DeliveryMode.PERSISTENT : DeliveryMode.NON_PERSISTENT) + "\n JMSPriority=" + priority + "\n JMSReplyTo=" + msg.getJMSReplyTo()); } connector.getJmsSupport().send(producer, msg, persistent, priority, ttl, topic, endpoint); if (useReplyToDestination && replyTo != null) { consumer = createReplyToConsumer(msg, event, session, replyTo, topic); if (topic) { // need to register a listener for a topic Latch l = new Latch(); ReplyToListener listener = new ReplyToListener(l); consumer.setMessageListener(listener); connector.getJmsSupport().send(producer, msg, persistent, priority, ttl, topic, endpoint); int timeout = event.getTimeout(); if (logger.isDebugEnabled()) { logger.debug("Waiting for return event for: " + timeout + " ms on " + replyTo); } l.await(timeout, TimeUnit.MILLISECONDS); consumer.setMessageListener(null); listener.release(); Message result = listener.getMessage(); if (result == null) { logger.debug("No message was returned via replyTo destination"); return new DefaultMuleMessage(NullPayload.getInstance(), connector.getMuleContext()); } else { MessageAdapter adapter = connector.getMessageAdapter(result); return new DefaultMuleMessage( JmsMessageUtils.toObject( result, connector.getSpecification(), endpoint.getEncoding()), adapter, connector.getMuleContext()); } } else { int timeout = event.getTimeout(); if (logger.isDebugEnabled()) { logger.debug("Waiting for return event for: " + timeout + " ms on " + replyTo); } Message result = consumer.receive(timeout); if (result == null) { logger.debug("No message was returned via replyTo destination " + replyTo); return new DefaultMuleMessage(NullPayload.getInstance(), connector.getMuleContext()); } else { MessageAdapter adapter = connector.getMessageAdapter(result); return new DefaultMuleMessage( JmsMessageUtils.toObject( result, connector.getSpecification(), endpoint.getEncoding()), adapter, connector.getMuleContext()); } } } return new DefaultMuleMessage( returnOriginalMessageAsReply ? msg : NullPayload.getInstance(), connector.getMuleContext()); } finally { connector.closeQuietly(producer); connector.closeQuietly(consumer); // TODO AP check if TopicResolver is to be utilized for temp destinations as well if (replyTo != null && (replyTo instanceof TemporaryQueue || replyTo instanceof TemporaryTopic)) { if (replyTo instanceof TemporaryQueue) { connector.closeQuietly((TemporaryQueue) replyTo); } else { // hope there are no more non-standard tricks from JMS vendors // here ;) connector.closeQuietly((TemporaryTopic) replyTo); } } if (!sessionManaged && transacted && muleTx instanceof TransactionCollection) { handleMultiTx(session); } // If the session is from the current transaction, it is up to the // transaction to close it. if (session != null && !cached && !transacted) { connector.closeQuietly(session); } } }
@Override public void processReplyTo(MuleEvent event, MuleMessage returnMessage, Object replyTo) throws MuleException { Destination replyToDestination = null; MessageProducer replyToProducer = null; Session session = null; try { // now we need to send the response if (replyTo instanceof Destination) { replyToDestination = (Destination) replyTo; } if (replyToDestination == null) { super.processReplyTo(event, returnMessage, replyTo); return; } // This is a work around for JmsTransformers where the current endpoint needs // to be set on the transformer so that a JMSMessage can be created correctly (the transformer // needs a Session) Class srcType = returnMessage.getPayload().getClass(); for (Iterator iterator = getTransformers().iterator(); iterator.hasNext(); ) { Transformer t = (Transformer) iterator.next(); if (t.isSourceDataTypeSupported(DataTypeFactory.create(srcType))) { if (t.getEndpoint() == null) { t.setEndpoint(getEndpoint(event, "jms://temporary")); break; } } } returnMessage.applyTransformers(getTransformers()); Object payload = returnMessage.getPayload(); if (replyToDestination instanceof Topic && replyToDestination instanceof Queue && connector.getJmsSupport() instanceof Jms102bSupport) { logger.error( StringMessageUtils.getBoilerPlate( "ReplyTo destination implements both Queue and Topic " + "while complying with JMS 1.0.2b specification. " + "Please report your application server or JMS vendor name and version " + "to dev<_at_>mule.codehaus.org or http://mule.mulesource.org/jira")); } final boolean topic = connector.getTopicResolver().isTopic(replyToDestination); session = connector.getSession(false, topic); Message replyToMessage = JmsMessageUtils.toMessage(payload, session); processMessage(replyToMessage, event); if (logger.isDebugEnabled()) { logger.debug( "Sending jms reply to: " + replyToDestination + "(" + replyToDestination.getClass().getName() + ")"); } replyToProducer = connector.getJmsSupport().createProducer(session, replyToDestination, topic); // QoS support MuleMessage eventMsg = event.getMessage(); String ttlString = (String) eventMsg.removeProperty(JmsConstants.TIME_TO_LIVE_PROPERTY); String priorityString = (String) eventMsg.removeProperty(JmsConstants.PRIORITY_PROPERTY); String persistentDeliveryString = (String) eventMsg.removeProperty(JmsConstants.PERSISTENT_DELIVERY_PROPERTY); String correlationIDString = replyToMessage.getJMSCorrelationID(); if (StringUtils.isBlank(correlationIDString)) { correlationIDString = (String) eventMsg.getProperty(JmsConstants.JMS_MESSAGE_ID); replyToMessage.setJMSCorrelationID(correlationIDString); } event.getService().getStatistics().incSentReplyToEvent(); final ImmutableEndpoint endpoint = event.getEndpoint(); if (ttlString == null && priorityString == null && persistentDeliveryString == null) { connector.getJmsSupport().send(replyToProducer, replyToMessage, topic, endpoint); } else { long ttl = Message.DEFAULT_TIME_TO_LIVE; int priority = Message.DEFAULT_PRIORITY; if (ttlString != null) { ttl = Long.parseLong(ttlString); } if (priorityString != null) { priority = Integer.parseInt(priorityString); } boolean persistent = StringUtils.isNotBlank(persistentDeliveryString) ? Boolean.valueOf(persistentDeliveryString) : connector.isPersistentDelivery(); connector .getJmsSupport() .send(replyToProducer, replyToMessage, persistent, priority, ttl, topic, endpoint); } logger.info( "Reply Message sent to: " + replyToDestination + " with correlationID:" + correlationIDString); } catch (Exception e) { throw new DispatchException( JmsMessages.failedToCreateAndDispatchResponse(replyToDestination), returnMessage, null, e); } finally { connector.closeQuietly(replyToProducer); final Transaction transaction = TransactionCoordination.getInstance().getTransaction(); if (transaction == null) { if (logger.isDebugEnabled()) { logger.debug("Closing non-TX replyTo session: " + session); } connector.closeQuietly(session); } else if (logger.isDebugEnabled()) { logger.debug("Not closing TX replyTo session: " + session); } } }
/** * Returns the transaction for the current event or null if there is no transaction in progresss * * @return the transaction for the current event or null if there is no transaction in progresss */ public UMOTransaction getTransaction() { return TransactionCoordination.getInstance().getTransaction(); }
protected void doTearDown() throws Exception { TransactionCoordination.getInstance() .unbindTransaction(TransactionCoordination.getInstance().getTransaction()); super.doTearDown(); }
public void testCleanup() throws Exception { assertNull( "There should be no transaction associated with this thread", TransactionCoordination.getInstance().getTransaction()); }