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.seda;
018    
019    import java.util.concurrent.BlockingQueue;
020    import java.util.concurrent.ExecutorService;
021    import java.util.concurrent.TimeUnit;
022    
023    import org.apache.camel.Consumer;
024    import org.apache.camel.Exchange;
025    import org.apache.camel.Processor;
026    import org.apache.camel.impl.ServiceSupport;
027    import org.apache.camel.util.concurrent.ExecutorServiceHelper;
028    import org.apache.commons.logging.Log;
029    import org.apache.commons.logging.LogFactory;
030    
031    /**
032     * A Consumer for the SEDA component.
033     *
034     * @version $Revision: 772598 $
035     */
036    public class SedaConsumer extends ServiceSupport implements Consumer, Runnable {
037        private static final transient Log LOG = LogFactory.getLog(SedaConsumer.class);
038    
039        private SedaEndpoint endpoint;
040        private Processor processor;
041        private ExecutorService executor;
042    
043        public SedaConsumer(SedaEndpoint endpoint, Processor processor) {
044            this.endpoint = endpoint;
045            this.processor = processor;
046        }
047    
048        @Override
049        public String toString() {
050            return "SedaConsumer[" + endpoint.getEndpointUri() + "]";
051        }
052    
053        public void run() {
054            BlockingQueue<Exchange> queue = endpoint.getQueue();
055            while (queue != null && isRunAllowed()) {
056                final Exchange exchange;
057                try {
058                    exchange = queue.poll(1000, TimeUnit.MILLISECONDS);
059                } catch (InterruptedException e) {
060                    LOG.debug("Sleep interrupted, are we stopping? " + (isStopping() || isStopped()));
061                    continue;
062                }
063                if (exchange != null) {
064                    if (isRunAllowed()) {
065                        try {
066                            processor.process(exchange);
067                        } catch (Exception e) {
068                            LOG.error("Seda queue caught: " + e, e);
069                        }
070                    } else {
071                        LOG.warn("This consumer is stopped during polling an exchange, so putting it back on the seda queue: " + exchange);
072                        try {
073                            queue.put(exchange);
074                        } catch (InterruptedException e) {
075                            LOG.debug("Sleep interrupted, are we stopping? " + (isStopping() || isStopped()));
076                        }
077                    }
078                }
079            }
080        }
081    
082        protected void doStart() throws Exception {
083            int poolSize = endpoint.getConcurrentConsumers();
084            executor = ExecutorServiceHelper.newFixedThreadPool(poolSize, endpoint.getEndpointUri(), true);
085            for (int i = 0; i < poolSize; i++) {
086                executor.execute(this);
087            }
088            endpoint.onStarted(this);
089        }
090    
091        protected void doStop() throws Exception {
092            endpoint.onStopped(this);
093            
094            executor.shutdownNow();
095            executor = null;
096        }
097    
098    }