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; 020import java.util.concurrent.ScheduledExecutorService; 021import javax.xml.bind.annotation.XmlAccessType; 022import javax.xml.bind.annotation.XmlAccessorType; 023import javax.xml.bind.annotation.XmlAttribute; 024import javax.xml.bind.annotation.XmlRootElement; 025import javax.xml.bind.annotation.XmlTransient; 026 027import org.apache.camel.Expression; 028import org.apache.camel.Processor; 029import org.apache.camel.builder.ExpressionBuilder; 030import org.apache.camel.model.language.ExpressionDefinition; 031import org.apache.camel.processor.Delayer; 032import org.apache.camel.spi.Metadata; 033import org.apache.camel.spi.RouteContext; 034 035/** 036 * Delays processing for a specified length of time 037 * 038 * @version 039 */ 040@Metadata(label = "eip,routing") 041@XmlRootElement(name = "delay") 042@XmlAccessorType(XmlAccessType.FIELD) 043public class DelayDefinition extends ExpressionNode implements ExecutorServiceAwareDefinition<DelayDefinition> { 044 045 // TODO: Camel 3.0 Should extend NoOutputExpressionNode 046 047 @XmlTransient 048 private ExecutorService executorService; 049 @XmlAttribute 050 private String executorServiceRef; 051 @XmlAttribute @Metadata(defaultValue = "false") 052 private Boolean asyncDelayed; 053 @XmlAttribute @Metadata(defaultValue = "true") 054 private Boolean callerRunsWhenRejected; 055 056 public DelayDefinition() { 057 } 058 059 public DelayDefinition(Expression delay) { 060 super(delay); 061 } 062 063 @Override 064 public String getLabel() { 065 return "delay[" + getExpression() + "]"; 066 } 067 068 @Override 069 public String toString() { 070 return "Delay[" + getExpression() + " -> " + getOutputs() + "]"; 071 } 072 073 @Override 074 public Processor createProcessor(RouteContext routeContext) throws Exception { 075 Processor childProcessor = this.createChildProcessor(routeContext, false); 076 Expression delay = createAbsoluteTimeDelayExpression(routeContext); 077 078 boolean async = getAsyncDelayed() != null && getAsyncDelayed(); 079 boolean shutdownThreadPool = ProcessorDefinitionHelper.willCreateNewThreadPool(routeContext, this, async); 080 ScheduledExecutorService threadPool = ProcessorDefinitionHelper.getConfiguredScheduledExecutorService(routeContext, "Delay", this, async); 081 082 Delayer answer = new Delayer(routeContext.getCamelContext(), childProcessor, delay, threadPool, shutdownThreadPool); 083 if (getAsyncDelayed() != null) { 084 answer.setAsyncDelayed(getAsyncDelayed()); 085 } 086 if (getCallerRunsWhenRejected() == null) { 087 // should be default true 088 answer.setCallerRunsWhenRejected(true); 089 } else { 090 answer.setCallerRunsWhenRejected(getCallerRunsWhenRejected()); 091 } 092 return answer; 093 } 094 095 private Expression createAbsoluteTimeDelayExpression(RouteContext routeContext) { 096 ExpressionDefinition expr = getExpression(); 097 if (expr != null) { 098 return expr.createExpression(routeContext); 099 } 100 return null; 101 } 102 103 // Fluent API 104 // ------------------------------------------------------------------------- 105 106 /** 107 * Sets the delay time in millis to delay 108 * 109 * @param delay delay time in millis 110 * @return the builder 111 */ 112 public DelayDefinition delayTime(Long delay) { 113 setExpression(ExpressionNodeHelper.toExpressionDefinition(ExpressionBuilder.constantExpression(delay))); 114 return this; 115 } 116 117 /** 118 * Whether or not the caller should run the task when it was rejected by the thread pool. 119 * <p/> 120 * Is by default <tt>true</tt> 121 * 122 * @param callerRunsWhenRejected whether or not the caller should run 123 * @return the builder 124 */ 125 public DelayDefinition callerRunsWhenRejected(boolean callerRunsWhenRejected) { 126 setCallerRunsWhenRejected(callerRunsWhenRejected); 127 return this; 128 } 129 130 /** 131 * Enables asynchronous delay which means the thread will <b>noy</b> block while delaying. 132 */ 133 public DelayDefinition asyncDelayed() { 134 setAsyncDelayed(true); 135 return this; 136 } 137 138 /** 139 * To use a custom Thread Pool if asyncDelay has been enabled. 140 */ 141 public DelayDefinition executorService(ExecutorService executorService) { 142 setExecutorService(executorService); 143 return this; 144 } 145 146 /** 147 * Refers to a custom Thread Pool if asyncDelay has been enabled. 148 */ 149 public DelayDefinition executorServiceRef(String executorServiceRef) { 150 setExecutorServiceRef(executorServiceRef); 151 return this; 152 } 153 154 // Properties 155 // ------------------------------------------------------------------------- 156 157 /** 158 * Expression to define how long time to wait (in millis) 159 */ 160 @Override 161 public void setExpression(ExpressionDefinition expression) { 162 // override to include javadoc what the expression is used for 163 super.setExpression(expression); 164 } 165 166 public Boolean getAsyncDelayed() { 167 return asyncDelayed; 168 } 169 170 public void setAsyncDelayed(Boolean asyncDelayed) { 171 this.asyncDelayed = asyncDelayed; 172 } 173 174 public Boolean getCallerRunsWhenRejected() { 175 return callerRunsWhenRejected; 176 } 177 178 public void setCallerRunsWhenRejected(Boolean callerRunsWhenRejected) { 179 this.callerRunsWhenRejected = callerRunsWhenRejected; 180 } 181 182 public ExecutorService getExecutorService() { 183 return executorService; 184 } 185 186 public void setExecutorService(ExecutorService executorService) { 187 this.executorService = executorService; 188 } 189 190 public String getExecutorServiceRef() { 191 return executorServiceRef; 192 } 193 194 public void setExecutorServiceRef(String executorServiceRef) { 195 this.executorServiceRef = executorServiceRef; 196 } 197}