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; 018 019import java.util.concurrent.ExecutorService; 020 021import javax.xml.bind.annotation.XmlAccessType; 022import javax.xml.bind.annotation.XmlAccessorType; 023import javax.xml.bind.annotation.XmlAttribute; 024import javax.xml.bind.annotation.XmlElement; 025import javax.xml.bind.annotation.XmlRootElement; 026import javax.xml.bind.annotation.XmlTransient; 027import javax.xml.bind.annotation.XmlType; 028 029import org.apache.camel.Expression; 030import org.apache.camel.builder.ExpressionBuilder; 031import org.apache.camel.model.language.ExpressionDefinition; 032import org.apache.camel.spi.Metadata; 033 034/** 035 * Controls the rate at which messages are passed to the next node in the route 036 */ 037@Metadata(label = "eip,routing") 038@XmlRootElement(name = "throttle") 039@XmlAccessorType(XmlAccessType.FIELD) 040@XmlType(propOrder = {"expression", "correlationExpression"}) 041public class ThrottleDefinition extends ExpressionNode implements ExecutorServiceAwareDefinition<ThrottleDefinition> { 042 043 @XmlElement(name = "correlationExpression") 044 private ExpressionSubElementDefinition correlationExpression; 045 @XmlTransient 046 private ExecutorService executorService; 047 @XmlAttribute 048 private String executorServiceRef; 049 @XmlAttribute 050 @Metadata(defaultValue = "1000") 051 private Long timePeriodMillis; 052 @XmlAttribute 053 private Boolean asyncDelayed; 054 @XmlAttribute 055 @Metadata(defaultValue = "true") 056 private Boolean callerRunsWhenRejected; 057 @XmlAttribute 058 private Boolean rejectExecution; 059 060 public ThrottleDefinition() { 061 } 062 063 public ThrottleDefinition(Expression maximumRequestsPerPeriod) { 064 super(maximumRequestsPerPeriod); 065 } 066 067 public ThrottleDefinition(Expression maximumRequestsPerPeriod, Expression correlationExpression) { 068 this(ExpressionNodeHelper.toExpressionDefinition(maximumRequestsPerPeriod), correlationExpression); 069 } 070 071 private ThrottleDefinition(ExpressionDefinition maximumRequestsPerPeriod, Expression correlationExpression) { 072 super(maximumRequestsPerPeriod); 073 074 ExpressionSubElementDefinition cor = new ExpressionSubElementDefinition(); 075 cor.setExpressionType(ExpressionNodeHelper.toExpressionDefinition(correlationExpression)); 076 setCorrelationExpression(cor); 077 } 078 079 @Override 080 public String toString() { 081 return "Throttle[" + description() + "]"; 082 } 083 084 protected String description() { 085 return getExpression() + " request per " + getTimePeriodMillis() + " millis"; 086 } 087 088 @Override 089 public String getShortName() { 090 return "throttle"; 091 } 092 093 @Override 094 public String getLabel() { 095 return "throttle[" + description() + "]"; 096 } 097 098 // Fluent API 099 // ------------------------------------------------------------------------- 100 /** 101 * Sets the time period during which the maximum request count is valid for 102 * 103 * @param timePeriodMillis period in millis 104 * @return the builder 105 */ 106 public ThrottleDefinition timePeriodMillis(long timePeriodMillis) { 107 setTimePeriodMillis(timePeriodMillis); 108 return this; 109 } 110 111 /** 112 * Sets the time period during which the maximum request count per period 113 * 114 * @param maximumRequestsPerPeriod the maximum request count number per time 115 * period 116 * @return the builder 117 */ 118 public ThrottleDefinition maximumRequestsPerPeriod(long maximumRequestsPerPeriod) { 119 setExpression(ExpressionNodeHelper.toExpressionDefinition(ExpressionBuilder.constantExpression(maximumRequestsPerPeriod))); 120 return this; 121 } 122 123 /** 124 * Whether or not the caller should run the task when it was rejected by the 125 * thread pool. 126 * <p/> 127 * Is by default <tt>true</tt> 128 * 129 * @param callerRunsWhenRejected whether or not the caller should run 130 * @return the builder 131 */ 132 public ThrottleDefinition callerRunsWhenRejected(boolean callerRunsWhenRejected) { 133 setCallerRunsWhenRejected(callerRunsWhenRejected); 134 return this; 135 } 136 137 /** 138 * Enables asynchronous delay which means the thread will <b>not</b> block 139 * while delaying. 140 * 141 * @return the builder 142 */ 143 public ThrottleDefinition asyncDelayed() { 144 setAsyncDelayed(true); 145 return this; 146 } 147 148 /** 149 * Whether or not throttler throws the ThrottlerRejectedExecutionException 150 * when the exchange exceeds the request limit 151 * <p/> 152 * Is by default <tt>false</tt> 153 * 154 * @param rejectExecution throw the RejectExecutionException if the exchange 155 * exceeds the request limit 156 * @return the builder 157 */ 158 public ThrottleDefinition rejectExecution(boolean rejectExecution) { 159 setRejectExecution(rejectExecution); 160 return this; 161 } 162 163 /** 164 * To use a custom thread pool (ScheduledExecutorService) by the throttler. 165 * 166 * @param executorService the custom thread pool (must be scheduled) 167 * @return the builder 168 */ 169 @Override 170 public ThrottleDefinition executorService(ExecutorService executorService) { 171 setExecutorService(executorService); 172 return this; 173 } 174 175 /** 176 * To use a custom thread pool (ScheduledExecutorService) by the throttler. 177 * 178 * @param executorServiceRef the reference id of the thread pool (must be 179 * scheduled) 180 * @return the builder 181 */ 182 @Override 183 public ThrottleDefinition executorServiceRef(String executorServiceRef) { 184 setExecutorServiceRef(executorServiceRef); 185 return this; 186 } 187 188 // Properties 189 // ------------------------------------------------------------------------- 190 191 /** 192 * Expression to configure the maximum number of messages to throttle per 193 * request 194 */ 195 @Override 196 public void setExpression(ExpressionDefinition expression) { 197 // override to include javadoc what the expression is used for 198 super.setExpression(expression); 199 } 200 201 public Long getTimePeriodMillis() { 202 return timePeriodMillis; 203 } 204 205 public void setTimePeriodMillis(Long timePeriodMillis) { 206 this.timePeriodMillis = timePeriodMillis; 207 } 208 209 public Boolean getAsyncDelayed() { 210 return asyncDelayed; 211 } 212 213 public void setAsyncDelayed(Boolean asyncDelayed) { 214 this.asyncDelayed = asyncDelayed; 215 } 216 217 public Boolean getCallerRunsWhenRejected() { 218 return callerRunsWhenRejected; 219 } 220 221 public void setCallerRunsWhenRejected(Boolean callerRunsWhenRejected) { 222 this.callerRunsWhenRejected = callerRunsWhenRejected; 223 } 224 225 @Override 226 public ExecutorService getExecutorService() { 227 return executorService; 228 } 229 230 @Override 231 public void setExecutorService(ExecutorService executorService) { 232 this.executorService = executorService; 233 } 234 235 @Override 236 public String getExecutorServiceRef() { 237 return executorServiceRef; 238 } 239 240 @Override 241 public void setExecutorServiceRef(String executorServiceRef) { 242 this.executorServiceRef = executorServiceRef; 243 } 244 245 public Boolean getRejectExecution() { 246 return rejectExecution; 247 } 248 249 public void setRejectExecution(Boolean rejectExecution) { 250 this.rejectExecution = rejectExecution; 251 } 252 253 /** 254 * The expression used to calculate the correlation key to use for throttle 255 * grouping. The Exchange which has the same correlation key is throttled 256 * together. 257 */ 258 public void setCorrelationExpression(ExpressionSubElementDefinition correlationExpression) { 259 this.correlationExpression = correlationExpression; 260 } 261 262 public ExpressionSubElementDefinition getCorrelationExpression() { 263 return correlationExpression; 264 } 265}