blob: fc34cc631fd5b83480b78d128fedbd7b7becc7c4 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.camel.model;
import java.util.concurrent.ExecutorService;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import org.apache.camel.Expression;
import org.apache.camel.builder.ExpressionBuilder;
import org.apache.camel.model.language.ExpressionDefinition;
import org.apache.camel.spi.Metadata;
/**
* Controls the rate at which messages are passed to the next node in the route
*/
@Metadata(label = "eip,routing")
@XmlRootElement(name = "throttle")
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(propOrder = {"expression", "correlationExpression"})
public class ThrottleDefinition extends ExpressionNode implements ExecutorServiceAwareDefinition<ThrottleDefinition> {
@XmlElement(name = "correlationExpression")
private ExpressionSubElementDefinition correlationExpression;
@XmlTransient
private ExecutorService executorService;
@XmlAttribute
private String executorServiceRef;
@XmlAttribute
@Metadata(defaultValue = "1000")
private Long timePeriodMillis;
@XmlAttribute
private Boolean asyncDelayed;
@XmlAttribute
@Metadata(defaultValue = "true")
private Boolean callerRunsWhenRejected;
@XmlAttribute
private Boolean rejectExecution;
public ThrottleDefinition() {
}
public ThrottleDefinition(Expression maximumRequestsPerPeriod) {
super(maximumRequestsPerPeriod);
}
public ThrottleDefinition(Expression maximumRequestsPerPeriod, Expression correlationExpression) {
this(ExpressionNodeHelper.toExpressionDefinition(maximumRequestsPerPeriod), correlationExpression);
}
private ThrottleDefinition(ExpressionDefinition maximumRequestsPerPeriod, Expression correlationExpression) {
super(maximumRequestsPerPeriod);
ExpressionSubElementDefinition cor = new ExpressionSubElementDefinition();
cor.setExpressionType(ExpressionNodeHelper.toExpressionDefinition(correlationExpression));
setCorrelationExpression(cor);
}
@Override
public String toString() {
return "Throttle[" + description() + "]";
}
protected String description() {
return getExpression() + " request per " + getTimePeriodMillis() + " millis";
}
@Override
public String getShortName() {
return "throttle";
}
@Override
public String getLabel() {
return "throttle[" + description() + "]";
}
// Fluent API
// -------------------------------------------------------------------------
/**
* Sets the time period during which the maximum request count is valid for
*
* @param timePeriodMillis period in millis
* @return the builder
*/
public ThrottleDefinition timePeriodMillis(long timePeriodMillis) {
setTimePeriodMillis(timePeriodMillis);
return this;
}
/**
* Sets the time period during which the maximum request count per period
*
* @param maximumRequestsPerPeriod the maximum request count number per time
* period
* @return the builder
*/
public ThrottleDefinition maximumRequestsPerPeriod(long maximumRequestsPerPeriod) {
setExpression(ExpressionNodeHelper.toExpressionDefinition(ExpressionBuilder.constantExpression(maximumRequestsPerPeriod)));
return this;
}
/**
* Whether or not the caller should run the task when it was rejected by the
* thread pool.
* <p/>
* Is by default <tt>true</tt>
*
* @param callerRunsWhenRejected whether or not the caller should run
* @return the builder
*/
public ThrottleDefinition callerRunsWhenRejected(boolean callerRunsWhenRejected) {
setCallerRunsWhenRejected(callerRunsWhenRejected);
return this;
}
/**
* Enables asynchronous delay which means the thread will <b>not</b> block
* while delaying.
*
* @return the builder
*/
public ThrottleDefinition asyncDelayed() {
setAsyncDelayed(true);
return this;
}
/**
* Whether or not throttler throws the ThrottlerRejectedExecutionException
* when the exchange exceeds the request limit
* <p/>
* Is by default <tt>false</tt>
*
* @param rejectExecution throw the RejectExecutionException if the exchange
* exceeds the request limit
* @return the builder
*/
public ThrottleDefinition rejectExecution(boolean rejectExecution) {
setRejectExecution(rejectExecution);
return this;
}
/**
* To use a custom thread pool (ScheduledExecutorService) by the throttler.
*
* @param executorService the custom thread pool (must be scheduled)
* @return the builder
*/
@Override
public ThrottleDefinition executorService(ExecutorService executorService) {
setExecutorService(executorService);
return this;
}
/**
* To use a custom thread pool (ScheduledExecutorService) by the throttler.
*
* @param executorServiceRef the reference id of the thread pool (must be
* scheduled)
* @return the builder
*/
@Override
public ThrottleDefinition executorServiceRef(String executorServiceRef) {
setExecutorServiceRef(executorServiceRef);
return this;
}
// Properties
// -------------------------------------------------------------------------
/**
* Expression to configure the maximum number of messages to throttle per
* request
*/
@Override
public void setExpression(ExpressionDefinition expression) {
// override to include javadoc what the expression is used for
super.setExpression(expression);
}
public Long getTimePeriodMillis() {
return timePeriodMillis;
}
public void setTimePeriodMillis(Long timePeriodMillis) {
this.timePeriodMillis = timePeriodMillis;
}
public Boolean getAsyncDelayed() {
return asyncDelayed;
}
public void setAsyncDelayed(Boolean asyncDelayed) {
this.asyncDelayed = asyncDelayed;
}
public Boolean getCallerRunsWhenRejected() {
return callerRunsWhenRejected;
}
public void setCallerRunsWhenRejected(Boolean callerRunsWhenRejected) {
this.callerRunsWhenRejected = callerRunsWhenRejected;
}
@Override
public ExecutorService getExecutorService() {
return executorService;
}
@Override
public void setExecutorService(ExecutorService executorService) {
this.executorService = executorService;
}
@Override
public String getExecutorServiceRef() {
return executorServiceRef;
}
@Override
public void setExecutorServiceRef(String executorServiceRef) {
this.executorServiceRef = executorServiceRef;
}
public Boolean getRejectExecution() {
return rejectExecution;
}
public void setRejectExecution(Boolean rejectExecution) {
this.rejectExecution = rejectExecution;
}
/**
* The expression used to calculate the correlation key to use for throttle
* grouping. The Exchange which has the same correlation key is throttled
* together.
*/
public void setCorrelationExpression(ExpressionSubElementDefinition correlationExpression) {
this.correlationExpression = correlationExpression;
}
public ExpressionSubElementDefinition getCorrelationExpression() {
return correlationExpression;
}
}