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);