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.model.loadbalancer;
018
019import java.util.ArrayList;
020import java.util.List;
021import javax.xml.bind.annotation.XmlAccessType;
022import javax.xml.bind.annotation.XmlAccessorType;
023import javax.xml.bind.annotation.XmlAttribute;
024import javax.xml.bind.annotation.XmlRootElement;
025
026import org.apache.camel.model.LoadBalancerDefinition;
027import org.apache.camel.processor.loadbalancer.LoadBalancer;
028import org.apache.camel.processor.loadbalancer.WeightedLoadBalancer;
029import org.apache.camel.processor.loadbalancer.WeightedRandomLoadBalancer;
030import org.apache.camel.processor.loadbalancer.WeightedRoundRobinLoadBalancer;
031import org.apache.camel.spi.Metadata;
032import org.apache.camel.spi.RouteContext;
033import org.apache.camel.util.ObjectHelper;
034
035/**
036 * Weighted load balancer
037 *
038 * The weighted load balancing policy allows you to specify a processing load distribution ratio for each server
039 * with respect to others. In addition to the weight, endpoint selection is then further refined using
040 * random distribution based on weight.
041 */
042@Metadata(label = "configuration,loadbalance")
043@XmlRootElement(name = "weighted")
044@XmlAccessorType(XmlAccessType.FIELD)
045public class WeightedLoadBalancerDefinition extends LoadBalancerDefinition {
046    @XmlAttribute
047    private Boolean roundRobin;
048    @XmlAttribute(required = true)
049    private String distributionRatio;
050    @XmlAttribute @Metadata(defaultValue = ",")
051    private String distributionRatioDelimiter;
052
053    public WeightedLoadBalancerDefinition() {
054    }
055
056    @Override
057    protected LoadBalancer createLoadBalancer(RouteContext routeContext) {
058        WeightedLoadBalancer loadBalancer;
059        List<Integer> distributionRatioList = new ArrayList<Integer>();
060        
061        try {
062            if (distributionRatioDelimiter == null) {
063                distributionRatioDelimiter = ",";
064            }
065            
066            String[] ratios = distributionRatio.split(distributionRatioDelimiter);
067            for (String ratio : ratios) {
068                distributionRatioList.add(new Integer(ratio.trim()));
069            }
070
071            boolean isRoundRobin = getRoundRobin() != null && getRoundRobin();
072            if (isRoundRobin) {
073                loadBalancer = new WeightedRoundRobinLoadBalancer(distributionRatioList);
074            } else {
075                loadBalancer = new WeightedRandomLoadBalancer(distributionRatioList);
076            }
077        } catch (Exception e) {
078            throw ObjectHelper.wrapRuntimeCamelException(e);
079        }
080
081        return loadBalancer;
082    }
083
084    public Boolean getRoundRobin() {
085        return roundRobin;
086    }
087
088    /**
089     * To enable round robin mode. By default the weighted distribution mode is used.
090     * <p/>
091     * The default value is false.
092     */
093    public void setRoundRobin(Boolean roundRobin) {
094        this.roundRobin = roundRobin;
095    }
096
097    public String getDistributionRatio() {
098        return distributionRatio;
099    }
100
101    /**
102     * The distribution ratio is a delimited String consisting on integer weights separated by delimiters for example "2,3,5".
103     * The distributionRatio must match the number of endpoints and/or processors specified in the load balancer list.
104     */
105    public void setDistributionRatio(String distributionRatio) {
106        this.distributionRatio = distributionRatio;
107    }
108
109    public String getDistributionRatioDelimiter() {
110        return distributionRatioDelimiter;
111    }
112
113    /**
114     * Delimiter used to specify the distribution ratio.
115     * <p/>
116     * The default value is ,
117     */
118    public void setDistributionRatioDelimiter(String distributionRatioDelimiter) {
119        this.distributionRatioDelimiter = distributionRatioDelimiter;
120    }
121
122    @Override
123    public String toString() {
124        boolean isRoundRobin = getRoundRobin() != null && getRoundRobin();
125        if (isRoundRobin) {
126            return "WeightedRoundRobinLoadBalancer[" + distributionRatio + "]";
127        } else {
128            return "WeightedRandomLoadBalancer[" + distributionRatio + "]";
129        }
130    }
131}