Пример #1
0
  /**
   * process the redelivered message. If the Jms receiver should process the message, it should be
   * returned. Otherwise the connector should throw a <code>MessageRedeliveredException</code> to
   * indicate that the message should be handled by the connector Exception Handler.
   *
   * @param message
   */
  public void handleRedelivery(Message message) throws JMSException, MessagingException {
    if (connector.getMaxRedelivery() <= 0) return;

    String id = message.getJMSMessageID();
    Integer i = (Integer) messages.remove(id);
    if (i == null) {
      if (logger.isDebugEnabled()) {
        logger.debug("Message with id: " + id + " has been redelivered for the fist time");
      }
      messages.put(id, new Integer(1));
      return;
    } else if (i.intValue() == connector.getMaxRedelivery()) {
      if (logger.isDebugEnabled()) {
        logger.debug(
            "Message with id: "
                + id
                + " has been redelivered "
                + (i.intValue() + 1)
                + " times, which exceeds the maxRedelivery setting on the connector");
      }
      JmsMessageAdapter adapter = (JmsMessageAdapter) connector.getMessageAdapter(message);
      throw new MessageRedeliveredException(adapter);

    } else {
      messages.put(id, new Integer(i.intValue() + 1));
      if (logger.isDebugEnabled()) {
        logger.debug("Message with id: " + id + " has been redelivered " + i.intValue() + " times");
      }
    }
  }
Пример #2
0
  protected Destination getReplyToDestination(
      Message message, Session session, MuleEvent event, boolean remoteSync, boolean topic)
      throws JMSException, EndpointException, InitialisationException {
    Destination replyTo = null;

    // Some JMS implementations might not support the ReplyTo property.
    if (isHandleReplyTo(message, event)) {

      Object tempReplyTo = event.getMessage().removeProperty(JmsConstants.JMS_REPLY_TO);
      if (tempReplyTo == null) {
        // It may be a Mule URI or global endpoint Ref
        tempReplyTo = event.getMessage().removeProperty(MuleProperties.MULE_REPLY_TO_PROPERTY);
        if (tempReplyTo != null) {
          int i = tempReplyTo.toString().indexOf("://");
          if (i > -1) {
            tempReplyTo = tempReplyTo.toString().substring(i + 3);
          } else {
            EndpointBuilder epb =
                event.getMuleContext().getRegistry().lookupEndpointBuilder(tempReplyTo.toString());
            if (epb != null) {
              tempReplyTo = epb.buildOutboundEndpoint().getEndpointURI().getAddress();
            }
          }
        }
      }
      if (tempReplyTo != null) {
        if (tempReplyTo instanceof Destination) {
          replyTo = (Destination) tempReplyTo;
        } else {
          // TODO AP should this drill-down be moved into the resolver as well?
          boolean replyToTopic = false;
          String reply = tempReplyTo.toString();
          int i = reply.indexOf(":");
          if (i > -1) {
            // TODO MULE-1409 this check will not work for ActiveMQ 4.x,
            // as they have temp-queue://<destination> and temp-topic://<destination> URIs
            // Extract to a custom resolver for ActiveMQ4.x
            // The code path can be exercised, e.g. by a LoanBrokerESBTestCase
            String qtype = reply.substring(0, i);
            replyToTopic = JmsConstants.TOPIC_PROPERTY.equalsIgnoreCase(qtype);
            reply = reply.substring(i + 1);
          }
          replyTo =
              connector.getJmsSupport().createDestination(session, reply, replyToTopic, endpoint);
        }
      }
      // Are we going to wait for a return event ?
      if (remoteSync && replyTo == null && !disableTemporaryDestinations) {
        replyTo = connector.getJmsSupport().createTemporaryDestination(session, topic);
      }
    }
    return replyTo;
  }
Пример #3
0
 public JmsMessageDispatcher(OutboundEndpoint endpoint) {
   super(endpoint);
   this.connector = (JmsConnector) endpoint.getConnector();
   disableTemporaryDestinations =
       connector.isDisableTemporaryReplyToDestinations()
           || ("true"
               .equals(endpoint.getProperty(JmsConstants.DISABLE_TEMP_DESTINATIONS_PROPERTY)));
   returnOriginalMessageAsReply =
       connector.isReturnOriginalMessageAsReply()
           || ("true".equals(endpoint.getProperty(JmsConstants.RETURN_ORIGINAL_MESSAGE_PROPERTY)));
   if (returnOriginalMessageAsReply && !disableTemporaryDestinations) {
     logger.warn(
         "The returnOriginalMessageAsReply property will be ignored because disableTemporaryReplyToDestinations=false.  You need to disable temporary ReplyTo destinations in order for this propery to take effect.");
   }
 }
Пример #4
0
  public void onMessage(Message message) {
    try {
      if (logger.isDebugEnabled()) {
        logger.debug("Message received it is of type: " + message.getClass().getName());
        if (message.getJMSDestination() != null) {
          logger.debug(
              "Message received on "
                  + message.getJMSDestination()
                  + " ("
                  + message.getJMSDestination().getClass().getName()
                  + ")");
        } else {
          logger.debug("Message received on unknown destination");
        }
        logger.debug("Message CorrelationId is: " + message.getJMSCorrelationID());
        logger.debug("Jms Message Id is: " + message.getJMSMessageID());
      }

      if (message.getJMSRedelivered()) {
        if (logger.isDebugEnabled()) {
          logger.debug(
              "Message with correlationId: "
                  + message.getJMSCorrelationID()
                  + " is redelivered. handing off to Exception Handler");
        }
        redeliveryHandler.handleRedelivery(message);
      }

      UMOMessageAdapter adapter = connector.getMessageAdapter(message);
      routeMessage(new MuleMessage(adapter));
    } catch (Exception e) {
      handleException(e);
    }
  }
Пример #5
0
  /**
   * Create a consumer for the jms destination
   *
   * @throws Exception
   */
  protected void createConsumer() throws Exception {
    try {
      JmsSupport jmsSupport = this.connector.getJmsSupport();
      // Create session if none exists
      if (session == null) {
        session = this.connector.getSession(endpoint);
      }

      boolean topic = connector.getTopicResolver().isTopic(endpoint, true);

      // Create destination
      Destination dest =
          jmsSupport.createDestination(session, endpoint.getEndpointURI().getAddress(), topic);

      // Extract jms selector
      String selector = null;
      if (endpoint.getFilter() != null && endpoint.getFilter() instanceof JmsSelectorFilter) {
        selector = ((JmsSelectorFilter) endpoint.getFilter()).getExpression();
      } else if (endpoint.getProperties() != null) {
        // still allow the selector to be set as a property on the endpoint
        // to be backward compatable
        selector = (String) endpoint.getProperties().get(JmsConstants.JMS_SELECTOR_PROPERTY);
      }
      String tempDurable = (String) endpoint.getProperties().get(JmsConstants.DURABLE_PROPERTY);
      boolean durable = connector.isDurable();
      if (tempDurable != null) {
        durable = Boolean.valueOf(tempDurable).booleanValue();
      }

      // Get the durable subscriber name if there is one
      String durableName =
          (String) endpoint.getProperties().get(JmsConstants.DURABLE_NAME_PROPERTY);
      if (durableName == null && durable && dest instanceof Topic) {
        durableName = "mule." + connector.getName() + "." + endpoint.getEndpointURI().getAddress();
        logger.debug(
            "Jms Connector for this receiver is durable but no durable name has been specified. Defaulting to: "
                + durableName);
      }

      // Create consumer
      consumer =
          jmsSupport.createConsumer(
              session, dest, selector, connector.isNoLocal(), durableName, topic);
    } catch (JMSException e) {
      throw new ConnectException(e, this);
    }
  }
Пример #6
0
 /*
  * (non-Javadoc)
  *
  * @see org.mule.umo.provider.UMOMessageDispatcher#getDelegateSession()
  */
 public synchronized Object getDelegateSession() throws UMOException {
   try {
     // Return the session bound to the current transaction
     // if possible
     Session session = connector.getSessionFromTransaction();
     if (session != null) {
       return session;
     }
     // Else create a session for this dispatcher and
     // use it each time
     if (delegateSession == null) {
       delegateSession = connector.getSession(false, false);
     }
     return delegateSession;
   } catch (Exception e) {
     throw new MuleException(new org.mule.config.i18n.Message("jms", 3), e);
   }
 }
Пример #7
0
  protected MessageConsumer createReplyToConsumer(
      Message currentMessage, MuleEvent event, Session session, Destination replyTo, boolean topic)
      throws JMSException {
    String selector = null;
    // Only used by topics
    String durableName = null;
    // If we're not using
    if (!(replyTo instanceof TemporaryQueue || replyTo instanceof TemporaryTopic)) {
      String jmsCorrelationId = currentMessage.getJMSCorrelationID();
      if (jmsCorrelationId == null) {
        jmsCorrelationId = currentMessage.getJMSMessageID();
      }

      selector = "JMSCorrelationID='" + jmsCorrelationId + "'";
      if (logger.isDebugEnabled()) {
        logger.debug("ReplyTo Selector is: " + selector);
      }
    }

    // We need to set the durableName and Selector if using topics
    if (topic) {
      String tempDurable =
          (String) event.getEndpoint().getProperties().get(JmsConstants.DURABLE_PROPERTY);
      boolean durable = connector.isDurable();
      if (tempDurable != null) {
        durable = Boolean.valueOf(tempDurable);
      }
      // Get the durable subscriber name if there is one
      durableName =
          (String) event.getEndpoint().getProperties().get(JmsConstants.DURABLE_NAME_PROPERTY);
      if (durableName == null && durable && topic) {
        durableName =
            "mule." + connector.getName() + "." + event.getEndpoint().getEndpointURI().getAddress();
        if (logger.isDebugEnabled()) {
          logger.debug(
              "Jms Connector for this receiver is durable but no durable name has been specified. Defaulting to: "
                  + durableName);
        }
      }
    }
    return connector
        .getJmsSupport()
        .createConsumer(session, replyTo, selector, connector.isNoLocal(), null, topic, endpoint);
  }
Пример #8
0
  /**
   * Make a specific request to the underlying transport
   *
   * @param endpoint the endpoint to use when connecting to the resource
   * @param timeout the maximum time the operation should block before returning. The call should
   *     return immediately if there is data available. If no data becomes available before the
   *     timeout elapses, null will be returned
   * @return the result of the request wrapped in a UMOMessage object. Null will be returned if no
   *     data was avaialable
   * @throws Exception if the call to the underlying protocal cuases an exception
   */
  protected UMOMessage doReceive(UMOImmutableEndpoint endpoint, long timeout) throws Exception {

    Session session = null;
    Destination dest = null;
    MessageConsumer consumer = null;
    try {
      boolean topic = false;
      String resourceInfo = endpoint.getEndpointURI().getResourceInfo();
      topic = (resourceInfo != null && JmsConstants.TOPIC_PROPERTY.equalsIgnoreCase(resourceInfo));

      session = connector.getSession(false, topic);
      dest =
          connector
              .getJmsSupport()
              .createDestination(session, endpoint.getEndpointURI().getAddress(), topic);
      consumer = connector.getJmsSupport().createConsumer(session, dest, topic);

      try {
        Message message = null;
        if (timeout == RECEIVE_NO_WAIT) {
          message = consumer.receiveNoWait();
        } else if (timeout == RECEIVE_WAIT_INDEFINITELY) {
          message = consumer.receive();
        } else {
          message = consumer.receive(timeout);
        }
        if (message == null) {
          return null;
        }

        message = connector.preProcessMessage(message, session);

        return new MuleMessage(connector.getMessageAdapter(message));
      } catch (Exception e) {
        connector.handleException(e);
        return null;
      }
    } finally {
      connector.closeQuietly(consumer);
      connector.closeQuietly(session);
    }
  }
Пример #9
0
 /**
  * Some Jms implementations do not support ReplyTo or require some further fiddling of the message
  *
  * @param msg The JMS message that will be sent
  * @param event the current event
  * @return true if this request should honour any JMSReplyTo settings on the message
  * @throws JMSException if the JmsMessage cannot be written to, this should not happen because the
  *     JMSMessage passed in will always be newly created
  */
 protected boolean isHandleReplyTo(Message msg, MuleEvent event) throws JMSException {
   return connector.supportsProperty(JmsConstants.JMS_REPLY_TO);
 }
Пример #10
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 remoteSync = useRemoteSync(event);

    if (logger.isDebugEnabled()) {
      logger.debug(
          "dispatching on endpoint: "
              + event.getEndpoint().getEndpointURI()
              + ". MuleEvent id is: "
              + event.getId()
              + ". Outbound transformers are: "
              + event.getEndpoint().getTransformers());
    }

    try {
      session = connector.getSessionFromTransaction();
      if (session != null) {
        transacted = true;

        // If a transaction is running, we can not receive any messages
        // in the same transaction.
        if (remoteSync) {
          throw new IllegalTransactionStateException(
              JmsMessages.connectorDoesNotSupportSyncReceiveWhenTransacted());
        }
      }
      // 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())) {
        cached = true;
        if (cachedSession != null) {
          session = cachedSession;
        } else {
          session = connector.getSession(event.getEndpoint());
          cachedSession = session;
        }
      } else {
        session = connector.getSession(event.getEndpoint());
        if (event.getEndpoint().getTransactionConfig().isTransacted()) {
          transacted = true;
        }
      }

      boolean topic = connector.getTopicResolver().isTopic(event.getEndpoint(), true);

      Destination dest = connector.createDestinationMule3858Backport(session, endpoint);
      producer = connector.getJmsSupport().createProducer(session, dest, topic);

      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;
      if (event.getMessage().getCorrelationId() != null) {
        msg.setJMSCorrelationID(event.getMessage().getCorrelationId());
      }

      MuleMessage eventMsg = event.getMessage();

      // Some JMS implementations might not support the ReplyTo property.
      if (connector.supportsProperty(JmsConstants.JMS_REPLY_TO)) {
        Object tempReplyTo = eventMsg.removeProperty(JmsConstants.JMS_REPLY_TO);
        if (tempReplyTo == null) {
          // It may be a Mule URI or global endpoint Ref
          tempReplyTo = eventMsg.removeProperty(MuleProperties.MULE_REPLY_TO_PROPERTY);
          if (tempReplyTo != null) {
            if (tempReplyTo.toString().startsWith("jms://")) {
              tempReplyTo = tempReplyTo.toString().substring(6);
            } else {
              EndpointBuilder epb =
                  event
                      .getMuleContext()
                      .getRegistry()
                      .lookupEndpointBuilder(tempReplyTo.toString());
              if (epb != null) {
                tempReplyTo = epb.buildOutboundEndpoint().getEndpointURI().getAddress();
              }
            }
          }
        }
        if (tempReplyTo != null) {
          if (tempReplyTo instanceof Destination) {
            replyTo = (Destination) tempReplyTo;
          } else {
            // TODO AP should this drill-down be moved into the resolver as well?
            boolean replyToTopic = false;
            String reply = tempReplyTo.toString();
            int i = reply.indexOf(":");
            if (i > -1) {
              // TODO MULE-1409 this check will not work for ActiveMQ 4.x,
              // as they have temp-queue://<destination> and temp-topic://<destination> URIs
              // Extract to a custom resolver for ActiveMQ4.x
              // The code path can be exercised, e.g. by a LoanBrokerESBTestCase
              String qtype = reply.substring(0, i);
              replyToTopic = JmsConstants.TOPIC_PROPERTY.equalsIgnoreCase(qtype);
              reply = reply.substring(i + 1);
            }
            replyTo = connector.getJmsSupport().createDestination(session, reply, replyToTopic);
          }
        }
        // Are we going to wait for a return event ?
        if (remoteSync && replyTo == null) {
          replyTo = connector.getJmsSupport().createTemporaryDestination(session, topic);
        }
        // Set the replyTo property
        if (replyTo != null) {
          msg.setJMSReplyTo(replyTo);
        }

        // Are we going to wait for a return event ?
        if (remoteSync) {
          try {
            consumer = connector.getJmsSupport().createConsumer(session, replyTo, topic);
          } catch (Exception e) {
            logger.warn(e);
          }
        }
      }

      // 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 (connector.isHonorQosHeaders()) {
        int priorityProp =
            eventMsg.getIntProperty(JmsConstants.JMS_PRIORITY, Connector.INT_VALUE_NOT_SET);
        int deliveryModeProp =
            eventMsg.getIntProperty(JmsConstants.JMS_DELIVERY_MODE, Connector.INT_VALUE_NOT_SET);

        if (priorityProp != Connector.INT_VALUE_NOT_SET) {
          priority = priorityProp;
        }
        if (deliveryModeProp != Connector.INT_VALUE_NOT_SET) {
          persistent = deliveryModeProp == DeliveryMode.PERSISTENT;
        }
      }

      if (logger.isDebugEnabled()) {
        logger.debug("Sending message of type " + ClassUtils.getSimpleName(msg.getClass()));
      }

      if (consumer != null && 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);

        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 null;
        } else {
          MessageAdapter adapter = connector.getMessageAdapter(result);
          return new DefaultMuleMessage(
              JmsMessageUtils.toObject(
                  result, connector.getSpecification(), endpoint.getEncoding()),
              adapter);
        }
      } else {
        connector.getJmsSupport().send(producer, msg, persistent, priority, ttl, topic);
        if (consumer != null) {
          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");
            return null;
          } else {
            MessageAdapter adapter = connector.getMessageAdapter(result);
            return new DefaultMuleMessage(
                JmsMessageUtils.toObject(
                    result, connector.getSpecification(), endpoint.getEncoding()),
                adapter);
          }
        }
      }
      return null;
    } 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 the session is from the current transaction, it is up to the
      // transaction to close it.
      if (session != null && !cached && !transacted) {
        connector.closeQuietly(session);
      }
    }
  }
Пример #11
0
  private UMOMessage dispatchMessage(UMOEvent event) throws Exception {
    Session session = null;
    MessageProducer producer = null;
    MessageConsumer consumer = null;
    Destination replyTo = null;
    boolean transacted = false;
    boolean cached = false;
    boolean remoteSync = useRemoteSync(event);

    if (logger.isDebugEnabled()) {
      logger.debug(
          "dispatching on endpoint: "
              + event.getEndpoint().getEndpointURI()
              + ". Event id is: "
              + event.getId());
    }

    try {
      // Retrieve the session from the current transaction.
      session = connector.getSessionFromTransaction();
      if (session != null) {
        transacted = true;

        // If a transaction is running, we can not receive any messages
        // in the same transaction.
        if (remoteSync) {
          throw new IllegalTransactionStateException(new org.mule.config.i18n.Message("jms", 2));
        }
      }
      // 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())) {
        cached = true;
        if (cachedSession != null) {
          session = cachedSession;
        } else {
          // Retrieve a session from the connector
          session = connector.getSession(event.getEndpoint());
          cachedSession = session;
        }
      } else {
        // Retrieve a session from the connector
        session = connector.getSession(event.getEndpoint());
        if (event.getEndpoint().getTransactionConfig().isTransacted()) {
          transacted = true;
        }
      }

      // Add a reference to the JMS session used so that an EventAwareTransformer
      // can later retrieve it.
      // TODO Figure out a better way to accomplish this: MULE-1079
      // event.getMessage().setProperty(MuleProperties.MULE_JMS_SESSION, session);

      UMOEndpointURI endpointUri = event.getEndpoint().getEndpointURI();

      // determine if endpointUri is a queue or topic
      // the format is topic:destination
      boolean topic = false;
      String resourceInfo = endpointUri.getResourceInfo();
      topic = (resourceInfo != null && JmsConstants.TOPIC_PROPERTY.equalsIgnoreCase(resourceInfo));
      // TODO MULE20 remove resource info support
      if (!topic) {
        topic =
            MapUtils.getBooleanValue(
                event.getEndpoint().getProperties(), JmsConstants.TOPIC_PROPERTY, false);
      }

      Destination dest =
          connector.getJmsSupport().createDestination(session, endpointUri.getAddress(), topic);
      producer = connector.getJmsSupport().createProducer(session, dest, topic);

      Object message = event.getTransformedMessage();
      if (!(message instanceof Message)) {
        throw new DispatchException(
            new org.mule.config.i18n.Message(
                Messages.MESSAGE_NOT_X_IT_IS_TYPE_X_CHECK_TRANSFORMER_ON_X,
                "JMS message",
                message.getClass().getName(),
                connector.getName()),
            event.getMessage(),
            event.getEndpoint());
      }

      Message msg = (Message) message;
      if (event.getMessage().getCorrelationId() != null) {
        msg.setJMSCorrelationID(event.getMessage().getCorrelationId());
      }

      UMOMessage eventMsg = event.getMessage();

      // Some JMS implementations might not support the ReplyTo property.
      if (connector.supportsProperty(JmsConstants.JMS_REPLY_TO)) {
        Object tempReplyTo = eventMsg.removeProperty(JmsConstants.JMS_REPLY_TO);
        if (tempReplyTo != null) {
          if (tempReplyTo instanceof Destination) {
            replyTo = (Destination) tempReplyTo;
          } else {
            boolean replyToTopic = false;
            String reply = tempReplyTo.toString();
            int i = reply.indexOf(":");
            if (i > -1) {
              String qtype = reply.substring(0, i);
              replyToTopic = "topic".equalsIgnoreCase(qtype);
              reply = reply.substring(i + 1);
            }
            replyTo = connector.getJmsSupport().createDestination(session, reply, replyToTopic);
          }
        }
        // Are we going to wait for a return event ?
        if (remoteSync && replyTo == null) {
          replyTo = connector.getJmsSupport().createTemporaryDestination(session, topic);
        }
        // Set the replyTo property
        if (replyTo != null) {
          msg.setJMSReplyTo(replyTo);
        }

        // Are we going to wait for a return event ?
        if (remoteSync) {
          consumer = connector.getJmsSupport().createConsumer(session, replyTo, topic);
        }
      }

      // 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 = Message.DEFAULT_TIME_TO_LIVE;
      int priority = Message.DEFAULT_PRIORITY;
      boolean persistent = Message.DEFAULT_DELIVERY_MODE == DeliveryMode.PERSISTENT;

      if (ttlString != null) {
        ttl = Long.parseLong(ttlString);
      }
      if (priorityString != null) {
        priority = Integer.parseInt(priorityString);
      }
      if (persistentDeliveryString != null) {
        persistent = Boolean.valueOf(persistentDeliveryString).booleanValue();
      }

      logger.debug("Sending message of type " + msg.getClass().getName());
      if (consumer != null && 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);

        int timeout = event.getTimeout();
        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 null;
        } else {
          UMOMessageAdapter adapter = connector.getMessageAdapter(result);
          return new MuleMessage(JmsMessageUtils.getObjectForMessage(result), adapter);
        }
      } else {
        connector.getJmsSupport().send(producer, msg, persistent, priority, ttl, topic);
        if (consumer != null) {
          int timeout = event.getTimeout();
          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");
            return null;
          } else {
            UMOMessageAdapter adapter = connector.getMessageAdapter(result);
            return new MuleMessage(JmsMessageUtils.getObjectForMessage(result), adapter);
          }
        }
      }
      return null;
    } finally {
      connector.closeQuietly(consumer);
      connector.closeQuietly(producer);

      // TODO I wonder if those temporary destinations also implement BOTH interfaces...
      // keep it 'simple' for now
      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 the session is from the current transaction, it is up to the
      // transaction to close it.
      if (session != null && !cached && !transacted) {
        connector.closeQuietly(session);
      }
    }
  }
Пример #12
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);
      }
    }
  }
Пример #13
0
 public JmsReplyToHandler(JmsConnector connector, List transformers) {
   super(transformers, connector.getMuleContext());
   this.connector = connector;
 }
Пример #14
0
 protected void doDispatch(MuleEvent event) throws Exception {
   if (connector.getConnection() == null) {
     throw new IllegalStateException("No JMS Connection");
   }
   dispatchMessage(event);
 }
Пример #15
0
 protected void closeConsumer() {
   connector.closeQuietly(consumer);
   consumer = null;
   connector.closeQuietly(session);
   session = null;
 }
Пример #16
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);
      }
    }
  }
Пример #17
0
 protected void doSetUp() throws Exception {
   super.doSetUp();
   connector = (JmsConnector) managementContext.getRegistry().lookupConnector("jmsConnector");
   resolver = (DefaultJmsTopicResolver) connector.getTopicResolver();
 }