示例#1
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);
      }
    }
  }
示例#2
0
 public JmsReplyToHandler(JmsConnector connector, List transformers) {
   super(transformers, connector.getMuleContext());
   this.connector = connector;
 }