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.ArrayList;
020    import java.util.HashSet;
021    import java.util.List;
022    import java.util.Set;
023    import java.util.concurrent.BlockingQueue;
024    import java.util.concurrent.CopyOnWriteArraySet;
025    import java.util.concurrent.LinkedBlockingQueue;
026    
027    import org.apache.camel.Component;
028    import org.apache.camel.Consumer;
029    import org.apache.camel.Exchange;
030    import org.apache.camel.MultipleConsumersSupport;
031    import org.apache.camel.Processor;
032    import org.apache.camel.Producer;
033    import org.apache.camel.WaitForTaskToComplete;
034    import org.apache.camel.impl.DefaultEndpoint;
035    import org.apache.camel.spi.BrowsableEndpoint;
036    
037    /**
038     * An implementation of the <a
039     * href="http://camel.apache.org/queue.html">Queue components</a> for
040     * asynchronous SEDA exchanges on a {@link BlockingQueue} within a CamelContext
041     *
042     * @version $Revision: 890752 $
043     */
044    public class SedaEndpoint extends DefaultEndpoint implements BrowsableEndpoint, MultipleConsumersSupport {
045        private volatile BlockingQueue<Exchange> queue;
046        private int size = 1000;
047        private int concurrentConsumers = 1;
048        private boolean multipleConsumers;
049        private WaitForTaskToComplete waitForTaskToComplete = WaitForTaskToComplete.IfReplyExpected;
050        private long timeout = 30000;
051        private volatile Set<SedaProducer> producers = new CopyOnWriteArraySet<SedaProducer>();
052        private volatile Set<SedaConsumer> consumers = new CopyOnWriteArraySet<SedaConsumer>();
053    
054        public SedaEndpoint() {
055        }
056    
057        public SedaEndpoint(String endpointUri, Component component, BlockingQueue<Exchange> queue) {
058            this(endpointUri, component, queue, 1);
059        }
060    
061        public SedaEndpoint(String endpointUri, Component component, BlockingQueue<Exchange> queue, int concurrentConsumers) {
062            super(endpointUri, component);
063            this.queue = queue;
064            this.concurrentConsumers = concurrentConsumers;
065        }
066    
067        public SedaEndpoint(String endpointUri, BlockingQueue<Exchange> queue) {
068            this(endpointUri, queue, 1);
069        }
070    
071        public SedaEndpoint(String endpointUri, BlockingQueue<Exchange> queue, int concurrentConsumers) {
072            super(endpointUri);
073            this.queue = queue;
074            this.concurrentConsumers = concurrentConsumers;
075        }
076        
077        public Producer createProducer() throws Exception {
078            return new SedaProducer(this, getQueue(), getWaitForTaskToComplete(), getTimeout());
079        }
080    
081        public Consumer createConsumer(Processor processor) throws Exception {
082            return new SedaConsumer(this, processor);
083        }
084    
085        public synchronized BlockingQueue<Exchange> getQueue() {
086            if (queue == null) {
087                queue = new LinkedBlockingQueue<Exchange>(size);
088            }
089            return queue;
090        }
091        
092        public void setQueue(BlockingQueue<Exchange> queue) {
093            this.queue = queue;
094        }
095    
096        public int getSize() {
097            return size;
098        }
099    
100        public void setSize(int size) {
101            this.size = size;
102        }
103    
104        public void setConcurrentConsumers(int concurrentConsumers) {
105            this.concurrentConsumers = concurrentConsumers;
106        }
107        
108        public int getConcurrentConsumers() {
109            return concurrentConsumers;
110        }
111    
112        public WaitForTaskToComplete getWaitForTaskToComplete() {
113            return waitForTaskToComplete;
114        }
115    
116        public void setWaitForTaskToComplete(WaitForTaskToComplete waitForTaskToComplete) {
117            this.waitForTaskToComplete = waitForTaskToComplete;
118        }
119    
120        public long getTimeout() {
121            return timeout;
122        }
123    
124        public void setTimeout(long timeout) {
125            this.timeout = timeout;
126        }
127    
128        public boolean isMultipleConsumers() {
129            return multipleConsumers;
130        }
131    
132        public void setMultipleConsumers(boolean multipleConsumers) {
133            this.multipleConsumers = multipleConsumers;
134        }
135    
136        public boolean isSingleton() {
137            return true;
138        }
139    
140        /**
141         * Returns the current pending exchanges
142         */
143        public List<Exchange> getExchanges() {
144            return new ArrayList<Exchange>(getQueue());
145        }
146    
147        public boolean isMultipleConsumersSupported() {
148            return isMultipleConsumers();
149        }
150    
151        /**
152         * Returns the current active consumers on this endpoint
153         */
154        public Set<SedaConsumer> getConsumers() {
155            return new HashSet<SedaConsumer>(consumers);
156        }
157    
158        /**
159         * Returns the current active producers on this endpoint
160         */
161        public Set<SedaProducer> getProducers() {
162            return new HashSet<SedaProducer>(producers);
163        }
164        
165        void onStarted(SedaProducer producer) {
166            producers.add(producer);
167        }
168    
169        void onStopped(SedaProducer producer) {
170            producers.remove(producer);
171        }
172    
173        void onStarted(SedaConsumer consumer) {
174            consumers.add(consumer);
175        }
176    
177        void onStopped(SedaConsumer consumer) {
178            consumers.remove(consumer);
179        }
180    
181    }