Search in sources :

Example 1 with Destination

use of javax.jms.Destination in project camel by apache.

the class JmsProducer method resolveOrCreateDestination.

protected Destination resolveOrCreateDestination(String destinationName, Session session) throws JMSException {
    Destination dest = null;
    boolean isPubSub = isTopicPrefix(destinationName) || (!isQueuePrefix(destinationName) && endpoint.isPubSubDomain());
    // try using destination resolver to lookup the destination
    if (endpoint.getDestinationResolver() != null) {
        dest = endpoint.getDestinationResolver().resolveDestinationName(session, destinationName, isPubSub);
        if (LOG.isDebugEnabled()) {
            LOG.debug("Resolved JMSReplyTo destination {} using DestinationResolver {} as PubSubDomain {} -> {}", new Object[] { destinationName, endpoint.getDestinationResolver(), isPubSub, dest });
        }
    }
    if (dest == null) {
        // must normalize the destination name
        String before = destinationName;
        destinationName = normalizeDestinationName(destinationName);
        LOG.trace("Normalized JMSReplyTo destination name {} -> {}", before, destinationName);
        // okay then fallback and create the queue/topic
        if (isPubSub) {
            LOG.debug("Creating JMSReplyTo topic: {}", destinationName);
            dest = session.createTopic(destinationName);
        } else {
            LOG.debug("Creating JMSReplyTo queue: {}", destinationName);
            dest = session.createQueue(destinationName);
        }
    }
    return dest;
}
Also used : Destination(javax.jms.Destination)

Example 2 with Destination

use of javax.jms.Destination in project camel by apache.

the class JmsProducer method processInOut.

protected boolean processInOut(final Exchange exchange, final AsyncCallback callback) {
    final org.apache.camel.Message in = exchange.getIn();
    String destinationName = in.getHeader(JmsConstants.JMS_DESTINATION_NAME, String.class);
    // remove the header so it wont be propagated
    in.removeHeader(JmsConstants.JMS_DESTINATION_NAME);
    if (destinationName == null) {
        destinationName = endpoint.getDestinationName();
    }
    Destination destination = in.getHeader(JmsConstants.JMS_DESTINATION, Destination.class);
    // remove the header so it wont be propagated
    in.removeHeader(JmsConstants.JMS_DESTINATION);
    if (destination == null) {
        destination = endpoint.getDestination();
    }
    if (destination != null) {
        // prefer to use destination over destination name
        destinationName = null;
    }
    initReplyManager();
    // the request timeout can be overruled by a header otherwise the endpoint configured value is used
    final long timeout = exchange.getIn().getHeader(JmsConstants.JMS_REQUEST_TIMEOUT, endpoint.getRequestTimeout(), long.class);
    final JmsConfiguration configuration = endpoint.getConfiguration();
    // when using message id as correlation id, we need at first to use a provisional correlation id
    // which we then update to the real JMSMessageID when the message has been sent
    // this is done with the help of the MessageSentCallback
    final boolean msgIdAsCorrId = configuration.isUseMessageIDAsCorrelationID();
    final String provisionalCorrelationId = msgIdAsCorrId ? getUuidGenerator().generateUuid() : null;
    MessageSentCallback messageSentCallback = null;
    if (msgIdAsCorrId) {
        messageSentCallback = new UseMessageIdAsCorrelationIdMessageSentCallback(replyManager, provisionalCorrelationId, timeout);
    }
    final String correlationProperty = configuration.getCorrelationProperty();
    final String correlationPropertyToUse = ofNullable(correlationProperty).orElse("JMSCorrelationID");
    final String originalCorrelationId = in.getHeader(correlationPropertyToUse, String.class);
    boolean generateFreshCorrId = (ObjectHelper.isEmpty(originalCorrelationId) && !msgIdAsCorrId) || (originalCorrelationId != null && originalCorrelationId.startsWith(GENERATED_CORRELATION_ID_PREFIX));
    if (generateFreshCorrId) {
        // we append the 'Camel-' prefix to know it was generated by us
        in.setHeader(correlationPropertyToUse, GENERATED_CORRELATION_ID_PREFIX + getUuidGenerator().generateUuid());
    }
    MessageCreator messageCreator = new MessageCreator() {

        public Message createMessage(Session session) throws JMSException {
            Message answer = endpoint.getBinding().makeJmsMessage(exchange, in, session, null);
            Destination replyTo = null;
            String replyToOverride = configuration.getReplyToOverride();
            if (replyToOverride != null) {
                replyTo = resolveOrCreateDestination(replyToOverride, session);
            } else {
                // get the reply to destination to be used from the reply manager
                replyTo = replyManager.getReplyTo();
            }
            if (replyTo == null) {
                throw new RuntimeExchangeException("Failed to resolve replyTo destination", exchange);
            }
            JmsMessageHelper.setJMSReplyTo(answer, replyTo);
            replyManager.setReplyToSelectorHeader(in, answer);
            String correlationId = determineCorrelationId(answer, provisionalCorrelationId);
            replyManager.registerReply(replyManager, exchange, callback, originalCorrelationId, correlationId, timeout);
            if (correlationProperty != null) {
                replyManager.setCorrelationProperty(correlationProperty);
            }
            if (LOG.isDebugEnabled()) {
                LOG.debug("Using {}: {}, JMSReplyTo destination: {}, with request timeout: {} ms.", new Object[] { correlationPropertyToUse, correlationId, replyTo, timeout });
            }
            LOG.trace("Created javax.jms.Message: {}", answer);
            return answer;
        }
    };
    doSend(true, destinationName, destination, messageCreator, messageSentCallback);
    // continue routing asynchronously (reply will be processed async when its received)
    return false;
}
Also used : Destination(javax.jms.Destination) Message(javax.jms.Message) UseMessageIdAsCorrelationIdMessageSentCallback(org.apache.camel.component.jms.reply.UseMessageIdAsCorrelationIdMessageSentCallback) UseMessageIdAsCorrelationIdMessageSentCallback(org.apache.camel.component.jms.reply.UseMessageIdAsCorrelationIdMessageSentCallback) MessageCreator(org.springframework.jms.core.MessageCreator) RuntimeExchangeException(org.apache.camel.RuntimeExchangeException) Session(javax.jms.Session)

Example 3 with Destination

use of javax.jms.Destination in project camel by apache.

the class JmsProducer method processInOnly.

protected boolean processInOnly(final Exchange exchange, final AsyncCallback callback) {
    final org.apache.camel.Message in = exchange.getIn();
    String destinationName = in.getHeader(JmsConstants.JMS_DESTINATION_NAME, String.class);
    if (destinationName != null) {
        // remove the header so it wont be propagated
        in.removeHeader(JmsConstants.JMS_DESTINATION_NAME);
    }
    if (destinationName == null) {
        destinationName = endpoint.getDestinationName();
    }
    Destination destination = in.getHeader(JmsConstants.JMS_DESTINATION, Destination.class);
    if (destination != null) {
        // remove the header so it wont be propagated
        in.removeHeader(JmsConstants.JMS_DESTINATION);
    }
    if (destination == null) {
        destination = endpoint.getDestination();
    }
    if (destination != null) {
        // prefer to use destination over destination name
        destinationName = null;
    }
    final String to = destinationName != null ? destinationName : "" + destination;
    MessageSentCallback messageSentCallback = getEndpoint().getConfiguration().isIncludeSentJMSMessageID() ? new InOnlyMessageSentCallback(exchange) : null;
    MessageCreator messageCreator = new MessageCreator() {

        public Message createMessage(Session session) throws JMSException {
            Message answer = endpoint.getBinding().makeJmsMessage(exchange, in, session, null);
            // when in InOnly mode the JMSReplyTo is a bit complicated
            // we only want to set the JMSReplyTo on the answer if
            // there is a JMSReplyTo from the header/endpoint and
            // we have been told to preserveMessageQos
            Object jmsReplyTo = JmsMessageHelper.getJMSReplyTo(answer);
            if (endpoint.isDisableReplyTo()) {
                // honor disable reply to configuration
                LOG.trace("ReplyTo is disabled on endpoint: {}", endpoint);
                JmsMessageHelper.setJMSReplyTo(answer, null);
            } else {
                // if the binding did not create the reply to then we have to try to create it here
                if (jmsReplyTo == null) {
                    // prefer reply to from header over endpoint configured
                    jmsReplyTo = exchange.getIn().getHeader("JMSReplyTo", String.class);
                    if (jmsReplyTo == null) {
                        jmsReplyTo = endpoint.getReplyTo();
                    }
                }
            }
            // unless we use preserveMessageQos=true to tell that we still want to use JMSReplyTo
            if (jmsReplyTo != null && !(endpoint.isPreserveMessageQos() || endpoint.isExplicitQosEnabled())) {
                // this behavior is also documented at the camel website
                if (LOG.isDebugEnabled()) {
                    LOG.debug("Disabling JMSReplyTo: {} for destination: {}. Use preserveMessageQos=true to force Camel to keep the JMSReplyTo on endpoint: {}", new Object[] { jmsReplyTo, to, endpoint });
                }
                jmsReplyTo = null;
            }
            // and if needed create the destination using the session if needed to
            if (jmsReplyTo != null && jmsReplyTo instanceof String) {
                String replyTo = (String) jmsReplyTo;
                // we need to null it as we use the String to resolve it as a Destination instance
                jmsReplyTo = resolveOrCreateDestination(replyTo, session);
            }
            // set the JMSReplyTo on the answer if we are to use it
            Destination replyTo = null;
            String replyToOverride = endpoint.getConfiguration().getReplyToOverride();
            if (replyToOverride != null) {
                replyTo = resolveOrCreateDestination(replyToOverride, session);
            } else if (jmsReplyTo instanceof Destination) {
                replyTo = (Destination) jmsReplyTo;
            }
            if (replyTo != null) {
                LOG.debug("Using JMSReplyTo destination: {}", replyTo);
                JmsMessageHelper.setJMSReplyTo(answer, replyTo);
            } else {
                // do not use JMSReplyTo
                log.trace("Not using JMSReplyTo");
                JmsMessageHelper.setJMSReplyTo(answer, null);
            }
            LOG.trace("Created javax.jms.Message: {}", answer);
            return answer;
        }
    };
    doSend(false, destinationName, destination, messageCreator, messageSentCallback);
    // after sending then set the OUT message id to the JMSMessageID so its identical
    setMessageId(exchange);
    // we are synchronous so return true
    callback.done(true);
    return true;
}
Also used : Destination(javax.jms.Destination) Message(javax.jms.Message) UseMessageIdAsCorrelationIdMessageSentCallback(org.apache.camel.component.jms.reply.UseMessageIdAsCorrelationIdMessageSentCallback) MessageCreator(org.springframework.jms.core.MessageCreator) Session(javax.jms.Session)

Example 4 with Destination

use of javax.jms.Destination in project camel by apache.

the class EndpointMessageListener method onMessage.

@Override
public void onMessage(Message message, Session session) throws JMSException {
    LOG.trace("onMessage START");
    LOG.debug("{} consumer received JMS message: {}", endpoint, message);
    boolean sendReply;
    RuntimeCamelException rce;
    try {
        Object replyDestination = getReplyToDestination(message);
        // we can only send back a reply if there was a reply destination configured
        // and disableReplyTo hasn't been explicit enabled
        sendReply = replyDestination != null && !disableReplyTo;
        // we should also not send back reply to ourself if this destination and replyDestination is the same
        Destination destination = JmsMessageHelper.getJMSDestination(message);
        if (destination != null && sendReply && !endpoint.isReplyToSameDestinationAllowed() && destination.equals(replyDestination)) {
            LOG.debug("JMSDestination and JMSReplyTo is the same, will skip sending a reply message to itself: {}", destination);
            sendReply = false;
        }
        final Exchange exchange = createExchange(message, session, replyDestination);
        if (eagerLoadingOfProperties) {
            exchange.getIn().getHeaders();
        }
        String correlationId = message.getJMSCorrelationID();
        if (correlationId != null) {
            LOG.debug("Received Message has JMSCorrelationID [{}]", correlationId);
        }
        // process the exchange either asynchronously or synchronous
        LOG.trace("onMessage.process START");
        AsyncCallback callback = new EndpointMessageListenerAsyncCallback(message, exchange, endpoint, sendReply, replyDestination);
        // async is by default false, which mean we by default will process the exchange synchronously
        // to keep backwards compatible, as well ensure this consumer will pickup messages in order
        // (eg to not consume the next message before the previous has been fully processed)
        // but if end user explicit configure consumerAsync=true, then we can process the message
        // asynchronously (unless endpoint has been configured synchronous, or we use transaction)
        boolean forceSync = endpoint.isSynchronous() || endpoint.isTransacted();
        if (forceSync || !isAsync()) {
            // must process synchronous if transacted or configured to do so
            if (LOG.isTraceEnabled()) {
                LOG.trace("Processing exchange {} synchronously", exchange.getExchangeId());
            }
            try {
                processor.process(exchange);
            } catch (Exception e) {
                exchange.setException(e);
            } finally {
                callback.done(true);
            }
        } else {
            // process asynchronous using the async routing engine
            if (LOG.isTraceEnabled()) {
                LOG.trace("Processing exchange {} asynchronously", exchange.getExchangeId());
            }
            boolean sync = processor.process(exchange, callback);
            if (!sync) {
                // will be done async so return now
                return;
            }
        }
        // if we failed processed the exchange from the async callback task, then grab the exception
        rce = exchange.getException(RuntimeCamelException.class);
    } catch (Exception e) {
        rce = wrapRuntimeCamelException(e);
    }
    // the JMS listener will use the error handler to handle the uncaught exception
    if (rce != null) {
        LOG.trace("onMessage END throwing exception: {}", rce.getMessage());
        // on the JmsEndpoint to handle the exception
        throw rce;
    }
    LOG.trace("onMessage END");
}
Also used : Exchange(org.apache.camel.Exchange) Destination(javax.jms.Destination) AsyncCallback(org.apache.camel.AsyncCallback) RuntimeCamelException(org.apache.camel.RuntimeCamelException) ObjectHelper.wrapRuntimeCamelException(org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException) RuntimeCamelException(org.apache.camel.RuntimeCamelException) RollbackExchangeException(org.apache.camel.RollbackExchangeException) JMSException(javax.jms.JMSException) ObjectHelper.wrapRuntimeCamelException(org.apache.camel.util.ObjectHelper.wrapRuntimeCamelException)

Example 5 with Destination

use of javax.jms.Destination in project camel by apache.

the class JmsProducerWithJMSHeaderTest method testInOnlyJMSDestination.

@Test
public void testInOnlyJMSDestination() throws Exception {
    Destination queue = new ActiveMQQueue("foo");
    MockEndpoint mock = getMockEndpoint("mock:result");
    mock.expectedMessageCount(1);
    mock.message(0).header("JMSDestination").isNotNull();
    template.sendBodyAndHeader("activemq:queue:bar", "Hello World", JmsConstants.JMS_DESTINATION, queue);
    assertMockEndpointsSatisfied();
    assertEquals("queue://foo", mock.getReceivedExchanges().get(0).getIn().getHeader("JMSDestination", Destination.class).toString());
}
Also used : Destination(javax.jms.Destination) MockEndpoint(org.apache.camel.component.mock.MockEndpoint) ActiveMQQueue(org.apache.activemq.command.ActiveMQQueue) Test(org.junit.Test)

Aggregations

Destination (javax.jms.Destination)137 Test (org.junit.Test)41 TextMessage (javax.jms.TextMessage)38 JMSException (javax.jms.JMSException)33 Message (javax.jms.Message)27 Session (javax.jms.Session)27 MessageProducer (javax.jms.MessageProducer)22 Connection (javax.jms.Connection)15 ConnectionFactory (javax.jms.ConnectionFactory)15 JMSContext (javax.jms.JMSContext)15 CountDownLatch (java.util.concurrent.CountDownLatch)13 MessageConsumer (javax.jms.MessageConsumer)12 StubTextMessage (org.springframework.jms.StubTextMessage)11 ObjectMessage (javax.jms.ObjectMessage)10 ActiveMQQueue (org.apache.activemq.command.ActiveMQQueue)10 MapMessage (javax.jms.MapMessage)7 Queue (javax.jms.Queue)7 Map (java.util.Map)6 HashMap (java.util.HashMap)5 JMSConsumer (javax.jms.JMSConsumer)5