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.BlockingQueue; 020import java.util.concurrent.Future; 021import java.util.concurrent.ThreadPoolExecutor; 022import java.util.concurrent.TimeUnit; 023import javax.xml.bind.annotation.XmlAccessType; 024import javax.xml.bind.annotation.XmlAccessorType; 025import javax.xml.bind.annotation.XmlRootElement; 026import javax.xml.bind.annotation.XmlTransient; 027 028import org.apache.camel.spi.Metadata; 029 030/** 031 * Hystrix Circuit Breaker EIP configuration 032 */ 033@Metadata(label = "eip,routing,circuitbreaker") 034@XmlRootElement(name = "hystrixConfiguration") 035@XmlAccessorType(XmlAccessType.FIELD) 036public class HystrixConfigurationDefinition extends HystrixConfigurationCommon { 037 038 public static final String DEFAULT_GROUP_KEY = "CamelHystrix"; 039 040 @XmlTransient 041 private HystrixDefinition parent; 042 043 public HystrixConfigurationDefinition() { 044 } 045 046 public HystrixConfigurationDefinition(HystrixDefinition parent) { 047 this.parent = parent; 048 } 049 050 // Fluent API 051 // ------------------------------------------------------------------------- 052 053 /** 054 * Sets the group key to use. The default value is CamelHystrix. 055 */ 056 public HystrixConfigurationDefinition groupKey(String groupKey) { 057 setGroupKey(groupKey); 058 return this; 059 } 060 061 /** 062 * Sets the thread pool key to use. Will by default use the same value as groupKey has been configured to use. 063 */ 064 public HystrixConfigurationDefinition threadPoolKey(String threadPoolKey) { 065 setThreadPoolKey(threadPoolKey); 066 return this; 067 } 068 069 /** 070 * Whether to use a HystrixCircuitBreaker or not. If false no circuit-breaker logic will be used and all requests permitted. 071 * <p> 072 * This is similar in effect to circuitBreakerForceClosed() except that continues tracking metrics and knowing whether it 073 * should be open/closed, this property results in not even instantiating a circuit-breaker. 074 */ 075 public HystrixConfigurationDefinition circuitBreakerEnabled(Boolean circuitBreakerEnabled) { 076 setCircuitBreakerEnabled(circuitBreakerEnabled); 077 return this; 078 } 079 080 /** 081 * Error percentage threshold (as whole number such as 50) at which point the circuit breaker will trip open and reject requests. 082 * <p> 083 * It will stay tripped for the duration defined in circuitBreakerSleepWindowInMilliseconds; 084 * <p> 085 * The error percentage this is compared against comes from HystrixCommandMetrics.getHealthCounts(). 086 */ 087 public HystrixConfigurationDefinition circuitBreakerErrorThresholdPercentage(Integer circuitBreakerErrorThresholdPercentage) { 088 setCircuitBreakerErrorThresholdPercentage(circuitBreakerErrorThresholdPercentage); 089 return this; 090 } 091 092 /** 093 * If true the HystrixCircuitBreaker#allowRequest() will always return true to allow requests regardless of 094 * the error percentage from HystrixCommandMetrics.getHealthCounts(). 095 * <p> 096 * The circuitBreakerForceOpen() property takes precedence so if it set to true this property does nothing. 097 */ 098 public HystrixConfigurationDefinition circuitBreakerForceClosed(Boolean circuitBreakerForceClosed) { 099 setCircuitBreakerForceClosed(circuitBreakerForceClosed); 100 return this; 101 } 102 103 /** 104 * If true the HystrixCircuitBreaker.allowRequest() will always return false, causing the circuit to be open (tripped) and reject all requests. 105 * <p> 106 * This property takes precedence over circuitBreakerForceClosed(); 107 */ 108 public HystrixConfigurationDefinition circuitBreakerForceOpen(Boolean circuitBreakerForceOpen) { 109 setCircuitBreakerForceOpen(circuitBreakerForceOpen); 110 return this; 111 } 112 113 /** 114 * Minimum number of requests in the metricsRollingStatisticalWindowInMilliseconds() that must exist before the HystrixCircuitBreaker will trip. 115 * <p> 116 * If below this number the circuit will not trip regardless of error percentage. 117 */ 118 public HystrixConfigurationDefinition circuitBreakerRequestVolumeThreshold(Integer circuitBreakerRequestVolumeThreshold) { 119 setCircuitBreakerRequestVolumeThreshold(circuitBreakerRequestVolumeThreshold); 120 return this; 121 } 122 123 /** 124 * The time in milliseconds after a HystrixCircuitBreaker trips open that it should wait before trying requests again. 125 */ 126 public HystrixConfigurationDefinition circuitBreakerSleepWindowInMilliseconds(Integer circuitBreakerSleepWindowInMilliseconds) { 127 setCircuitBreakerSleepWindowInMilliseconds(circuitBreakerSleepWindowInMilliseconds); 128 return this; 129 } 130 131 /** 132 * Number of concurrent requests permitted to HystrixCommand.run(). Requests beyond the concurrent limit will be rejected. 133 * <p> 134 * Applicable only when executionIsolationStrategy == SEMAPHORE. 135 */ 136 public HystrixConfigurationDefinition executionIsolationSemaphoreMaxConcurrentRequests(Integer executionIsolationSemaphoreMaxConcurrentRequests) { 137 setExecutionIsolationSemaphoreMaxConcurrentRequests(executionIsolationSemaphoreMaxConcurrentRequests); 138 return this; 139 } 140 141 /** 142 * What isolation strategy HystrixCommand.run() will be executed with. 143 * <p> 144 * If THREAD then it will be executed on a separate thread and concurrent requests limited by the number of threads in the thread-pool. 145 * <p> 146 * If SEMAPHORE then it will be executed on the calling thread and concurrent requests limited by the semaphore count. 147 */ 148 public HystrixConfigurationDefinition executionIsolationStrategy(String executionIsolationStrategy) { 149 setExecutionIsolationStrategy(executionIsolationStrategy); 150 return this; 151 } 152 153 /** 154 * Whether the execution thread should attempt an interrupt (using {@link Future#cancel}) when a thread times out. 155 * <p> 156 * Applicable only when executionIsolationStrategy() == THREAD. 157 */ 158 public HystrixConfigurationDefinition executionIsolationThreadInterruptOnTimeout(Boolean executionIsolationThreadInterruptOnTimeout) { 159 setExecutionIsolationThreadInterruptOnTimeout(executionIsolationThreadInterruptOnTimeout); 160 return this; 161 } 162 163 /** 164 * Time in milliseconds at which point the command will timeout and halt execution. 165 * <p> 166 * If {@link #executionIsolationThreadInterruptOnTimeout} == true and the command is thread-isolated, the executing thread will be interrupted. 167 * If the command is semaphore-isolated and a HystrixObservableCommand, that command will get unsubscribed. 168 */ 169 public HystrixConfigurationDefinition executionTimeoutInMilliseconds(Integer executionTimeoutInMilliseconds) { 170 setExecutionTimeoutInMilliseconds(executionTimeoutInMilliseconds); 171 return this; 172 } 173 174 /** 175 * Whether the timeout mechanism is enabled for this command 176 */ 177 public HystrixConfigurationDefinition executionTimeoutEnabled(Boolean executionTimeoutEnabled) { 178 setExecutionTimeoutEnabled(executionTimeoutEnabled); 179 return this; 180 } 181 182 /** 183 * Number of concurrent requests permitted to HystrixCommand.getFallback(). 184 * Requests beyond the concurrent limit will fail-fast and not attempt retrieving a fallback. 185 */ 186 public HystrixConfigurationDefinition fallbackIsolationSemaphoreMaxConcurrentRequests(Integer fallbackIsolationSemaphoreMaxConcurrentRequests) { 187 setFallbackIsolationSemaphoreMaxConcurrentRequests(fallbackIsolationSemaphoreMaxConcurrentRequests); 188 return this; 189 } 190 191 /** 192 * Whether HystrixCommand.getFallback() should be attempted when failure occurs. 193 */ 194 public HystrixConfigurationDefinition fallbackEnabled(Boolean fallbackEnabled) { 195 setFallbackEnabled(fallbackEnabled); 196 return this; 197 } 198 199 /** 200 * Time in milliseconds to wait between allowing health snapshots to be taken that calculate success and error 201 * percentages and affect HystrixCircuitBreaker.isOpen() status. 202 * <p> 203 * On high-volume circuits the continual calculation of error percentage can become CPU intensive thus this controls how often it is calculated. 204 */ 205 public HystrixConfigurationDefinition metricsHealthSnapshotIntervalInMilliseconds(Integer metricsHealthSnapshotIntervalInMilliseconds) { 206 setMetricsHealthSnapshotIntervalInMilliseconds(metricsHealthSnapshotIntervalInMilliseconds); 207 return this; 208 } 209 210 /** 211 * Maximum number of values stored in each bucket of the rolling percentile. 212 * This is passed into HystrixRollingPercentile inside HystrixCommandMetrics. 213 */ 214 public HystrixConfigurationDefinition metricsRollingPercentileBucketSize(Integer metricsRollingPercentileBucketSize) { 215 setMetricsRollingPercentileBucketSize(metricsRollingPercentileBucketSize); 216 return this; 217 } 218 219 /** 220 * Whether percentile metrics should be captured using HystrixRollingPercentile inside HystrixCommandMetrics. 221 */ 222 public HystrixConfigurationDefinition metricsRollingPercentileEnabled(Boolean metricsRollingPercentileEnabled) { 223 setMetricsRollingPercentileEnabled(metricsRollingPercentileEnabled); 224 return this; 225 } 226 227 /** 228 * Duration of percentile rolling window in milliseconds. 229 * This is passed into HystrixRollingPercentile inside HystrixCommandMetrics. 230 */ 231 public HystrixConfigurationDefinition metricsRollingPercentileWindowInMilliseconds(Integer metricsRollingPercentileWindowInMilliseconds) { 232 setMetricsRollingPercentileWindowInMilliseconds(metricsRollingPercentileWindowInMilliseconds); 233 return this; 234 } 235 236 /** 237 * Number of buckets the rolling percentile window is broken into. 238 * This is passed into HystrixRollingPercentile inside HystrixCommandMetrics. 239 */ 240 public HystrixConfigurationDefinition metricsRollingPercentileWindowBuckets(Integer metricsRollingPercentileWindowBuckets) { 241 setMetricsRollingPercentileWindowBuckets(metricsRollingPercentileWindowBuckets); 242 return this; 243 } 244 245 /** 246 * This property sets the duration of the statistical rolling window, in milliseconds. This is how long metrics are kept for the thread pool. 247 * 248 * The window is divided into buckets and “rolls” by those increments. 249 */ 250 public HystrixConfigurationDefinition metricsRollingStatisticalWindowInMilliseconds(Integer metricsRollingStatisticalWindowInMilliseconds) { 251 setMetricsRollingStatisticalWindowInMilliseconds(metricsRollingStatisticalWindowInMilliseconds); 252 return this; 253 } 254 255 /** 256 * Number of buckets the rolling statistical window is broken into. 257 * This is passed into HystrixRollingNumber inside HystrixCommandMetrics. 258 */ 259 public HystrixConfigurationDefinition metricsRollingStatisticalWindowBuckets(Integer metricsRollingStatisticalWindowBuckets) { 260 setMetricsRollingStatisticalWindowBuckets(metricsRollingStatisticalWindowBuckets); 261 return this; 262 } 263 264 /** 265 * Whether HystrixCommand execution and events should be logged to HystrixRequestLog. 266 */ 267 public HystrixConfigurationDefinition requestLogEnabled(Boolean requestLogEnabled) { 268 setRequestLogEnabled(requestLogEnabled); 269 return this; 270 } 271 272 /** 273 * Core thread-pool size that gets passed to {@link java.util.concurrent.ThreadPoolExecutor#setCorePoolSize(int)} 274 */ 275 public HystrixConfigurationDefinition corePoolSize(Integer corePoolSize) { 276 setCorePoolSize(corePoolSize); 277 return this; 278 } 279 280 /** 281 * Keep-alive time in minutes that gets passed to {@link ThreadPoolExecutor#setKeepAliveTime(long, TimeUnit)} 282 */ 283 public HystrixConfigurationDefinition keepAliveTime(Integer keepAliveTime) { 284 setKeepAliveTime(keepAliveTime); 285 return this; 286 } 287 288 /** 289 * Max queue size that gets passed to {@link BlockingQueue} in HystrixConcurrencyStrategy.getBlockingQueue(int) 290 * 291 * This should only affect the instantiation of a threadpool - it is not eliglible to change a queue size on the fly. 292 * For that, use queueSizeRejectionThreshold(). 293 */ 294 public HystrixConfigurationDefinition maxQueueSize(Integer maxQueueSize) { 295 setMaxQueueSize(maxQueueSize); 296 return this; 297 } 298 299 /** 300 * Maximum thread-pool size that gets passed to {@link ThreadPoolExecutor#setMaximumPoolSize(int)}. 301 * This is the maximum amount of concurrency that can be supported without starting to reject HystrixCommands. 302 * Please note that this setting only takes effect if you also set allowMaximumSizeToDivergeFromCoreSize 303 */ 304 public HystrixConfigurationDefinition maximumSize(Integer maximumSize) { 305 setMaximumSize(maximumSize); 306 return this; 307 } 308 309 /** 310 * Queue size rejection threshold is an artificial "max" size at which rejections will occur even 311 * if {@link #maxQueueSize} has not been reached. This is done because the {@link #maxQueueSize} 312 * of a {@link BlockingQueue} can not be dynamically changed and we want to support dynamically 313 * changing the queue size that affects rejections. 314 * <p> 315 * This is used by HystrixCommand when queuing a thread for execution. 316 */ 317 public HystrixConfigurationDefinition queueSizeRejectionThreshold(Integer queueSizeRejectionThreshold) { 318 setQueueSizeRejectionThreshold(queueSizeRejectionThreshold); 319 return this; 320 } 321 322 /** 323 * Duration of statistical rolling window in milliseconds. 324 * This is passed into HystrixRollingNumber inside each HystrixThreadPoolMetrics instance. 325 */ 326 public HystrixConfigurationDefinition threadPoolRollingNumberStatisticalWindowInMilliseconds(Integer threadPoolRollingNumberStatisticalWindowInMilliseconds) { 327 setThreadPoolRollingNumberStatisticalWindowInMilliseconds(threadPoolRollingNumberStatisticalWindowInMilliseconds); 328 return this; 329 } 330 331 /** 332 * Number of buckets the rolling statistical window is broken into. 333 * This is passed into HystrixRollingNumber inside each HystrixThreadPoolMetrics instance. 334 */ 335 public HystrixConfigurationDefinition threadPoolRollingNumberStatisticalWindowBuckets(Integer threadPoolRollingNumberStatisticalWindowBuckets) { 336 setThreadPoolRollingNumberStatisticalWindowBuckets(threadPoolRollingNumberStatisticalWindowBuckets); 337 return this; 338 } 339 340 /** 341 * Allows the configuration for maximumSize to take effect. That value can then be equal to, or higher, than coreSize 342 */ 343 public HystrixConfigurationDefinition allowMaximumSizeToDivergeFromCoreSize(Boolean allowMaximumSizeToDivergeFromCoreSize) { 344 setAllowMaximumSizeToDivergeFromCoreSize(allowMaximumSizeToDivergeFromCoreSize); 345 return this; 346 } 347 348 /** 349 * End of configuration 350 */ 351 public HystrixDefinition end() { 352 return parent; 353 } 354 355}