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     */
017    package org.apache.camel.component.spring.integration.adapter;
018    
019    import java.util.concurrent.atomic.AtomicBoolean;
020    
021    import org.apache.camel.Consumer;
022    import org.apache.camel.Endpoint;
023    import org.apache.camel.Exchange;
024    import org.apache.camel.Processor;
025    import org.apache.camel.component.spring.integration.SpringIntegrationBinding;
026    import org.slf4j.Logger;
027    import org.slf4j.LoggerFactory;
028    import org.springframework.beans.factory.DisposableBean;
029    import org.springframework.beans.factory.InitializingBean;
030    import org.springframework.integration.Message;
031    import org.springframework.integration.MessageChannel;
032    import org.springframework.integration.MessageHeaders;
033    import org.springframework.integration.channel.DirectChannel;
034    import org.springframework.integration.core.MessageHandler;
035    
036    /**
037     * A CamelContext will be injected into CameSourceAdapter which will
038     * let Spring Integration channel talk to the CamelContext certain endpoint
039     *
040     * @version 
041     */
042    public class CamelSourceAdapter extends AbstractCamelAdapter implements InitializingBean, DisposableBean {
043        private static final Logger LOG = LoggerFactory.getLogger(CamelSourceAdapter.class);
044    
045        private Consumer consumer;
046        private Endpoint camelEndpoint;
047        private MessageChannel requestChannel;
048        private DirectChannel replyChannel;
049        private final AtomicBoolean initialized = new AtomicBoolean();
050    
051        public void setRequestChannel(MessageChannel channel) {
052            requestChannel = channel;        
053        }
054    
055        public MessageChannel getChannel() {
056            return requestChannel;
057        }
058    
059        public void setReplyChannel(DirectChannel channel) {        
060            replyChannel = channel;
061        }
062    
063        protected class ConsumerProcessor implements Processor {
064            public void process(final Exchange exchange) throws Exception {
065                org.springframework.integration.Message request = SpringIntegrationBinding.createSpringIntegrationMessage(exchange);
066    
067                if (exchange.getPattern().isOutCapable()) {
068                    exchange.getIn().getHeaders().put(MessageHeaders.REPLY_CHANNEL , replyChannel);
069    
070                    // we want to do in-out so the inputChannel is mandatory (used to receive reply from spring integration)
071                    if (replyChannel == null) {
072                        throw new IllegalArgumentException("ReplyChannel has not been configured on: " + this);
073                    }
074    
075                    replyChannel.subscribe(new MessageHandler() {
076                        public void handleMessage(Message<?> message) {
077                            LOG.debug("Received {} from ReplyChannel: {}", message, replyChannel);
078                            //TODO set the corralationID
079                            SpringIntegrationBinding.storeToCamelMessage(message, exchange.getOut());
080                        }
081                    });
082                }
083                     
084                requestChannel.send(request);
085            }
086        }
087    
088        public final void afterPropertiesSet() throws Exception {
089            if (initialized.compareAndSet(false, true)) {
090                initialize();
091            }
092        }
093    
094        public void destroy() throws Exception {
095            if (consumer != null) {
096                consumer.stop();
097            }
098        }
099    
100        protected void initialize() throws Exception {
101            // start the service here
102            camelEndpoint = getCamelContext().getEndpoint(getCamelEndpointUri());
103            consumer = camelEndpoint.createConsumer(new ConsumerProcessor());
104            consumer.start();
105        }
106    
107    }