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