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.camel.processor.loadbalancer;
018
019import java.util.ArrayList;
020import java.util.List;
021import java.util.concurrent.CopyOnWriteArrayList;
022
023import org.apache.camel.Exchange;
024import org.apache.camel.Navigate;
025import org.apache.camel.Processor;
026import org.apache.camel.spi.IdAware;
027import org.apache.camel.support.ServiceSupport;
028import org.apache.camel.util.AsyncProcessorHelper;
029import org.apache.camel.util.ServiceHelper;
030import org.slf4j.Logger;
031import org.slf4j.LoggerFactory;
032
033/**
034 * A default base class for a {@link LoadBalancer} implementation.
035 * <p/>
036 * This implementation is dedicated for asynchronous load balancers.
037 * <p/>
038 * Consider using the {@link SimpleLoadBalancerSupport} if your load balancer does not by nature
039 * support asynchronous routing.
040 *
041 * @version 
042 */
043public abstract class LoadBalancerSupport extends ServiceSupport implements LoadBalancer, Navigate<Processor>, IdAware {
044
045    protected final Logger log = LoggerFactory.getLogger(getClass());
046    private final List<Processor> processors = new CopyOnWriteArrayList<>();
047    private String id;
048
049    public void addProcessor(Processor processor) {
050        processors.add(processor);
051    }
052
053    public void removeProcessor(Processor processor) {
054        processors.remove(processor);
055    }
056
057    public List<Processor> getProcessors() {
058        return processors;
059    }
060
061    public List<Processor> next() {
062        if (!hasNext()) {
063            return null;
064        }
065        return new ArrayList<>(processors);
066    }
067
068    public boolean hasNext() {
069        return processors.size() > 0;
070    }
071
072    public String getId() {
073        return id;
074    }
075
076    public void setId(String id) {
077        this.id = id;
078    }
079
080    protected void doStart() throws Exception {
081        ServiceHelper.startServices(processors);
082    }
083
084    protected void doStop() throws Exception {
085        ServiceHelper.stopServices(processors);
086    }
087
088    @Override
089    protected void doShutdown() throws Exception {
090        ServiceHelper.stopAndShutdownServices(processors);
091        for (Processor processor : processors) {
092            removeProcessor(processor);
093        }
094    }
095
096    public void process(Exchange exchange) throws Exception {
097        AsyncProcessorHelper.process(this, exchange);
098    }
099}