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