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