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.ForkJoinPool;
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 * Resilience4j Circuit Breaker EIP configuration
030 */
031@Metadata(label = "eip,routing,circuitbreaker")
032@XmlRootElement(name = "resilience4jConfiguration")
033@XmlAccessorType(XmlAccessType.FIELD)
034public class Resilience4jConfigurationDefinition extends Resilience4jConfigurationCommon {
035
036    @XmlTransient
037    private CircuitBreakerDefinition parent;
038
039    public Resilience4jConfigurationDefinition() {
040    }
041
042    public Resilience4jConfigurationDefinition(CircuitBreakerDefinition parent) {
043        this.parent = parent;
044    }
045
046    // Fluent API
047    // -------------------------------------------------------------------------
048
049    /**
050     * Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreaker instance
051     * to lookup and use from the registry. When using this, then any other circuit breaker options
052     * are not in use.
053     */
054    public Resilience4jConfigurationDefinition circuitBreakerRef(String circuitBreakerRef) {
055        setCircuitBreakerRef(circuitBreakerRef);
056        return this;
057    }
058
059
060    /**
061     * Refers to an existing io.github.resilience4j.circuitbreaker.CircuitBreakerConfig instance
062     * to lookup and use from the registry.
063     */
064    public Resilience4jConfigurationDefinition configRef(String ref) {
065        setConfigRef(ref);
066        return this;
067    }
068
069    /**
070     * Configures the failure rate threshold in percentage.
071     * If the failure rate is equal or greater than the threshold the CircuitBreaker transitions to open and starts short-circuiting calls.
072     * <p>
073     * The threshold must be greater than 0 and not greater than 100. Default value is 50 percentage.
074     */
075    public Resilience4jConfigurationDefinition failureRateThreshold(Float failureRateThreshold) {
076        setFailureRateThreshold(failureRateThreshold != null ? failureRateThreshold.toString() : null);
077        return this;
078    }
079
080    /**
081     * Configures the number of permitted calls when the CircuitBreaker is half open.
082     * <p>
083     * The size must be greater than 0. Default size is 10.
084     */
085    public Resilience4jConfigurationDefinition permittedNumberOfCallsInHalfOpenState(Integer permittedNumberOfCallsInHalfOpenState) {
086        setPermittedNumberOfCallsInHalfOpenState(permittedNumberOfCallsInHalfOpenState != null ? permittedNumberOfCallsInHalfOpenState.toString() : null);
087        return this;
088    }
089
090    /**
091     * Configures the size of the sliding window which is used to record the outcome of calls when the CircuitBreaker is closed.
092     * {@code slidingWindowSize} configures the size of the sliding window. Sliding window can either be count-based or time-based.
093     *
094     * If {@code slidingWindowType} is COUNT_BASED, the last {@code slidingWindowSize} calls are recorded and aggregated.
095     * If {@code slidingWindowType} is TIME_BASED, the calls of the last {@code slidingWindowSize} seconds are recorded and aggregated.
096     * <p>
097     * The {@code slidingWindowSize} must be greater than 0.
098     * The {@code minimumNumberOfCalls} must be greater than 0.
099     * If the slidingWindowType is COUNT_BASED, the {@code minimumNumberOfCalls} cannot be greater than {@code slidingWindowSize}.
100     * If the slidingWindowType is TIME_BASED, you can pick whatever you want.
101     *
102     * Default slidingWindowSize is 100.
103     */
104    public Resilience4jConfigurationDefinition slidingWindowSize(Integer slidingWindowSize) {
105        setSlidingWindowSize(slidingWindowSize != null ? slidingWindowSize.toString() : null);
106        return this;
107    }
108
109    /**
110     * Configures the type of the sliding window which is used to record the outcome of calls when the CircuitBreaker is closed.
111     * Sliding window can either be count-based or time-based.
112     *
113     * If {@code slidingWindowType} is COUNT_BASED, the last {@code slidingWindowSize} calls are recorded and aggregated.
114     * If {@code slidingWindowType} is TIME_BASED, the calls of the last {@code slidingWindowSize} seconds are recorded and aggregated.
115     *
116     * Default slidingWindowType is COUNT_BASED.
117     */
118    public Resilience4jConfigurationDefinition slidingWindowType(String slidingWindowType) {
119        setSlidingWindowType(slidingWindowType);
120        return this;
121    }
122
123    /**
124     * Configures configures the minimum number of calls which are required (per sliding window period) before the CircuitBreaker can calculate the error rate.
125     * For example, if {@code minimumNumberOfCalls} is 10, then at least 10 calls must be recorded, before the failure rate can be calculated.
126     * If only 9 calls have been recorded the CircuitBreaker will not transition to open even if all 9 calls have failed.
127     *
128     * Default minimumNumberOfCalls is 100
129     */
130    public Resilience4jConfigurationDefinition minimumNumberOfCalls(Integer minimumNumberOfCalls) {
131        setMinimumNumberOfCalls(minimumNumberOfCalls != null ? minimumNumberOfCalls.toString() : null);
132        return this;
133    }
134
135    /**
136     * Enables writable stack traces. When set to false, Exception.getStackTrace returns a zero length array.
137     * This may be used to reduce log spam when the circuit breaker is open as the cause of the exceptions is already known (the circuit breaker is short-circuiting calls).
138     */
139    public Resilience4jConfigurationDefinition writableStackTraceEnabled(Boolean writableStackTraceEnabled) {
140        setWritableStackTraceEnabled(writableStackTraceEnabled != null ? writableStackTraceEnabled.toString() : null);
141        return this;
142    }
143
144    /**
145     * Configures the wait duration (in seconds) which specifies how long the CircuitBreaker should stay open, before it switches to half open.
146     * Default value is 60 seconds.
147     */
148    public Resilience4jConfigurationDefinition waitDurationInOpenState(Integer waitDurationInOpenState) {
149        setWaitDurationInOpenState(waitDurationInOpenState != null ? waitDurationInOpenState.toString() : null);
150        return this;
151    }
152
153    /**
154     * Enables automatic transition from OPEN to HALF_OPEN state once the waitDurationInOpenState has passed.
155     */
156    public Resilience4jConfigurationDefinition automaticTransitionFromOpenToHalfOpenEnabled(Boolean automaticTransitionFromOpenToHalfOpenEnabled) {
157        setAutomaticTransitionFromOpenToHalfOpenEnabled(automaticTransitionFromOpenToHalfOpenEnabled != null ? automaticTransitionFromOpenToHalfOpenEnabled.toString() : null);
158        return this;
159    }
160
161    /**
162     * Configures a threshold in percentage. The CircuitBreaker considers a call as slow when the call duration is greater than slowCallDurationThreshold(Duration.
163     * When the percentage of slow calls is equal or greater the threshold, the CircuitBreaker transitions to open and starts short-circuiting calls.
164     * <p>
165     * The threshold must be greater than 0 and not greater than 100.
166     * Default value is 100 percentage which means that all recorded calls must be slower than slowCallDurationThreshold.
167     */
168    public Resilience4jConfigurationDefinition slowCallRateThreshold(Float slowCallRateThreshold) {
169        setSlowCallRateThreshold(slowCallRateThreshold != null ? slowCallRateThreshold.toString() : null);
170        return this;
171    }
172
173    /**
174     * Configures the duration threshold (seconds) above which calls are considered as slow and increase the slow calls percentage.
175     * Default value is 60 seconds.
176     */
177    public Resilience4jConfigurationDefinition slowCallDurationThreshold(Integer slowCallDurationThreshold) {
178        setSlowCallDurationThreshold(slowCallDurationThreshold != null ? slowCallDurationThreshold.toString() : null);
179        return this;
180    }
181
182    /**
183     * Whether bulkhead is enabled or not on the circuit breaker.
184     * Default is false.
185     */
186    public Resilience4jConfigurationDefinition bulkheadEnabled(Boolean bulkheadEnabled) {
187        setBulkheadEnabled(bulkheadEnabled != null ? bulkheadEnabled.toString() : null);
188        return this;
189    }
190
191    /**
192     * Configures the max amount of concurrent calls the bulkhead will support.
193     */
194    public Resilience4jConfigurationDefinition bulkheadMaxConcurrentCalls(Integer bulkheadMaxConcurrentCalls) {
195        setBulkheadMaxWaitDuration(bulkheadMaxConcurrentCalls != null ? bulkheadMaxConcurrentCalls.toString() : null);
196        return this;
197    }
198
199    /**
200     * Configures a maximum amount of time which the calling thread will wait to enter the bulkhead. If bulkhead has space available, entry
201     * is guaranteed and immediate. If bulkhead is full, calling threads will contest for space, if it becomes available. maxWaitDuration can be set to 0.
202     * <p>
203     * Note: for threads running on an event-loop or equivalent (rx computation pool, etc), setting maxWaitDuration to 0 is highly recommended. Blocking
204     * an event-loop thread will most likely have a negative effect on application throughput.
205     */
206    public Resilience4jConfigurationDefinition bulkheadMaxWaitDuration(Integer bulkheadMaxWaitDuration) {
207        setBulkheadMaxWaitDuration(bulkheadMaxWaitDuration != null ? bulkheadMaxWaitDuration.toString() : null);
208        return this;
209    }
210
211    /**
212     * Whether timeout is enabled or not on the circuit breaker.
213     * Default is false.
214     */
215    public Resilience4jConfigurationDefinition timeoutEnabled(Boolean timeoutEnabled) {
216        setTimeoutEnabled(timeoutEnabled != null ? timeoutEnabled.toString() : null);
217        return this;
218    }
219
220    /**
221     * References to a custom thread pool to use when timeout is enabled (uses {@link ForkJoinPool#commonPool()} by default)
222     */
223    public Resilience4jConfigurationDefinition timeoutExecutorServiceRef(String executorServiceRef) {
224        setTimeoutExecutorServiceRef(executorServiceRef);
225        return this;
226    }
227
228    /**
229     * Configures the thread execution timeout (millis).
230     * Default value is 1000 millis (1 second).
231     */
232    public Resilience4jConfigurationDefinition timeoutDuration(Integer timeoutDuration) {
233        setTimeoutDuration(timeoutDuration != null ? timeoutDuration.toString() : null);
234        return this;
235    }
236
237    /**
238     * Configures whether cancel is called on the running future.
239     * Defaults to true.
240     */
241    public Resilience4jConfigurationDefinition timeoutCancelRunningFuture(Boolean timeoutCancelRunningFuture) {
242        setTimeoutCancelRunningFuture(timeoutCancelRunningFuture != null ? timeoutCancelRunningFuture.toString() : null);
243        return this;
244    }
245
246    /**
247     * End of configuration.
248     */
249    public CircuitBreakerDefinition end() {
250        return parent;
251    }
252
253}