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