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.model;
018
019 import java.util.ArrayList;
020 import java.util.Collection;
021 import java.util.List;
022
023 import javax.xml.bind.annotation.XmlAccessType;
024 import javax.xml.bind.annotation.XmlAccessorType;
025 import javax.xml.bind.annotation.XmlAttribute;
026 import javax.xml.bind.annotation.XmlElement;
027 import javax.xml.bind.annotation.XmlElementRef;
028 import javax.xml.bind.annotation.XmlElements;
029 import javax.xml.bind.annotation.XmlRootElement;
030
031 import org.apache.camel.Exchange;
032 import org.apache.camel.Expression;
033 import org.apache.camel.Processor;
034 import org.apache.camel.model.loadbalancer.LoadBalancerType;
035 import org.apache.camel.model.loadbalancer.RandomLoadBalanceStrategy;
036 import org.apache.camel.model.loadbalancer.RoundRobinLoadBalanceStrategy;
037 import org.apache.camel.model.loadbalancer.StickyLoadBalanceStrategy;
038 import org.apache.camel.model.loadbalancer.TopicLoadBalanceStrategy;
039 import org.apache.camel.processor.SendProcessor;
040 import org.apache.camel.processor.loadbalancer.LoadBalancer;
041 import org.apache.camel.processor.loadbalancer.RandomLoadBalancer;
042 import org.apache.camel.processor.loadbalancer.RoundRobinLoadBalancer;
043 import org.apache.camel.processor.loadbalancer.StickyLoadBalancer;
044 import org.apache.camel.processor.loadbalancer.TopicLoadBalancer;
045 import org.apache.camel.spi.RouteContext;
046 import org.apache.camel.util.CollectionStringBuffer;
047
048 /**
049 * Represents an XML <loadBalance/> element
050 */
051 @XmlRootElement(name = "loadBalance")
052 @XmlAccessorType(XmlAccessType.FIELD)
053 public class LoadBalanceType extends ProcessorType<LoadBalanceType> {
054 @XmlAttribute(required = false)
055 private String ref;
056
057 @XmlElements({
058 @XmlElement(required = false, name = "roundRobin", type = RoundRobinLoadBalanceStrategy.class),
059 @XmlElement(required = false, name = "random", type = RandomLoadBalanceStrategy.class),
060 @XmlElement(required = false, name = "sticky", type = StickyLoadBalanceStrategy.class),
061 @XmlElement(required = false, name = "topic", type = TopicLoadBalanceStrategy.class)}
062 )
063 private LoadBalancerType loadBalancerType;
064
065 @XmlElementRef
066 private List<ProcessorType<?>> outputs = new ArrayList<ProcessorType<?>>();
067
068 public LoadBalanceType() {
069 }
070
071 @Override
072 public String getShortName() {
073 return "loadbalance";
074 }
075
076 public List<ProcessorType<?>> getOutputs() {
077 return outputs;
078 }
079
080 public void setOutputs(List<ProcessorType<?>> outputs) {
081 this.outputs = outputs;
082 if (outputs != null) {
083 for (ProcessorType output : outputs) {
084 configureChild(output);
085 }
086 }
087 }
088
089
090 @Override
091 protected void configureChild(ProcessorType output) {
092 super.configureChild(output);
093 if (isInheritErrorHandler()) {
094 output.setErrorHandlerBuilder(getErrorHandlerBuilder());
095 }
096 }
097
098 public String getRef() {
099 return ref;
100 }
101
102 public void setRef(String ref) {
103 this.ref = ref;
104 }
105
106 public LoadBalancerType getLoadBalancerType() {
107 return loadBalancerType;
108 }
109
110 public void setLoadBalancerType(LoadBalancerType loadbalancer) {
111 loadBalancerType = loadbalancer;
112 }
113
114 protected Processor createOutputsProcessor(RouteContext routeContext, Collection<ProcessorType<?>> outputs)
115 throws Exception {
116 LoadBalancer loadBalancer = LoadBalancerType.getLoadBalancer(routeContext, loadBalancerType, ref);
117 for (ProcessorType processorType : outputs) {
118 // The outputs should be the SendProcessor
119 SendProcessor processor = (SendProcessor) processorType.createProcessor(routeContext);
120 loadBalancer.addProcessor(processor);
121 }
122 return loadBalancer;
123 }
124
125 @Override
126 public Processor createProcessor(RouteContext routeContext) throws Exception {
127 LoadBalancer loadBalancer = LoadBalancerType.getLoadBalancer(routeContext, loadBalancerType, ref);
128 for (ProcessorType processorType : getOutputs()) {
129 Processor processor = processorType.createProcessor(routeContext);
130 processor = processorType.wrapProcessorInInterceptors(routeContext, processor);
131 loadBalancer.addProcessor(processor);
132 }
133
134 return loadBalancer;
135 }
136
137 // Fluent API
138 // -------------------------------------------------------------------------
139 public LoadBalanceType setLoadBalancer(LoadBalancer loadBalancer) {
140 loadBalancerType = new LoadBalancerType(loadBalancer);
141 return this;
142 }
143
144 public LoadBalanceType roundRobin() {
145 loadBalancerType = new LoadBalancerType(new RoundRobinLoadBalancer());
146 return this;
147 }
148
149 public LoadBalanceType random() {
150 loadBalancerType = new LoadBalancerType(new RandomLoadBalancer());
151 return this;
152 }
153
154 public LoadBalanceType sticky(Expression<Exchange> correlationExpression) {
155 loadBalancerType = new LoadBalancerType(new StickyLoadBalancer(correlationExpression));
156 return this;
157 }
158
159 /**
160 * @deprecated will be removed in Camel 2.0, use multicast instead
161 */
162 public LoadBalanceType topic() {
163 loadBalancerType = new LoadBalancerType(new TopicLoadBalancer());
164 return this;
165 }
166
167 @Override
168 public String getLabel() {
169 CollectionStringBuffer buffer = new CollectionStringBuffer();
170 List<ProcessorType<?>> list = getOutputs();
171 for (ProcessorType<?> processorType : list) {
172 buffer.append(processorType.getLabel());
173 }
174 return buffer.toString();
175 }
176
177 @Override
178 public String toString() {
179 if (loadBalancerType != null) {
180 return "LoadBalanceType[" + loadBalancerType + ", " + getOutputs() + "]";
181 } else {
182 return "LoadBalanceType[ref: " + ref + ", " + getOutputs() + "]";
183 }
184 }
185
186 }