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

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


The following commit(s) were added to refs/heads/main by this push:
     new 321e84e17d8 CAMEL-18507: camel-resilience4j - Add option to throw 
exception if CB rejected due to half-open/open state
321e84e17d8 is described below

commit 321e84e17d870da40645c52974b86a9b63f3473f
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Wed Sep 14 15:52:49 2022 +0200

    CAMEL-18507: camel-resilience4j - Add option to throw exception if CB 
rejected due to half-open/open state
---
 .../resilience4j/ResilienceProcessor.java          |  9 +++++---
 .../component/resilience4j/ResilienceReifier.java  |  9 +++++++-
 .../resilience4j/ResilienceRouteRejectedTest.java  | 22 ++++++++++++++++++++
 ...ilience4jConfigurationDefinitionConfigurer.java |  7 +++++++
 .../camel/model/resilience4jConfiguration.json     |  1 +
 .../model/Resilience4jConfigurationCommon.java     | 15 ++++++++++++++
 .../model/Resilience4jConfigurationDefinition.java | 10 +++++++++
 ...ilience4jConfigurationPropertiesConfigurer.java |  7 +++++++
 .../camel-main-configuration-metadata.json         |  1 +
 core/camel-main/src/main/docs/main.adoc            |  3 ++-
 .../main/Resilience4jConfigurationProperties.java  | 24 ++++++++++++++++++++++
 .../java/org/apache/camel/xml/in/ModelParser.java  |  1 +
 12 files changed, 104 insertions(+), 5 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 5b52420f031..0acf20d903e 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
@@ -84,6 +84,7 @@ public class ResilienceProcessor extends AsyncProcessorSupport
     private TimeLimiter timeLimiter;
     private final Processor processor;
     private final Processor fallback;
+    private final boolean throwExceptionWhenHalfOpenOrOpenState;
     private boolean shutdownExecutorService;
     private ExecutorService executorService;
     private ProcessorExchangeFactory processorExchangeFactory;
@@ -92,12 +93,13 @@ public class ResilienceProcessor extends 
AsyncProcessorSupport
 
     public ResilienceProcessor(CircuitBreakerConfig circuitBreakerConfig, 
BulkheadConfig bulkheadConfig,
                                TimeLimiterConfig timeLimiterConfig, Processor 
processor,
-                               Processor fallback) {
+                               Processor fallback, boolean 
throwExceptionWhenHalfOpenOrOpenState) {
         this.circuitBreakerConfig = circuitBreakerConfig;
         this.bulkheadConfig = bulkheadConfig;
         this.timeLimiterConfig = timeLimiterConfig;
         this.processor = processor;
         this.fallback = fallback;
+        this.throwExceptionWhenHalfOpenOrOpenState = 
throwExceptionWhenHalfOpenOrOpenState;
     }
 
     @Override
@@ -636,12 +638,13 @@ public class ResilienceProcessor extends 
AsyncProcessorSupport
                     return exchange;
                 } else if (throwable instanceof CallNotPermittedException) {
                     // the circuit breaker triggered a call rejected
-                    // where the circuit breaker is half-open / open and 
therefore
-                    // we should just set properties and do not set any 
exception
                     
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_SUCCESSFUL_EXECUTION,
 false);
                     
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_FROM_FALLBACK,
 false);
                     
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_SHORT_CIRCUITED,
 true);
                     
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_REJECTED, 
true);
+                    if (throwExceptionWhenHalfOpenOrOpenState) {
+                        exchange.setException(throwable);
+                    }
                     return exchange;
                 } else if (throwable instanceof BulkheadFullException) {
                     // the circuit breaker bulkhead is full
diff --git 
a/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceReifier.java
 
b/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceReifier.java
index ecdbccda287..9b1b66cff83 100644
--- 
a/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceReifier.java
+++ 
b/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceReifier.java
@@ -37,6 +37,7 @@ import org.apache.camel.reifier.ProcessorReifier;
 import org.apache.camel.spi.BeanIntrospection;
 import org.apache.camel.spi.ExtendedPropertyConfigurerGetter;
 import org.apache.camel.spi.PropertyConfigurer;
+import org.apache.camel.support.CamelContextHelper;
 import org.apache.camel.support.PropertyBindingSupport;
 import org.apache.camel.util.function.Suppliers;
 
@@ -63,8 +64,14 @@ public class ResilienceReifier extends 
ProcessorReifier<CircuitBreakerDefinition
         CircuitBreakerConfig cbConfig = configureCircuitBreaker(config);
         BulkheadConfig bhConfig = configureBulkHead(config);
         TimeLimiterConfig tlConfig = configureTimeLimiter(config);
+        boolean throwExceptionWhenHalfOpenOrOpenState = false;
+        Boolean b = CamelContextHelper.parseBoolean(camelContext, 
config.getThrowExceptionWhenHalfOpenOrOpenState());
+        if (b != null) {
+            throwExceptionWhenHalfOpenOrOpenState = b;
+        }
 
-        ResilienceProcessor answer = new ResilienceProcessor(cbConfig, 
bhConfig, tlConfig, processor, fallback);
+        ResilienceProcessor answer = new ResilienceProcessor(
+                cbConfig, bhConfig, tlConfig, processor, fallback, 
throwExceptionWhenHalfOpenOrOpenState);
         configureTimeoutExecutorService(answer, config);
         // using any existing circuit breakers?
         if (config.getCircuitBreaker() != null) {
diff --git 
a/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteRejectedTest.java
 
b/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteRejectedTest.java
index eb27a8ae1a8..4b24d5b97d7 100644
--- 
a/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteRejectedTest.java
+++ 
b/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceRouteRejectedTest.java
@@ -19,11 +19,15 @@ package org.apache.camel.component.resilience4j;
 import javax.management.MBeanServer;
 import javax.management.ObjectName;
 
+import io.github.resilience4j.circuitbreaker.CallNotPermittedException;
+import org.apache.camel.CamelExecutionException;
 import org.apache.camel.builder.RouteBuilder;
 import org.apache.camel.test.junit5.CamelTestSupport;
 import org.junit.jupiter.api.Test;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertInstanceOf;
+import static org.junit.jupiter.api.Assertions.fail;
 
 public class ResilienceRouteRejectedTest extends CamelTestSupport {
 
@@ -46,6 +50,19 @@ public class ResilienceRouteRejectedTest extends 
CamelTestSupport {
         test("direct:start.with.timeout.enabled", "myResilienceWithTimeout");
     }
 
+    @Test
+    public void testResilienceWithThrowException() throws Exception {
+        try {
+            test("direct:start-throw-exception", 
"myResilienceWithThrowException");
+            fail("Should throw exception");
+        } catch (CamelExecutionException e) {
+            CallNotPermittedException ce = 
assertInstanceOf(CallNotPermittedException.class, e.getCause());
+            assertEquals("myResilienceWithThrowException", 
ce.getCausingCircuitBreakerName());
+            assertEquals("CircuitBreaker 'myResilienceWithThrowException' is 
FORCED_OPEN and does not permit further calls",
+                    ce.getMessage());
+        }
+    }
+
     private void test(String endPointUri, String circuitBreakerName) throws 
Exception {
         // look inside jmx
         // get the stats for the route
@@ -83,6 +100,11 @@ public class ResilienceRouteRejectedTest extends 
CamelTestSupport {
                         
.id("myResilienceWithTimeout").to("direct:foo").to("log:foo").end().to("log:result")
                         .to("mock:result");
 
+                from("direct:start-throw-exception")
+                        
.circuitBreaker().resilience4jConfiguration().throwExceptionWhenHalfOpenOrOpenState(true).end()
+                        
.id("myResilienceWithThrowException").to("direct:foo").to("log:foo").end().to("log:result")
+                        .to("mock:result");
+
                 from("direct:foo").transform().constant("Bye World");
             }
         };
diff --git 
a/core/camel-core-model/src/generated/java/org/apache/camel/model/Resilience4jConfigurationDefinitionConfigurer.java
 
b/core/camel-core-model/src/generated/java/org/apache/camel/model/Resilience4jConfigurationDefinitionConfigurer.java
index 28ebbfd96b0..b57882d05a2 100644
--- 
a/core/camel-core-model/src/generated/java/org/apache/camel/model/Resilience4jConfigurationDefinitionConfigurer.java
+++ 
b/core/camel-core-model/src/generated/java/org/apache/camel/model/Resilience4jConfigurationDefinitionConfigurer.java
@@ -34,6 +34,7 @@ public class Resilience4jConfigurationDefinitionConfigurer 
extends org.apache.ca
         map.put("SlidingWindowType", java.lang.String.class);
         map.put("SlowCallDurationThreshold", java.lang.String.class);
         map.put("SlowCallRateThreshold", java.lang.String.class);
+        map.put("ThrowExceptionWhenHalfOpenOrOpenState", 
java.lang.String.class);
         map.put("TimeoutCancelRunningFuture", java.lang.String.class);
         map.put("TimeoutDuration", java.lang.String.class);
         map.put("TimeoutEnabled", java.lang.String.class);
@@ -75,6 +76,8 @@ public class Resilience4jConfigurationDefinitionConfigurer 
extends org.apache.ca
         case "SlowCallDurationThreshold": 
target.setSlowCallDurationThreshold(property(camelContext, 
java.lang.String.class, value)); return true;
         case "slowcallratethreshold":
         case "SlowCallRateThreshold": 
target.setSlowCallRateThreshold(property(camelContext, java.lang.String.class, 
value)); return true;
+        case "throwexceptionwhenhalfopenoropenstate":
+        case "ThrowExceptionWhenHalfOpenOrOpenState": 
target.setThrowExceptionWhenHalfOpenOrOpenState(property(camelContext, 
java.lang.String.class, value)); return true;
         case "timeoutcancelrunningfuture":
         case "TimeoutCancelRunningFuture": 
target.setTimeoutCancelRunningFuture(property(camelContext, 
java.lang.String.class, value)); return true;
         case "timeoutduration":
@@ -127,6 +130,8 @@ public class Resilience4jConfigurationDefinitionConfigurer 
extends org.apache.ca
         case "SlowCallDurationThreshold": return java.lang.String.class;
         case "slowcallratethreshold":
         case "SlowCallRateThreshold": return java.lang.String.class;
+        case "throwexceptionwhenhalfopenoropenstate":
+        case "ThrowExceptionWhenHalfOpenOrOpenState": return 
java.lang.String.class;
         case "timeoutcancelrunningfuture":
         case "TimeoutCancelRunningFuture": return java.lang.String.class;
         case "timeoutduration":
@@ -175,6 +180,8 @@ public class Resilience4jConfigurationDefinitionConfigurer 
extends org.apache.ca
         case "SlowCallDurationThreshold": return 
target.getSlowCallDurationThreshold();
         case "slowcallratethreshold":
         case "SlowCallRateThreshold": return target.getSlowCallRateThreshold();
+        case "throwexceptionwhenhalfopenoropenstate":
+        case "ThrowExceptionWhenHalfOpenOrOpenState": return 
target.getThrowExceptionWhenHalfOpenOrOpenState();
         case "timeoutcancelrunningfuture":
         case "TimeoutCancelRunningFuture": return 
target.getTimeoutCancelRunningFuture();
         case "timeoutduration":
diff --git 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/resilience4jConfiguration.json
 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/resilience4jConfiguration.json
index de134cf0125..fa87423edeb 100644
--- 
a/core/camel-core-model/src/generated/resources/org/apache/camel/model/resilience4jConfiguration.json
+++ 
b/core/camel-core-model/src/generated/resources/org/apache/camel/model/resilience4jConfiguration.json
@@ -16,6 +16,7 @@
     "config": { "kind": "attribute", "displayName": "Config", "label": 
"advanced", "required": false, "type": "string", "javaType": 
"java.lang.String", "deprecated": false, "autowired": false, "secret": false, 
"description": "Refers to an existing 
io.github.resilience4j.circuitbreaker.CircuitBreakerConfig instance to lookup 
and use from the registry." },
     "failureRateThreshold": { "kind": "attribute", "displayName": "Failure 
Rate Threshold", "required": false, "type": "number", "javaType": 
"java.lang.Float", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "50", "description": "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. The 
threshold must be greater than 0 and not great [...]
     "permittedNumberOfCallsInHalfOpenState": { "kind": "attribute", 
"displayName": "Permitted Number Of Calls In Half Open State", "label": 
"advanced", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "10", "description": "Configures the number of permitted calls 
when the CircuitBreaker is half open. The size must be greater than 0. Default 
size is 10." },
+    "throwExceptionWhenHalfOpenOrOpenState": { "kind": "attribute", 
"displayName": "Throw Exception When Half Open Or Open State", "required": 
false, "type": "boolean", "javaType": "java.lang.Boolean", "deprecated": false, 
"autowired": false, "secret": false, "defaultValue": false, "description": 
"Whether to throw 
io.github.resilience4j.circuitbreaker.CallNotPermittedException when the call 
is rejected due circuit breaker is half open or open." },
     "slidingWindowSize": { "kind": "attribute", "displayName": "Sliding Window 
Size", "required": false, "type": "integer", "javaType": "java.lang.Integer", 
"deprecated": false, "autowired": false, "secret": false, "defaultValue": 
"100", "description": "Configures the size of the sliding window which is used 
to record the outcome of calls when the CircuitBreaker is closed. 
slidingWindowSize configures the size of the sliding window. Sliding window can 
either be count-based or time-based. [...]
     "slidingWindowType": { "kind": "attribute", "displayName": "Sliding Window 
Type", "label": "advanced", "required": false, "type": "enum", "javaType": 
"java.lang.String", "enum": [ "TIME_BASED", "COUNT_BASED" ], "deprecated": 
false, "autowired": false, "secret": false, "defaultValue": "COUNT_BASED", 
"description": "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-b [...]
     "minimumNumberOfCalls": { "kind": "attribute", "displayName": "Minimum 
Number Of Calls", "required": false, "type": "integer", "javaType": 
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, 
"defaultValue": "100", "description": "Configures the minimum number of calls 
which are required (per sliding window period) before the CircuitBreaker can 
calculate the error rate. For example, if minimumNumberOfCalls is 10, then at 
least 10 calls must be recorded, befo [...]
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java
index dacb08e3e4e..ba5994ef43b 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationCommon.java
@@ -40,6 +40,9 @@ public class Resilience4jConfigurationCommon extends 
IdentifiedType {
     @Metadata(label = "advanced", defaultValue = "10", javaType = 
"java.lang.Integer")
     private String permittedNumberOfCallsInHalfOpenState;
     @XmlAttribute
+    @Metadata(defaultValue = "false", javaType = "java.lang.Boolean")
+    private String throwExceptionWhenHalfOpenOrOpenState;
+    @XmlAttribute
     @Metadata(defaultValue = "100", javaType = "java.lang.Integer")
     private String slidingWindowSize;
     @XmlAttribute
@@ -132,6 +135,18 @@ public class Resilience4jConfigurationCommon extends 
IdentifiedType {
         this.permittedNumberOfCallsInHalfOpenState = 
permittedNumberOfCallsInHalfOpenState;
     }
 
+    public String getThrowExceptionWhenHalfOpenOrOpenState() {
+        return throwExceptionWhenHalfOpenOrOpenState;
+    }
+
+    /**
+     * Whether to throw 
io.github.resilience4j.circuitbreaker.CallNotPermittedException when the call
+     * is rejected due circuit breaker is half open or open.
+     */
+    public void setThrowExceptionWhenHalfOpenOrOpenState(String 
throwExceptionWhenHalfOpenOrOpenState) {
+        this.throwExceptionWhenHalfOpenOrOpenState = 
throwExceptionWhenHalfOpenOrOpenState;
+    }
+
     public String getSlidingWindowSize() {
         return slidingWindowSize;
     }
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java
index e76a92ec5e7..9bd4f7ba9fd 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/Resilience4jConfigurationDefinition.java
@@ -88,6 +88,16 @@ public class Resilience4jConfigurationDefinition extends 
Resilience4jConfigurati
         return this;
     }
 
+    /**
+     * Whether to throw 
io.github.resilience4j.circuitbreaker.CallNotPermittedException when the call
+     * is rejected due circuit breaker is half open or open.
+     */
+    public Resilience4jConfigurationDefinition 
throwExceptionWhenHalfOpenOrOpenState(
+            boolean throwExceptionWhenHalfOpenOrOpenState) {
+        
setThrowExceptionWhenHalfOpenOrOpenState(Boolean.toString(throwExceptionWhenHalfOpenOrOpenState));
+        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
diff --git 
a/core/camel-main/src/generated/java/org/apache/camel/main/Resilience4jConfigurationPropertiesConfigurer.java
 
b/core/camel-main/src/generated/java/org/apache/camel/main/Resilience4jConfigurationPropertiesConfigurer.java
index 591343125f4..013c26a8275 100644
--- 
a/core/camel-main/src/generated/java/org/apache/camel/main/Resilience4jConfigurationPropertiesConfigurer.java
+++ 
b/core/camel-main/src/generated/java/org/apache/camel/main/Resilience4jConfigurationPropertiesConfigurer.java
@@ -33,6 +33,7 @@ public class Resilience4jConfigurationPropertiesConfigurer 
extends org.apache.ca
         map.put("SlidingWindowType", java.lang.String.class);
         map.put("SlowCallDurationThreshold", java.lang.Integer.class);
         map.put("SlowCallRateThreshold", java.lang.Float.class);
+        map.put("ThrowExceptionWhenHalfOpenOrOpenState", 
java.lang.Boolean.class);
         map.put("TimeoutCancelRunningFuture", java.lang.Boolean.class);
         map.put("TimeoutDuration", java.lang.Integer.class);
         map.put("TimeoutEnabled", java.lang.Boolean.class);
@@ -73,6 +74,8 @@ public class Resilience4jConfigurationPropertiesConfigurer 
extends org.apache.ca
         case "SlowCallDurationThreshold": 
target.setSlowCallDurationThreshold(property(camelContext, 
java.lang.Integer.class, value)); return true;
         case "slowcallratethreshold":
         case "SlowCallRateThreshold": 
target.setSlowCallRateThreshold(property(camelContext, java.lang.Float.class, 
value)); return true;
+        case "throwexceptionwhenhalfopenoropenstate":
+        case "ThrowExceptionWhenHalfOpenOrOpenState": 
target.setThrowExceptionWhenHalfOpenOrOpenState(property(camelContext, 
java.lang.Boolean.class, value)); return true;
         case "timeoutcancelrunningfuture":
         case "TimeoutCancelRunningFuture": 
target.setTimeoutCancelRunningFuture(property(camelContext, 
java.lang.Boolean.class, value)); return true;
         case "timeoutduration":
@@ -127,6 +130,8 @@ public class Resilience4jConfigurationPropertiesConfigurer 
extends org.apache.ca
         case "SlowCallDurationThreshold": return java.lang.Integer.class;
         case "slowcallratethreshold":
         case "SlowCallRateThreshold": return java.lang.Float.class;
+        case "throwexceptionwhenhalfopenoropenstate":
+        case "ThrowExceptionWhenHalfOpenOrOpenState": return 
java.lang.Boolean.class;
         case "timeoutcancelrunningfuture":
         case "TimeoutCancelRunningFuture": return java.lang.Boolean.class;
         case "timeoutduration":
@@ -173,6 +178,8 @@ public class Resilience4jConfigurationPropertiesConfigurer 
extends org.apache.ca
         case "SlowCallDurationThreshold": return 
target.getSlowCallDurationThreshold();
         case "slowcallratethreshold":
         case "SlowCallRateThreshold": return target.getSlowCallRateThreshold();
+        case "throwexceptionwhenhalfopenoropenstate":
+        case "ThrowExceptionWhenHalfOpenOrOpenState": return 
target.getThrowExceptionWhenHalfOpenOrOpenState();
         case "timeoutcancelrunningfuture":
         case "TimeoutCancelRunningFuture": return 
target.getTimeoutCancelRunningFuture();
         case "timeoutduration":
diff --git 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
index 244dd57d7c9..326888ac898 100644
--- 
a/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
+++ 
b/core/camel-main/src/generated/resources/META-INF/camel-main-configuration-metadata.json
@@ -167,6 +167,7 @@
     { "name": "camel.resilience4j.slidingWindowType", "description": 
"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 slidingWindowType is COUNT_BASED, the last 
slidingWindowSize calls are recorded and aggregated. If slidingWindowType is 
TIME_BASED, the calls of the last slidingWindowSize seconds are recorded and 
aggregated. Default slidingWindowType is COU [...]
     { "name": "camel.resilience4j.slowCallDurationThreshold", "description": 
"Configures the duration threshold (seconds) above which calls are considered 
as slow and increase the slow calls percentage. Default value is 60 seconds.", 
"sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", 
"type": "integer", "javaType": "java.lang.Integer", "defaultValue": 60 },
     { "name": "camel.resilience4j.slowCallRateThreshold", "description": 
"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. The 
threshold must be greater than 0 and not greater than 100. Default value is 100 
percentage which means that all re [...]
+    { "name": "camel.resilience4j.throwExceptionWhenHalfOpenOrOpenState", 
"description": "Whether to throw 
io.github.resilience4j.circuitbreaker.CallNotPermittedException when the call 
is rejected due circuit breaker is half open or open.", "sourceType": 
"org.apache.camel.main.Resilience4jConfigurationProperties", "type": "boolean", 
"javaType": "java.lang.Boolean", "defaultValue": false },
     { "name": "camel.resilience4j.timeoutCancelRunningFuture", "description": 
"Configures whether cancel is called on the running future. Defaults to true.", 
"sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", 
"type": "boolean", "javaType": "java.lang.Boolean", "defaultValue": true },
     { "name": "camel.resilience4j.timeoutDuration", "description": "Configures 
the thread execution timeout (millis). Default value is 1000 millis (1 
second).", "sourceType": 
"org.apache.camel.main.Resilience4jConfigurationProperties", "type": "integer", 
"javaType": "java.lang.Integer", "defaultValue": 1000 },
     { "name": "camel.resilience4j.timeoutEnabled", "description": "Whether 
timeout is enabled or not on the circuit breaker. Default is false.", 
"sourceType": "org.apache.camel.main.Resilience4jConfigurationProperties", 
"type": "boolean", "javaType": "java.lang.Boolean", "defaultValue": false },
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index f946ead8202..73171822dff 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -271,7 +271,7 @@ The camel.faulttolerance supports 13 options, which are 
listed below.
 |===
 
 === Resilience4j EIP Circuit Breaker configurations
-The camel.resilience4j supports 19 options, which are listed below.
+The camel.resilience4j supports 20 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -289,6 +289,7 @@ The camel.resilience4j supports 19 options, which are 
listed below.
 | *camel.resilience4j.sliding{zwsp}WindowType* | 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 slidingWindowType is COUNT_BASED, the last slidingWindowSize 
calls are recorded and aggregated. If slidingWindowType is TIME_BASED, the 
calls of the last slidingWindowSize seconds are recorded and aggregated. 
Default slidingWindowType is COUNT_BASED. | COUNT_BAS [...]
 | *camel.resilience4j.slowCall{zwsp}DurationThreshold* | Configures the 
duration threshold (seconds) above which calls are considered as slow and 
increase the slow calls percentage. Default value is 60 seconds. | 60 | Integer
 | *camel.resilience4j.slowCall{zwsp}RateThreshold* | 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. 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  [...]
+| *camel.resilience4j.throw{zwsp}ExceptionWhenHalfOpenOrOpen{zwsp}State* | 
Whether to throw 
io.github.resilience4j.circuitbreaker.CallNotPermittedException when the call 
is rejected due circuit breaker is half open or open. | false | Boolean
 | *camel.resilience4j.timeout{zwsp}CancelRunningFuture* | Configures whether 
cancel is called on the running future. Defaults to true. | true | Boolean
 | *camel.resilience4j.timeout{zwsp}Duration* | Configures the thread execution 
timeout (millis). Default value is 1000 millis (1 second). | 1000 | Integer
 | *camel.resilience4j.timeout{zwsp}Enabled* | Whether timeout is enabled or 
not on the circuit breaker. Default is false. | false | Boolean
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/Resilience4jConfigurationProperties.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/Resilience4jConfigurationProperties.java
index d557c49d3f4..51a1aaaa42f 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/Resilience4jConfigurationProperties.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/Resilience4jConfigurationProperties.java
@@ -36,6 +36,8 @@ public class Resilience4jConfigurationProperties implements 
BootstrapCloseable {
     private Float failureRateThreshold;
     @Metadata(defaultValue = "10")
     private Integer permittedNumberOfCallsInHalfOpenState;
+    @Metadata(defaultValue = "false")
+    private Boolean throwExceptionWhenHalfOpenOrOpenState;
     @Metadata(defaultValue = "100")
     private Integer slidingWindowSize;
     @Metadata(defaultValue = "COUNT_BASED", enums = "COUNT_BASED,TIME_BASED")
@@ -129,6 +131,18 @@ public class Resilience4jConfigurationProperties 
implements BootstrapCloseable {
         this.permittedNumberOfCallsInHalfOpenState = 
permittedNumberOfCallsInHalfOpenState;
     }
 
+    public Boolean getThrowExceptionWhenHalfOpenOrOpenState() {
+        return throwExceptionWhenHalfOpenOrOpenState;
+    }
+
+    /**
+     * Whether to throw 
io.github.resilience4j.circuitbreaker.CallNotPermittedException when the call
+     * is rejected due circuit breaker is half open or open.
+     */
+    public void setThrowExceptionWhenHalfOpenOrOpenState(Boolean 
throwExceptionWhenHalfOpenOrOpenState) {
+        this.throwExceptionWhenHalfOpenOrOpenState = 
throwExceptionWhenHalfOpenOrOpenState;
+    }
+
     public Integer getSlidingWindowSize() {
         return slidingWindowSize;
     }
@@ -374,6 +388,16 @@ public class Resilience4jConfigurationProperties 
implements BootstrapCloseable {
         return this;
     }
 
+    /**
+     * Whether to throw 
io.github.resilience4j.circuitbreaker.CallNotPermittedException when the call
+     * is rejected due circuit breaker is half open or open.
+     */
+    public Resilience4jConfigurationProperties 
withThrowExceptionWhenHalfOpenOrOpenState(
+            Boolean throwExceptionWhenHalfOpenOrOpenState) {
+        this.throwExceptionWhenHalfOpenOrOpenState = 
throwExceptionWhenHalfOpenOrOpenState;
+        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
diff --git 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
index 7ca23e33695..54ee7a6daf6 100644
--- 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
+++ 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/in/ModelParser.java
@@ -891,6 +891,7 @@ public class ModelParser extends BaseParser {
                 case "slidingWindowType": def.setSlidingWindowType(val); break;
                 case "slowCallDurationThreshold": 
def.setSlowCallDurationThreshold(val); break;
                 case "slowCallRateThreshold": 
def.setSlowCallRateThreshold(val); break;
+                case "throwExceptionWhenHalfOpenOrOpenState": 
def.setThrowExceptionWhenHalfOpenOrOpenState(val); break;
                 case "waitDurationInOpenState": 
def.setWaitDurationInOpenState(val); break;
                 case "writableStackTraceEnabled": 
def.setWritableStackTraceEnabled(val); break;
                 default: return identifiedTypeAttributeHandler().accept(def, 
key, val);

Reply via email to