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