/* * @see javax.jms.MessageListener#onMessage(javax.jms.Message) * * @param message */ @Override public void onMessage(Message message) { RuntimeCamelException rce = null; try { final DefaultExchange exchange = (DefaultExchange) JmsMessageHelper.createExchange(message, getEndpoint()); log.debug("Processing Exchange.id:{}", exchange.getExchangeId()); if (isTransacted() && synchronization != null) { exchange.addOnCompletion(synchronization); } try { if (isTransacted() || isSynchronous()) { log.debug(" Handling synchronous message: {}", exchange.getIn().getBody()); handleMessage(exchange); } else { log.debug(" Handling asynchronous message: {}", exchange.getIn().getBody()); executor.execute( new Runnable() { @Override public void run() { try { handleMessage(exchange); } catch (Exception e) { exchange.setException(e); } } }); } } catch (Exception e) { if (exchange != null) { if (exchange.getException() == null) { exchange.setException(e); } else { throw e; } } } } catch (Exception e) { rce = wrapRuntimeCamelException(e); } finally { if (rce != null) { throw rce; } } }
/** * TODO time out is actually double as it waits for the producer and then waits for the response. * Use an atomic long to manage the countdown */ @Override public void sendMessage( final Exchange exchange, final AsyncCallback callback, final MessageProducerResources producer, final ReleaseProducerCallback releaseProducerCallback) throws Exception { Message request = getEndpoint().getBinding().makeJmsMessage(exchange, producer.getSession()); String correlationId = exchange.getIn().getHeader(JmsConstants.JMS_CORRELATION_ID, String.class); if (correlationId == null) { // we append the 'Camel-' prefix to know it was generated by us correlationId = GENERATED_CORRELATION_ID_PREFIX + getUuidGenerator().generateUuid(); } Object responseObject = null; Exchanger<Object> messageExchanger = new Exchanger<Object>(); JmsMessageHelper.setCorrelationId(request, correlationId); EXCHANGERS.put(correlationId, messageExchanger); MessageConsumerResources consumer = consumers.borrowObject(); JmsMessageHelper.setJMSReplyTo(request, consumer.getReplyToDestination()); consumers.returnObject(consumer); producer.getMessageProducer().send(request); // Return the producer to the pool so another waiting producer // can move forward // without waiting on us to complete the exchange try { releaseProducerCallback.release(producer); } catch (Exception exception) { // thrown if the pool is full. safe to ignore. } try { responseObject = messageExchanger.exchange(null, getResponseTimeOut(), TimeUnit.MILLISECONDS); EXCHANGERS.remove(correlationId); } catch (InterruptedException e) { log.debug("Exchanger was interrupted while waiting on response", e); exchange.setException(e); } catch (TimeoutException e) { log.debug("Exchanger timed out while waiting on response", e); exchange.setException(e); } if (exchange.getException() == null) { if (responseObject instanceof Throwable) { exchange.setException((Throwable) responseObject); } else if (responseObject instanceof Message) { Message message = (Message) responseObject; SjmsMessage response = new SjmsMessage(message, consumer.getSession(), getEndpoint().getBinding()); // the JmsBinding is designed to be "pull-based": it will populate the Camel message on // demand // therefore, we link Exchange and OUT message before continuing, so that the JmsBinding has // full access // to everything it may need, and can populate headers, properties, etc. accordingly (solves // CAMEL-6218). exchange.setOut(response); } else { exchange.setException(new CamelException("Unknown response type: " + responseObject)); } } callback.done(isSynchronous()); }