@Override
  public JMSProducer send(Destination destination, Message message) {
    if (message == null) {
      throw new MessageFormatRuntimeException("null message");
    }

    try {
      if (jmsHeaderCorrelationID != null) {
        message.setJMSCorrelationID(jmsHeaderCorrelationID);
      }
      if (jmsHeaderCorrelationIDAsBytes != null && jmsHeaderCorrelationIDAsBytes.length > 0) {
        message.setJMSCorrelationIDAsBytes(jmsHeaderCorrelationIDAsBytes);
      }
      if (jmsHeaderReplyTo != null) {
        message.setJMSReplyTo(jmsHeaderReplyTo);
      }
      if (jmsHeaderType != null) {
        message.setJMSType(jmsHeaderType);
      }
      // XXX HORNETQ-1209 "JMS 2.0" can this be a foreign msg?
      // if so, then "SimpleString" properties will trigger an error.
      setProperties(message);
      if (completionListener != null) {
        CompletionListener wrapped = new CompletionListenerWrapper(completionListener);
        producer.send(destination, message, wrapped);
      } else {
        producer.send(destination, message);
      }
    } catch (JMSException e) {
      throw JmsExceptionUtils.convertToRuntimeException(e);
    }
    return this;
  }
  /**
   * Set correlation id
   *
   * @param correlationID The value
   * @throws JMSException Thrown if an error occurs
   */
  @Override
  public void setJMSCorrelationID(final String correlationID) throws JMSException {
    if (ActiveMQRAMessage.trace) {
      ActiveMQRALogger.LOGGER.trace("setJMSCorrelationID(" + correlationID + ")");
    }

    message.setJMSCorrelationID(correlationID);
  }
Exemple #3
0
 public void appendJmsProperty(
     Message jmsMessage,
     Exchange exchange,
     org.apache.camel.Message in,
     String headerName,
     Object headerValue)
     throws JMSException {
   if (isStandardJMSHeader(headerName)) {
     if (headerName.equals("JMSCorrelationID")) {
       jmsMessage.setJMSCorrelationID(
           ExchangeHelper.convertToType(exchange, String.class, headerValue));
     } else if (headerName.equals("JMSReplyTo") && headerValue != null) {
       if (headerValue instanceof String) {
         // if the value is a String we must normalize it first, and must include the prefix
         // as ActiveMQ requires that when converting the String to a javax.jms.Destination type
         headerValue = normalizeDestinationName((String) headerValue, true);
       }
       Destination replyTo =
           ExchangeHelper.convertToType(exchange, Destination.class, headerValue);
       JmsMessageHelper.setJMSReplyTo(jmsMessage, replyTo);
     } else if (headerName.equals("JMSType")) {
       jmsMessage.setJMSType(ExchangeHelper.convertToType(exchange, String.class, headerValue));
     } else if (headerName.equals("JMSPriority")) {
       jmsMessage.setJMSPriority(
           ExchangeHelper.convertToType(exchange, Integer.class, headerValue));
     } else if (headerName.equals("JMSDeliveryMode")) {
       JmsMessageHelper.setJMSDeliveryMode(exchange, jmsMessage, headerValue);
     } else if (headerName.equals("JMSExpiration")) {
       jmsMessage.setJMSExpiration(
           ExchangeHelper.convertToType(exchange, Long.class, headerValue));
     } else {
       // The following properties are set by the MessageProducer:
       // JMSDestination
       // The following are set on the underlying JMS provider:
       // JMSMessageID, JMSTimestamp, JMSRedelivered
       // log at trace level to not spam log
       LOG.trace("Ignoring JMS header: {} with value: {}", headerName, headerValue);
     }
   } else if (shouldOutputHeader(in, headerName, headerValue, exchange)) {
     // only primitive headers and strings is allowed as properties
     // see message properties: http://java.sun.com/j2ee/1.4/docs/api/javax/jms/Message.html
     Object value = getValidJMSHeaderValue(headerName, headerValue);
     if (value != null) {
       // must encode to safe JMS header name before setting property on jmsMessage
       String key = jmsKeyFormatStrategy.encodeKey(headerName);
       // set the property
       JmsMessageHelper.setProperty(jmsMessage, key, value);
     } else if (LOG.isDebugEnabled()) {
       // okay the value is not a primitive or string so we cannot sent it over the wire
       LOG.debug(
           "Ignoring non primitive header: {} of class: {} with value: {}",
           new Object[] {headerName, headerValue.getClass().getName(), headerValue});
     }
   }
 }
  /** {@inheritDoc} */
  @Override
  public void mapTo(Context context, JMSBindingData target) throws Exception {
    super.mapTo(context, target);

    Message message = target.getMessage();
    for (Property property : context.getProperties()) {
      String name = property.getName();

      if (matches(name)) {
        Object value = property.getValue();
        if (value == null) {
          continue;
        }

        try {
          // process JMS headers
          if (name.equals(HEADER_JMS_DESTINATION)) {
            message.setJMSDestination(Destination.class.cast(value));
          } else if (name.equals(HEADER_JMS_DELIVERY_MODE)) {
            message.setJMSDeliveryMode(Integer.parseInt(value.toString()));
          } else if (name.equals(HEADER_JMS_EXPIRATION)) {
            message.setJMSExpiration(Long.parseLong(value.toString()));
          } else if (name.equals(HEADER_JMS_PRIORITY)) {
            message.setJMSPriority(Integer.parseInt(value.toString()));
          } else if (name.equals(HEADER_JMS_MESSAGE_ID)) {
            message.setJMSMessageID(value.toString());
          } else if (name.equals(HEADER_JMS_TIMESTAMP)) {
            message.setJMSTimestamp(Long.parseLong(value.toString()));
          } else if (name.equals(HEADER_JMS_CORRELATION_ID)) {
            message.setJMSCorrelationID(value.toString());
          } else if (name.equals(HEADER_JMS_REPLY_TO)) {
            message.setJMSReplyTo(Destination.class.cast(value));
          } else if (name.equals(HEADER_JMS_TYPE)) {
            message.setJMSType(value.toString());
          } else if (name.equals(HEADER_JMS_REDELIVERED)) {
            message.setJMSRedelivered(Boolean.parseBoolean(value.toString()));

            // process JMS properties
          } else {
            message.setObjectProperty(name, value);
          }
        } catch (Throwable t) {
          continue;
        }
      } else if (matches(name, getIncludeRegexes(), new ArrayList<Pattern>())) {
        Object value = property.getValue();
        if (value == null) {
          continue;
        }
        message.setObjectProperty(name, value);
      }
    }
  }
 /**
  * If no metadata key is configured or if no value is stored against the configured key a message
  * is logged to this effect and no Exception is thrown.
  *
  * @see com.adaptris.core.jms.CorrelationIdSource#processCorrelationId
  *     (com.adaptris.core.AdaptrisMessage, javax.jms.Message)
  */
 public void processCorrelationId(AdaptrisMessage src, Message dest) throws JMSException {
   if (isEmpty(getMetadataKey())) {
     log.warn("metadata key for correlation ID not configured");
   } else {
     String correlationId = src.getMetadataValue(getMetadataKey());
     if (isEmpty(correlationId)) {
       log.warn("no value for metadata key [" + getMetadataKey() + "]");
     } else {
       dest.setJMSCorrelationID(correlationId);
       log.debug("set correlation ID to [" + correlationId + "]");
     }
   }
 }
Exemple #6
0
 public static void constructMessageHeaders(
     Message jmsMsg, MessageHeaders msgHeaders, Destination destination) throws JMSException {
   jmsMsg.setJMSCorrelationID(msgHeaders.getJMSCorrelationID());
   jmsMsg.setJMSDeliveryMode(msgHeaders.getJMSDeliveryMode());
   jmsMsg.setJMSExpiration(msgHeaders.getJMSExpiration());
   jmsMsg.setJMSMessageID(msgHeaders.getJMSMessageID());
   jmsMsg.setJMSPriority(msgHeaders.getJMSPriority());
   jmsMsg.setJMSRedelivered(msgHeaders.isJMSRedelivered());
   // currently we are setting the replyTo destination as null
   jmsMsg.setJMSReplyTo(null);
   jmsMsg.setJMSTimestamp(msgHeaders.getJMSTimestamp());
   jmsMsg.setJMSType(msgHeaders.getJMSType());
   jmsMsg.setJMSDestination(destination);
 }
  @Test
  public void testContainerWithDestNameNoCorrelation() throws Exception {
    BeanFactory beanFactory = mock(BeanFactory.class);
    when(beanFactory.containsBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME))
        .thenReturn(true);
    ThreadPoolTaskScheduler scheduler = new ThreadPoolTaskScheduler();
    scheduler.initialize();
    when(beanFactory.getBean(IntegrationContextUtils.TASK_SCHEDULER_BEAN_NAME, TaskScheduler.class))
        .thenReturn(scheduler);
    final JmsOutboundGateway gateway = new JmsOutboundGateway();
    gateway.setBeanFactory(beanFactory);
    gateway.setConnectionFactory(getConnectionFactory());
    gateway.setRequestDestination(requestQueue4);
    gateway.setReplyDestinationName("reply4");
    gateway.setUseReplyContainer(true);
    gateway.afterPropertiesSet();
    gateway.start();
    final AtomicReference<Object> reply = new AtomicReference<Object>();
    final CountDownLatch latch1 = new CountDownLatch(1);
    final CountDownLatch latch2 = new CountDownLatch(1);
    Executors.newSingleThreadExecutor()
        .execute(
            () -> {
              latch1.countDown();
              try {
                reply.set(gateway.handleRequestMessage(new GenericMessage<String>("foo")));
              } finally {
                latch2.countDown();
              }
            });
    assertTrue(latch1.await(10, TimeUnit.SECONDS));
    JmsTemplate template = new JmsTemplate();
    template.setConnectionFactory(getConnectionFactory());
    template.setReceiveTimeout(10000);
    javax.jms.Message request = template.receive(requestQueue4);
    assertNotNull(request);
    final javax.jms.Message jmsReply = request;
    template.send(
        request.getJMSReplyTo(),
        (MessageCreator)
            session -> {
              jmsReply.setJMSCorrelationID(jmsReply.getJMSMessageID());
              return jmsReply;
            });
    assertTrue(latch2.await(10, TimeUnit.SECONDS));
    assertNotNull(reply.get());

    gateway.stop();
    scheduler.destroy();
  }
Exemple #8
0
  protected void processMessage(Message replyToMessage, MuleEvent event) throws JMSException {
    replyToMessage.setJMSReplyTo(null);

    // If JMS correlation ID exists in the incoming message - use it for the outbound message;
    // otherwise use JMS Message ID
    MuleMessage eventMsg = event.getMessage();
    Object jmsCorrelationId = eventMsg.getProperty("JMSCorrelationID");
    if (jmsCorrelationId == null) {
      jmsCorrelationId = eventMsg.getProperty("JMSMessageID");
    }
    if (jmsCorrelationId != null) {
      replyToMessage.setJMSCorrelationID(jmsCorrelationId.toString());
    }
    if (logger.isDebugEnabled()) {
      logger.debug("replyTomessage is " + replyToMessage);
    }
  }
 /**
  * Test that the <code>Message.getPropertyNames()</code> method does not return the name of the
  * JMS standard header fields (e.g. <code>JMSCorrelationID</code>).
  */
 @Test
 public void testGetPropertyNames() {
   try {
     Message message = senderSession.createMessage();
     message.setJMSCorrelationID("foo");
     Enumeration enumeration = message.getPropertyNames();
     while (enumeration.hasMoreElements()) {
       String propName = (String) enumeration.nextElement();
       boolean valid = !propName.startsWith("JMS") || propName.startsWith("JMSX");
       Assert.assertTrue(
           "sec. 3.5.6 The getPropertyNames method does not return the names of "
               + "the JMS standard header field [e.g. JMSCorrelationID]: "
               + propName,
           valid);
     }
   } catch (JMSException e) {
     fail(e);
   }
 }
  public static void copyJMSHeaders(Message inputMessage, Message outputMessage)
      throws JMSException {
    Object propValue;

    if (inputMessage == null || outputMessage == null) {
      return;
    }

    propValue = inputMessage.getJMSMessageID();
    if (propValue != null) {
      outputMessage.setJMSMessageID((String) propValue);
    }

    propValue = inputMessage.getJMSDestination();
    if (propValue != null) {
      outputMessage.setJMSDestination((Destination) propValue);
    }

    propValue = inputMessage.getJMSReplyTo();
    if (propValue != null) {
      outputMessage.setJMSReplyTo((Destination) propValue);
    }

    outputMessage.setJMSTimestamp(inputMessage.getJMSTimestamp());

    propValue = inputMessage.getJMSCorrelationID();
    if (!StringUtil.isEmpty((String) propValue)) {
      outputMessage.setJMSCorrelationID((String) propValue);
    }

    outputMessage.setJMSPriority(inputMessage.getJMSPriority());

    outputMessage.setJMSExpiration(inputMessage.getJMSExpiration());

    return;
  }
Exemple #11
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);
      }
    }
  }
Exemple #12
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);
      }
    }
  }
Exemple #13
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);
      }
    }
  }