001/** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.activemq.camel.component.broker; 018 019import org.apache.activemq.broker.ProducerBrokerExchange; 020import org.apache.activemq.command.ActiveMQMessage; 021import org.apache.camel.AsyncCallback; 022import org.apache.camel.Exchange; 023import org.apache.camel.Message; 024import org.apache.camel.component.jms.JmsMessage; 025import org.apache.camel.impl.DefaultAsyncProducer; 026 027import javax.jms.JMSException; 028import java.util.Map; 029 030public class BrokerProducer extends DefaultAsyncProducer { 031 private final BrokerEndpoint brokerEndpoint; 032 033 public BrokerProducer(BrokerEndpoint endpoint) { 034 super(endpoint); 035 brokerEndpoint = endpoint; 036 } 037 038 @Override 039 public boolean process(Exchange exchange, AsyncCallback callback) { 040 try { 041 //In the middle of the broker - InOut doesn't make any sense 042 //so we do in only 043 return processInOnly(exchange, callback); 044 } catch (Throwable e) { 045 // must catch exception to ensure callback is invoked as expected 046 // to let Camel error handling deal with this 047 exchange.setException(e); 048 callback.done(true); 049 return true; 050 } 051 } 052 053 protected boolean processInOnly(final Exchange exchange, final AsyncCallback callback) { 054 try { 055 ActiveMQMessage message = getMessage(exchange); 056 057 if (message != null) { 058 message.setDestination(brokerEndpoint.getDestination()); 059 //if the ProducerBrokerExchange is null the broker will create it 060 ProducerBrokerExchange producerBrokerExchange = (ProducerBrokerExchange) exchange.getProperty(BrokerEndpoint.PRODUCER_BROKER_EXCHANGE); 061 062 brokerEndpoint.inject(producerBrokerExchange, message); 063 } 064 } catch (Exception e) { 065 exchange.setException(e); 066 } 067 callback.done(true); 068 return true; 069 } 070 071 private ActiveMQMessage getMessage(Exchange exchange) throws IllegalStateException, JMSException { 072 Message camelMessage = getMessageFromExchange(exchange); 073 checkOriginalMessage(camelMessage); 074 ActiveMQMessage result = (ActiveMQMessage) ((JmsMessage) camelMessage).getJmsMessage(); 075 applyNewHeaders(result, camelMessage.getHeaders()); 076 return result; 077 } 078 079 private Message getMessageFromExchange(Exchange exchange) { 080 if (exchange.hasOut()) { 081 return exchange.getOut(); 082 } 083 084 return exchange.getIn(); 085 } 086 087 private void checkOriginalMessage(Message camelMessage) throws IllegalStateException { 088 /** 089 * We purposely don't want to support injecting messages half-way through 090 * broker processing - use the activemq camel component for that - but 091 * we will support changing message headers and destinations. 092 */ 093 094 if (!(camelMessage instanceof JmsMessage)) { 095 throw new IllegalStateException("Not the original message from the broker " + camelMessage); 096 } 097 098 javax.jms.Message message = ((JmsMessage) camelMessage).getJmsMessage(); 099 100 if (!(message instanceof ActiveMQMessage)) { 101 throw new IllegalStateException("Not the original message from the broker " + message); 102 } 103 } 104 105 private void applyNewHeaders(ActiveMQMessage message, Map<String, Object> headers) throws JMSException { 106 for (Map.Entry<String, Object> entry : headers.entrySet()) { 107 String key = entry.getKey(); 108 Object value = entry.getValue(); 109 if(value == null) { 110 continue; 111 } 112 message.setObjectProperty(key, value.toString(), false); 113 } 114 } 115}