@Override
 protected void doTearDown() throws Exception {
   Transaction tx = TransactionCoordination.getInstance().getTransaction();
   if (tx != null) {
     TransactionCoordination.getInstance().unbindTransaction(tx);
   }
 }
예제 #2
0
 public Object process(Object a) throws Exception {
   if (TransactionCoordination.getInstance().getTransaction() == null) {
     success = false;
     logger.error("Transction is null");
   }
   return a;
 }
예제 #3
0
  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;
  }
예제 #4
0
  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;
  }
예제 #5
0
 /**
  * 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();
    }
  }
예제 #7
0
  /*
   * (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;
    }
  }
예제 #8
0
 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);
     }
   }
 }
예제 #9
0
  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);
      }
    }
  }
예제 #10
0
  @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);
      }
    }
  }
예제 #11
0
 /**
  * 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();
 }
예제 #12
0
 protected void doTearDown() throws Exception {
   TransactionCoordination.getInstance()
       .unbindTransaction(TransactionCoordination.getInstance().getTransaction());
   super.doTearDown();
 }
예제 #13
0
 public void testCleanup() throws Exception {
   assertNull(
       "There should be no transaction associated with this thread",
       TransactionCoordination.getInstance().getTransaction());
 }