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 = "eip,routing,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<>();
060        
061        try {
062            String[] ratios = distributionRatio.split(getDistributionRatioDelimiter());
063            for (String ratio : ratios) {
064                distributionRatioList.add(new Integer(ratio.trim()));
065            }
066
067            boolean isRoundRobin = getRoundRobin() != null && getRoundRobin();
068            if (isRoundRobin) {
069                loadBalancer = new WeightedRoundRobinLoadBalancer(distributionRatioList);
070            } else {
071                loadBalancer = new WeightedRandomLoadBalancer(distributionRatioList);
072            }
073        } catch (Exception e) {
074            throw ObjectHelper.wrapRuntimeCamelException(e);
075        }
076
077        return loadBalancer;
078    }
079
080    public Boolean getRoundRobin() {
081        return roundRobin;
082    }
083
084    /**
085     * To enable round robin mode. By default the weighted distribution mode is used.
086     * <p/>
087     * The default value is false.
088     */
089    public void setRoundRobin(Boolean roundRobin) {
090        this.roundRobin = roundRobin;
091    }
092
093    public String getDistributionRatio() {
094        return distributionRatio;
095    }
096
097    /**
098     * The distribution ratio is a delimited String consisting on integer weights separated by delimiters for example "2,3,5".
099     * The distributionRatio must match the number of endpoints and/or processors specified in the load balancer list.
100     */
101    public void setDistributionRatio(String distributionRatio) {
102        this.distributionRatio = distributionRatio;
103    }
104
105    public String getDistributionRatioDelimiter() {
106        return distributionRatioDelimiter == null ? "," : distributionRatioDelimiter;
107    }
108
109    /**
110     * Delimiter used to specify the distribution ratio.
111     * <p/>
112     * The default value is ,
113     */
114    public void setDistributionRatioDelimiter(String distributionRatioDelimiter) {
115        this.distributionRatioDelimiter = distributionRatioDelimiter;
116    }
117
118    @Override
119    public String toString() {
120        boolean isRoundRobin = getRoundRobin() != null && getRoundRobin();
121        if (isRoundRobin) {
122            return "WeightedRoundRobinLoadBalancer[" + distributionRatio + "]";
123        } else {
124            return "WeightedRandomLoadBalancer[" + distributionRatio + "]";
125        }
126    }
127}