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