You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2019/11/18 09:00:45 UTC

[camel] 03/23: CAMEL-13691: camel-resilience4j - WIP

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 <cl...@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;
+    }
+
+}