This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch CAMEL-13691
in repository https://gitbox.apache.org/repos/asf/camel.git

commit f42465fd9dcadf6fd8d80648cfb9dfb9d35fc065
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sat Nov 16 12:45:54 2019 +0100

    CAMEL-13691: camel-resilience4j - WIP
---
 .../resilience4j/ResilienceProcessor.java          |   4 +
 .../src/main/docs/eips/hystrix-eip.adoc            |  14 +-
 .../{hystrix-eip.adoc => resilience4j-eip.adoc}    |  52 +++--
 .../docs/eips/resilience4jConfiguration-eip.adoc   |   6 +
 .../camel/model/CircuitBreakerDefinition.java      |  39 +++-
 .../model/Resilience4jConfigurationCommon.java     | 218 +++++++++++++++++++++
 .../model/Resilience4jConfigurationDefinition.java | 177 +++++++++++++++++
 7 files changed, 469 insertions(+), 41 deletions(-)

diff --git 
a/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceProcessor.java
 
b/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceProcessor.java
index 17be13f..1a6dbef 100644
--- 
a/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceProcessor.java
+++ 
b/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceProcessor.java
@@ -16,12 +16,16 @@
  */
 package org.apache.camel.component.resilience4j;
 
+import java.time.Duration;
 import java.util.ArrayList;
 import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CompletableFuture;
 import java.util.function.Function;
 import java.util.function.Supplier;
 
 import io.github.resilience4j.circuitbreaker.CircuitBreaker;
+import io.github.resilience4j.timelimiter.TimeLimiter;
 import io.vavr.control.Try;
 import org.apache.camel.AsyncCallback;
 import org.apache.camel.Exchange;
diff --git a/core/camel-core-engine/src/main/docs/eips/hystrix-eip.adoc 
b/core/camel-core-engine/src/main/docs/eips/hystrix-eip.adoc
index 3fa4d1b..b2d3a16 100644
--- a/core/camel-core-engine/src/main/docs/eips/hystrix-eip.adoc
+++ b/core/camel-core-engine/src/main/docs/eips/hystrix-eip.adoc
@@ -113,11 +113,11 @@ You can find an example with the source code: 
https://github.com/apache/camel/tr
 
 See the xref:hystrix-component.adoc[Hystrix Component].
 
-== Camel's Error Handler and Hystrix EIP
+== Camel's Error Handler and Circuit Breaker EIP
 
-By default the Hystrix EIP handles errors by itself. This means if the circuit 
breaker is open and
+By default the Circuit Breaker EIP handles errors by itself. This means if the 
circuit breaker is open and
 the message fails, then Camel's error handler is not reacting also.
-However, you can enable Camels error handler with Hystrix by enabling the 
`inheritErrorHandler` option, as shown:
+However, you can enable Camels error handler with circuit breaker by enabling 
the `inheritErrorHandler` option, as shown:
 
 [source,java]
 ----
@@ -126,7 +126,7 @@ 
errorHandler(deadLetterChannel("mock:dead").maximumRedeliveries(3).redeliveryDel
 
 from("direct:start")
     .to("log:start")
-    // turn on Camel's error handler on hystrix so it can do redeliveries
+    // turn on Camel's error handler on circuit breaker so Camel can do 
redeliveries
     .circuitBreaker().inheritErrorHandler(true)
         .to("mock:a")
         .throwException(new IllegalArgumentException("Forced"))
@@ -135,13 +135,13 @@ from("direct:start")
     .to("mock:result");
 ----
 
-This example is from an unit test, where you can see the Hystrix EIP block has 
been hardcoded
+This example is from an unit test, where you can see the Circuit Breaker EIP 
block has been hardcoded
 to always fail by throwing an exception. Because the `inheritErrorHandler` has 
been enabled,
-then Camel's error handler will attempt to call the Hystrix EIP block again.
+then Camel's error handler will attempt to call the Circuit Breaker EIP block 
again.
 
 That means the `mock:a` endpoint will receive the message again, and a total 
of 1 + 3 = 4 message
 (first time + 3 redeliveries).
 
-If we turn off the `inheritErrorHandler` option (default) then the Hystrix EIP 
will only be
+If we turn off the `inheritErrorHandler` option (default) then the Circuit 
Breaker EIP will only be
 executed once because it handled the error itself.
 
diff --git a/core/camel-core-engine/src/main/docs/eips/hystrix-eip.adoc 
b/core/camel-core-engine/src/main/docs/eips/resilience4j-eip.adoc
similarity index 57%
copy from core/camel-core-engine/src/main/docs/eips/hystrix-eip.adoc
copy to core/camel-core-engine/src/main/docs/eips/resilience4j-eip.adoc
index 3fa4d1b..1137147 100644
--- a/core/camel-core-engine/src/main/docs/eips/hystrix-eip.adoc
+++ b/core/camel-core-engine/src/main/docs/eips/resilience4j-eip.adoc
@@ -1,12 +1,12 @@
-[[hystrix-eip]]
-= Hystrix EIP
+[[resilience4j-eip]]
+= Resilience4j EIP
 
-*Available as of Camel 2.18*
+*Available as of Camel 3.0*
 
-The Hystrix EIP provides integration with Netflix 
https://github.com/Netflix/Hystrix[Hystrix] to be used as circuit breaker in 
the Camel routes. Hystrix is a latency and fault tolerance library designed to 
isolate points of access to remote systems, services and 3rd party libraries, 
stop cascading failure and enable resilience in complex distributed systems 
where failure is inevitable.
+This component supports the Circuit Breaker EIP with the Resilience4j library.
 
 NOTE: Camel provides the Circuit Breaker EIP in the route model, which allows 
to plugin different implementations.
-Hystrix is one such implementation.
+Resilience4j is one such implementation.
 
 Maven users will need to add the following dependency to their pom.xml to use 
this EIP:
 
@@ -14,7 +14,7 @@ Maven users will need to add the following dependency to 
their pom.xml to use th
 ----
 <dependency>
     <groupId>org.apache.camel</groupId>
-    <artifactId>camel-hystrix</artifactId>
+    <artifactId>camel-resilience4j</artifactId>
     <version>x.x.x</version><!-- use the same version as your Camel core 
version -->
 </dependency>
 ----
@@ -22,26 +22,18 @@ Maven users will need to add the following dependency to 
their pom.xml to use th
 == Configuration options
 
 // eip options: START
-The Hystrix EIP supports 2 options which are listed below:
-
-[width="100%",cols="2,5,^1,2",options="header"]
-|===
-| Name | Description | Default | Type
-| *hystrixConfiguration* | Configures the Hystrix EIP Use end when 
configuration is complete, to return back to the Hystrix EIP. |  | 
HystrixConfiguration Definition
-| *hystrixConfigurationRef* | Refers to a Hystrix configuration to use for 
configuring the Hystrix EIP. |  | String
-|===
 // eip options: END
 
-See xref:hystrixConfiguration-eip.adoc[Hystrix Configuration] for all the 
configuration options on Hystrix EIP.
+See xref:resilience4jConfiguration-eip.adoc[Resilience4j Configuration] for 
all the configuration options on Resilience Circuit Breaker.
 
 == Samples
 
-Below is an example route showing an Hystrix endpoint that protects against 
slow operation by falling back to the in-lined fallback route. By default the 
timeout request is just *1000ms* so the HTTP endpoint has to be fairly quick to 
succeed.
+Below is an example route showing a Resilience endpoint that protects against 
a downstream HTTP operation by falling back to the in-lined fallback route.
 [source,java]
 ----
 from("direct:start")
     .circuitBreaker()
-        .to("http://fooservice.com/slow";)
+        .to("http://fooservice.com/faulty";)
     .onFallback()
         .transform().constant("Fallback message")
     .end()
@@ -55,7 +47,7 @@ And in XML DSL:
   <route>
     <from uri="direct:start"/>
     <circuitBreaker>
-      <to uri="http://fooservice.com/slow"/>
+      <to uri="http://fooservice.com/faulty"/>
       <onFallback>
         <transform>
           <constant>Fallback message</constant>
@@ -67,9 +59,11 @@ And in XML DSL:
 </camelContext>
 ----
 
-== Configuring Hystrix
+== Configuring Resilienc4j
 
-You can fine-tune Hystrix by the many 
xref:hystrixConfiguration-eip.adoc[Hystrix Configuration] options.
+You can fine-tune Resilience4j by the many 
xref:resilience4jConfiguration-eip.adoc[Resilience4j Configuration] options.
+
+TODO: Update example!!!
 For example to use a 2 second execution timeout, you can do as follows:
 
 [source,java]
@@ -109,15 +103,15 @@ See xref:onFallback-eip.adoc[onFallback].
 
 You can find an example with the source code: 
https://github.com/apache/camel/tree/master/examples/camel-example-hystrix[camel-example-hystrix].
 
-== Using Hystrix with Spring Boot
+== Using Resilience4j with Spring Boot
 
-See the xref:hystrix-component.adoc[Hystrix Component].
+See the xref:components::resilience4j-component.adoc[Resilience4j Component].
 
-== Camel's Error Handler and Hystrix EIP
+== Camel's Error Handler and Circuit Breaker EIP
 
-By default the Hystrix EIP handles errors by itself. This means if the circuit 
breaker is open and
+By default the Circuit Breaker EIP handles errors by itself. This means if the 
circuit breaker is open and
 the message fails, then Camel's error handler is not reacting also.
-However, you can enable Camels error handler with Hystrix by enabling the 
`inheritErrorHandler` option, as shown:
+However, you can enable Camels error handler with circuit breaker by enabling 
the `inheritErrorHandler` option, as shown:
 
 [source,java]
 ----
@@ -126,7 +120,7 @@ 
errorHandler(deadLetterChannel("mock:dead").maximumRedeliveries(3).redeliveryDel
 
 from("direct:start")
     .to("log:start")
-    // turn on Camel's error handler on hystrix so it can do redeliveries
+    // turn on Camel's error handler on circuit breaker so Camel can do 
redeliveries
     .circuitBreaker().inheritErrorHandler(true)
         .to("mock:a")
         .throwException(new IllegalArgumentException("Forced"))
@@ -135,13 +129,13 @@ from("direct:start")
     .to("mock:result");
 ----
 
-This example is from an unit test, where you can see the Hystrix EIP block has 
been hardcoded
+This example is from an unit test, where you can see the Circuit Breaker EIP 
block has been hardcoded
 to always fail by throwing an exception. Because the `inheritErrorHandler` has 
been enabled,
-then Camel's error handler will attempt to call the Hystrix EIP block again.
+then Camel's error handler will attempt to call the Circuit Breaker EIP block 
again.
 
 That means the `mock:a` endpoint will receive the message again, and a total 
of 1 + 3 = 4 message
 (first time + 3 redeliveries).
 
-If we turn off the `inheritErrorHandler` option (default) then the Hystrix EIP 
will only be
+If we turn off the `inheritErrorHandler` option (default) then the Circuit 
Breaker EIP will only be
 executed once because it handled the error itself.
 
diff --git 
a/core/camel-core-engine/src/main/docs/eips/resilience4jConfiguration-eip.adoc 
b/core/camel-core-engine/src/main/docs/eips/resilience4jConfiguration-eip.adoc
new file mode 100644
index 0000000..77f40f9
--- /dev/null
+++ 
b/core/camel-core-engine/src/main/docs/eips/resilience4jConfiguration-eip.adoc
@@ -0,0 +1,6 @@
+[[resilience4jConfiguration-eip]]
+= Resilience4j Configuration EIP
+
+
+// eip options: START
+// eip options: END
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/model/CircuitBreakerDefinition.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/model/CircuitBreakerDefinition.java
index c16e1b0..7a0769e 100644
--- 
a/core/camel-core-engine/src/main/java/org/apache/camel/model/CircuitBreakerDefinition.java
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/model/CircuitBreakerDefinition.java
@@ -1,13 +1,13 @@
-/**
+/*
  * Licensed to the Apache Software Foundation (ASF) under one or more
  * contributor license agreements.  See the NOTICE file distributed with
  * this work for additional information regarding copyright ownership.
  * The ASF licenses this file to You under the Apache License, Version 2.0
  * (the "License"); you may not use this file except in compliance with
  * the License.  You may obtain a copy of the License at
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -36,6 +36,8 @@ public class CircuitBreakerDefinition extends 
ProcessorDefinition<CircuitBreaker
 
     @XmlElement
     private HystrixConfigurationDefinition hystrixConfiguration;
+    @XmlElement
+    private Resilience4jConfigurationDefinition resilience4jConfiguration;
     @XmlAttribute
     private String configurationRef;
     @XmlElementRef
@@ -122,12 +124,20 @@ public class CircuitBreakerDefinition extends 
ProcessorDefinition<CircuitBreaker
         this.hystrixConfiguration = hystrixConfiguration;
     }
 
+    public Resilience4jConfigurationCommon getResilience4jConfiguration() {
+        return resilience4jConfiguration;
+    }
+
+    public void 
setResilience4jConfiguration(Resilience4jConfigurationDefinition 
resilience4jConfiguration) {
+        this.resilience4jConfiguration = resilience4jConfiguration;
+    }
+
     public String getConfigurationRef() {
         return configurationRef;
     }
 
     /**
-     * Refers to a circuit breaker configuration (such as hystrix, 
resillient4j, or microprofile-fault-tolerance)
+     * Refers to a circuit breaker configuration (such as hystrix, 
resillience4j, or microprofile-fault-tolerance)
      * to use for configuring the circuit breaker EIP.
      */
     public void setConfigurationRef(String configurationRef) {
@@ -165,6 +175,25 @@ public class CircuitBreakerDefinition extends 
ProcessorDefinition<CircuitBreaker
     }
 
     /**
+     * Configures the circuit breaker to use Resilience4j.
+     * <p/>
+     * Use <tt>end</tt> when configuration is complete, to return back to the
+     * Circuit Breaker EIP.
+     */
+    public Resilience4jConfigurationDefinition resilience4jConfiguration() {
+        resilience4jConfiguration = resilience4jConfiguration == null ? new 
Resilience4jConfigurationDefinition(this) : resilience4jConfiguration;
+        return resilience4jConfiguration;
+    }
+
+    /**
+     * Configures the circuit breaker to use Resilience4j with the given 
configuration.
+     */
+    public CircuitBreakerDefinition 
resilience4jConfiguration(Resilience4jConfigurationDefinition configuration) {
+        resilience4jConfiguration = configuration;
+        return this;
+    }
+
+    /**
      * Refers to a configuration to use for configuring the circuit breaker.
      */
     public CircuitBreakerDefinition configuration(String ref) {
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java
new file mode 100644
index 0000000..3c5be79
--- /dev/null
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java
@@ -0,0 +1,218 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+
+import org.apache.camel.spi.Metadata;
+
+@XmlAccessorType(XmlAccessType.FIELD)
+public class Resilience4jConfigurationCommon extends IdentifiedType {
+
+    @XmlAttribute
+    @Metadata(defaultValue = "Camel")
+    private String groupKey;
+    @XmlAttribute
+    @Metadata(defaultValue = "50")
+    private Float failureRateThreshold;
+    @XmlAttribute
+    @Metadata(defaultValue = "10")
+    private Integer permittedNumberOfCallsInHalfOpenState;
+    @XmlAttribute
+    @Metadata(defaultValue = "100")
+    private Integer slidingWindowSize;
+    @XmlAttribute
+    @Metadata(defaultValue = "COUNT_BASED", enums = "TIME_BASED,COUNT_BASED")
+    private String slidingWindowType;
+    @XmlAttribute
+    @Metadata(defaultValue = "100")
+    private Integer minimumNumberOfCalls;
+    @XmlAttribute
+    @Metadata(defaultValue = "true")
+    private Boolean writableStackTraceEnabled;
+    @XmlAttribute
+    @Metadata(defaultValue = "60")
+    private Integer waitDurationInOpenState;
+    @XmlAttribute
+    @Metadata(defaultValue = "false")
+    private Boolean automaticTransitionFromOpenToHalfOpenEnabled;
+    @XmlAttribute
+    @Metadata(defaultValue = "100")
+    private Float slowCallRateThreshold;
+    @XmlAttribute
+    @Metadata(defaultValue = "60")
+    private Integer slowCallDurationThreshold;
+
+    // Getter/Setter
+    // 
-------------------------------------------------------------------------
+
+    public String getGroupKey() {
+        return groupKey;
+    }
+
+    /**
+     * Sets the group key to use. The default value is Camel.
+     */
+    public void setGroupKey(String groupKey) {
+        this.groupKey = groupKey;
+    }
+
+    public Float getFailureRateThreshold() {
+        return failureRateThreshold;
+    }
+
+    /**
+     * Configures the failure rate threshold in percentage.
+     * If the failure rate is equal or greater than the threshold the 
CircuitBreaker transitions to open and starts short-circuiting calls.
+     * <p>
+     * The threshold must be greater than 0 and not greater than 100. Default 
value is 50 percentage.
+     */
+    public void setFailureRateThreshold(Float failureRateThreshold) {
+        this.failureRateThreshold = failureRateThreshold;
+    }
+
+    public Integer getPermittedNumberOfCallsInHalfOpenState() {
+        return permittedNumberOfCallsInHalfOpenState;
+    }
+
+    /**
+     * Configures the number of permitted calls when the CircuitBreaker is 
half open.
+     * <p>
+     * The size must be greater than 0. Default size is 10.
+     */
+    public void setPermittedNumberOfCallsInHalfOpenState(Integer 
permittedNumberOfCallsInHalfOpenState) {
+        this.permittedNumberOfCallsInHalfOpenState = 
permittedNumberOfCallsInHalfOpenState;
+    }
+
+    public Integer getSlidingWindowSize() {
+        return slidingWindowSize;
+    }
+
+    /**
+     * Configures the size of the sliding window which is used to record the 
outcome of calls when the CircuitBreaker is closed.
+     * {@code slidingWindowSize} configures the size of the sliding window. 
Sliding window can either be count-based or time-based.
+     *
+     * If {@code slidingWindowType} is COUNT_BASED, the last {@code 
slidingWindowSize} calls are recorded and aggregated.
+     * If {@code slidingWindowType} is TIME_BASED, the calls of the last 
{@code slidingWindowSize} seconds are recorded and aggregated.
+     * <p>
+     * The {@code slidingWindowSize} must be greater than 0.
+     * The {@code minimumNumberOfCalls} must be greater than 0.
+     * If the slidingWindowType is COUNT_BASED, the {@code 
minimumNumberOfCalls} cannot be greater than {@code slidingWindowSize}.
+     * If the slidingWindowType is TIME_BASED, you can pick whatever you want.
+     *
+     * Default slidingWindowSize is 100.
+     */
+    public void setSlidingWindowSize(Integer slidingWindowSize) {
+        this.slidingWindowSize = slidingWindowSize;
+    }
+
+    public String getSlidingWindowType() {
+        return slidingWindowType;
+    }
+
+    /**
+     * Configures the type of the sliding window which is used to record the 
outcome of calls when the CircuitBreaker is closed.
+     * Sliding window can either be count-based or time-based.
+     *
+     * If {@code slidingWindowType} is COUNT_BASED, the last {@code 
slidingWindowSize} calls are recorded and aggregated.
+     * If {@code slidingWindowType} is TIME_BASED, the calls of the last 
{@code slidingWindowSize} seconds are recorded and aggregated.
+     *
+     * Default slidingWindowType is COUNT_BASED.
+     */
+    public void setSlidingWindowType(String slidingWindowType) {
+        this.slidingWindowType = slidingWindowType;
+    }
+
+    public Integer getMinimumNumberOfCalls() {
+        return minimumNumberOfCalls;
+    }
+
+    /**
+     * Configures configures the minimum number of calls which are required 
(per sliding window period) before the CircuitBreaker can calculate the error 
rate.
+     * For example, if {@code minimumNumberOfCalls} is 10, then at least 10 
calls must be recorded, before the failure rate can be calculated.
+     * If only 9 calls have been recorded the CircuitBreaker will not 
transition to open even if all 9 calls have failed.
+     *
+     * Default minimumNumberOfCalls is 100
+     */
+    public void setMinimumNumberOfCalls(Integer minimumNumberOfCalls) {
+        this.minimumNumberOfCalls = minimumNumberOfCalls;
+    }
+
+    public Boolean getWritableStackTraceEnabled() {
+        return writableStackTraceEnabled;
+    }
+
+    /**
+     * Enables writable stack traces. When set to false, 
Exception.getStackTrace returns a zero length array.
+     * 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).
+     */
+    public void setWritableStackTraceEnabled(Boolean 
writableStackTraceEnabled) {
+        this.writableStackTraceEnabled = writableStackTraceEnabled;
+    }
+
+    public Integer getWaitDurationInOpenState() {
+        return waitDurationInOpenState;
+    }
+
+    /**
+     * Configures the wait duration (in seconds) which specifies how long the 
CircuitBreaker should stay open, before it switches to half open.
+     * Default value is 60 seconds.
+     */
+    public void setWaitDurationInOpenState(Integer waitDurationInOpenState) {
+        this.waitDurationInOpenState = waitDurationInOpenState;
+    }
+
+    public Boolean getAutomaticTransitionFromOpenToHalfOpenEnabled() {
+        return automaticTransitionFromOpenToHalfOpenEnabled;
+    }
+
+    /**
+     * Enables automatic transition from OPEN to HALF_OPEN state once the 
waitDurationInOpenState has passed.
+     */
+    public void setAutomaticTransitionFromOpenToHalfOpenEnabled(Boolean 
automaticTransitionFromOpenToHalfOpenEnabled) {
+        this.automaticTransitionFromOpenToHalfOpenEnabled = 
automaticTransitionFromOpenToHalfOpenEnabled;
+    }
+
+    public Float getSlowCallRateThreshold() {
+        return slowCallRateThreshold;
+    }
+
+    /**
+     * Configures a threshold in percentage. The CircuitBreaker considers a 
call as slow when the call duration is greater than 
slowCallDurationThreshold(Duration.
+     * When the percentage of slow calls is equal or greater the threshold, 
the CircuitBreaker transitions to open and starts short-circuiting calls.
+     * <p>
+     * The threshold must be greater than 0 and not greater than 100.
+     * Default value is 100 percentage which means that all recorded calls 
must be slower than slowCallDurationThreshold.
+     */
+    public void setSlowCallRateThreshold(Float slowCallRateThreshold) {
+        this.slowCallRateThreshold = slowCallRateThreshold;
+    }
+
+    public Integer getSlowCallDurationThreshold() {
+        return slowCallDurationThreshold;
+    }
+
+    /**
+     * Configures the duration threshold (seconds) above which calls are 
considered as slow and increase the slow calls percentage.
+     * Default value is 60 seconds.
+     */
+    public void setSlowCallDurationThreshold(Integer 
slowCallDurationThreshold) {
+        this.slowCallDurationThreshold = slowCallDurationThreshold;
+    }
+}
diff --git 
a/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java
 
b/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java
new file mode 100644
index 0000000..2275140
--- /dev/null
+++ 
b/core/camel-core-engine/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java
@@ -0,0 +1,177 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.model;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlRootElement;
+import javax.xml.bind.annotation.XmlTransient;
+
+import org.apache.camel.spi.Metadata;
+
+/**
+ * Resilience4j Circuit Breaker EIP configuration
+ */
+@Metadata(label = "eip,routing,circuitbreaker")
+@XmlRootElement(name = "resilience4jConfiguration")
+@XmlAccessorType(XmlAccessType.FIELD)
+public class Resilience4jConfigurationDefinition extends 
Resilience4jConfigurationCommon {
+
+    public static final String DEFAULT_GROUP_KEY = "Camel";
+
+    @XmlTransient
+    private CircuitBreakerDefinition parent;
+
+    public Resilience4jConfigurationDefinition() {
+    }
+
+    public Resilience4jConfigurationDefinition(CircuitBreakerDefinition 
parent) {
+        this.parent = parent;
+    }
+
+    // Fluent API
+    // 
-------------------------------------------------------------------------
+
+    /**
+     * Sets the group key to use. The default value is Camel.
+     */
+    public Resilience4jConfigurationDefinition groupKey(String groupKey) {
+        setGroupKey(groupKey);
+        return this;
+    }
+
+    /**
+     * Configures the failure rate threshold in percentage.
+     * If the failure rate is equal or greater than the threshold the 
CircuitBreaker transitions to open and starts short-circuiting calls.
+     * <p>
+     * The threshold must be greater than 0 and not greater than 100. Default 
value is 50 percentage.
+     */
+    public Resilience4jConfigurationDefinition failureRateThreshold(Float 
failureRateThreshold) {
+        setFailureRateThreshold(failureRateThreshold);
+        return this;
+    }
+
+    /**
+     * Configures the number of permitted calls when the CircuitBreaker is 
half open.
+     * <p>
+     * The size must be greater than 0. Default size is 10.
+     */
+    public Resilience4jConfigurationDefinition 
permittedNumberOfCallsInHalfOpenState(Integer 
permittedNumberOfCallsInHalfOpenState) {
+        
setPermittedNumberOfCallsInHalfOpenState(permittedNumberOfCallsInHalfOpenState);
+        return this;
+    }
+
+    /**
+     * Configures the size of the sliding window which is used to record the 
outcome of calls when the CircuitBreaker is closed.
+     * {@code slidingWindowSize} configures the size of the sliding window. 
Sliding window can either be count-based or time-based.
+     *
+     * If {@code slidingWindowType} is COUNT_BASED, the last {@code 
slidingWindowSize} calls are recorded and aggregated.
+     * If {@code slidingWindowType} is TIME_BASED, the calls of the last 
{@code slidingWindowSize} seconds are recorded and aggregated.
+     * <p>
+     * The {@code slidingWindowSize} must be greater than 0.
+     * The {@code minimumNumberOfCalls} must be greater than 0.
+     * If the slidingWindowType is COUNT_BASED, the {@code 
minimumNumberOfCalls} cannot be greater than {@code slidingWindowSize}.
+     * If the slidingWindowType is TIME_BASED, you can pick whatever you want.
+     *
+     * Default slidingWindowSize is 100.
+     */
+    public Resilience4jConfigurationDefinition slidingWindowSize(Integer 
slidingWindowSize) {
+        setSlidingWindowSize(slidingWindowSize);
+        return this;
+    }
+
+    /**
+     * Configures the type of the sliding window which is used to record the 
outcome of calls when the CircuitBreaker is closed.
+     * Sliding window can either be count-based or time-based.
+     *
+     * If {@code slidingWindowType} is COUNT_BASED, the last {@code 
slidingWindowSize} calls are recorded and aggregated.
+     * If {@code slidingWindowType} is TIME_BASED, the calls of the last 
{@code slidingWindowSize} seconds are recorded and aggregated.
+     *
+     * Default slidingWindowType is COUNT_BASED.
+     */
+    public Resilience4jConfigurationDefinition slidingWindowType(String 
slidingWindowType) {
+        setSlidingWindowType(slidingWindowType);
+        return this;
+    }
+
+    /**
+     * Configures configures the minimum number of calls which are required 
(per sliding window period) before the CircuitBreaker can calculate the error 
rate.
+     * For example, if {@code minimumNumberOfCalls} is 10, then at least 10 
calls must be recorded, before the failure rate can be calculated.
+     * If only 9 calls have been recorded the CircuitBreaker will not 
transition to open even if all 9 calls have failed.
+     *
+     * Default minimumNumberOfCalls is 100
+     */
+    public Resilience4jConfigurationDefinition minimumNumberOfCalls(Integer 
minimumNumberOfCalls) {
+        setMinimumNumberOfCalls(minimumNumberOfCalls);
+        return this;
+    }
+
+    /**
+     * Enables writable stack traces. When set to false, 
Exception.getStackTrace returns a zero length array.
+     * 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).
+     */
+    public Resilience4jConfigurationDefinition 
writableStackTraceEnabled(Boolean writableStackTraceEnabled) {
+        setWritableStackTraceEnabled(writableStackTraceEnabled);
+        return this;
+    }
+
+    /**
+     * Configures the wait duration (in seconds) which specifies how long the 
CircuitBreaker should stay open, before it switches to half open.
+     * Default value is 60 seconds.
+     */
+    public Resilience4jConfigurationDefinition waitDurationInOpenState(Integer 
waitDurationInOpenState) {
+        setWaitDurationInOpenState(waitDurationInOpenState);
+        return this;
+    }
+
+    /**
+     * Enables automatic transition from OPEN to HALF_OPEN state once the 
waitDurationInOpenState has passed.
+     */
+    public Resilience4jConfigurationDefinition 
automaticTransitionFromOpenToHalfOpenEnabled(Boolean 
automaticTransitionFromOpenToHalfOpenEnabled) {
+        
setAutomaticTransitionFromOpenToHalfOpenEnabled(automaticTransitionFromOpenToHalfOpenEnabled);
+        return this;
+    }
+
+    /**
+     * Configures a threshold in percentage. The CircuitBreaker considers a 
call as slow when the call duration is greater than 
slowCallDurationThreshold(Duration.
+     * When the percentage of slow calls is equal or greater the threshold, 
the CircuitBreaker transitions to open and starts short-circuiting calls.
+     * <p>
+     * The threshold must be greater than 0 and not greater than 100.
+     * Default value is 100 percentage which means that all recorded calls 
must be slower than slowCallDurationThreshold.
+     */
+    public Resilience4jConfigurationDefinition slowCallRateThreshold(Float 
slowCallRateThreshold) {
+        setSlowCallRateThreshold(slowCallRateThreshold);
+        return this;
+    }
+
+    /**
+     * Configures the duration threshold (seconds) above which calls are 
considered as slow and increase the slow calls percentage.
+     * Default value is 60 seconds.
+     */
+    public Resilience4jConfigurationDefinition 
slowCallDurationThreshold(Integer slowCallDurationThreshold) {
+        setSlowCallDurationThreshold(slowCallDurationThreshold);
+        return this;
+    }
+
+    /**
+     * End of configuration.
+     */
+    public CircuitBreakerDefinition end() {
+        return parent;
+    }
+
+}

Reply via email to