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}