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 9971a57276a2 CAMEL-24136: Fix FT circuit breaker exchange properties,
bulkhead, dead option, docs
9971a57276a2 is described below
commit 9971a57276a27db5549bffd032044b4abb45b6a9
Author: Claus Ibsen <[email protected]>
AuthorDate: Fri Jul 17 06:52:38 2026 +0200
CAMEL-24136: Fix FT circuit breaker exchange properties, bulkhead, dead
option, docs
Co-Authored-By: Claude Opus 4.6 <[email protected]>
---
.../models/faultToleranceConfiguration.json | 2 +-
.../apache/camel/catalog/schemas/camel-spring.xsd | 2 +-
.../apache/camel/catalog/schemas/camel-xml-io.xsd | 2 +-
.../FaultToleranceConfiguration.java | 2 +
.../faulttolerance/FaultToleranceProcessor.java | 41 +++++-------
.../faulttolerance/FaultToleranceReifier.java | 1 +
.../FaultToleranceTimeoutExchangePropertyTest.java | 64 +++++++++++++++++++
...nceTimeoutWithFallbackExchangePropertyTest.java | 74 ++++++++++++++++++++++
.../component/resilience4j/ResilienceConsole.java | 6 +-
.../resilience4j/ResilienceProcessor.java | 2 +-
.../modules/eips/pages/circuitBreaker-eip.adoc | 8 ++-
.../modules/eips/pages/fault-tolerance-eip.adoc | 17 +++--
.../docs/modules/eips/pages/resilience4j-eip.adoc | 8 ++-
.../camel/model/faultToleranceConfiguration.json | 2 +-
.../model/FaultToleranceConfigurationCommon.java | 6 +-
.../FaultToleranceConfigurationDefinition.java | 6 +-
.../dsl/yaml/deserializers/ModelDeserializers.java | 2 +-
.../resources/schema/camelYamlDsl-canonical.json | 3 +-
.../generated/resources/schema/camelYamlDsl.json | 3 +-
19 files changed, 203 insertions(+), 48 deletions(-)
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/faultToleranceConfiguration.json
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/faultToleranceConfiguration.json
index 3b049f5d7448..2b2bbbd57eb3 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/faultToleranceConfiguration.json
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/models/faultToleranceConfiguration.json
@@ -20,7 +20,7 @@
"failureRatio": { "index": 5, "kind": "attribute", "displayName": "Failure
Ratio", "group": "common", "required": false, "type": "integer", "javaType":
"java.lang.Integer", "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." },
"timeoutEnabled": { "index": 6, "kind": "attribute", "displayName":
"Timeout Enabled", "group": "common", "required": false, "type": "boolean",
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "description": "Whether timeout is
enabled or not on the circuit breaker." },
"timeoutDuration": { "index": 7, "kind": "attribute", "displayName":
"Timeout Duration", "group": "common", "required": false, "type": "duration",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "1000", "description": "Configures the thread
execution timeout. Default value is 1 second." },
- "timeoutPoolSize": { "index": 8, "kind": "attribute", "displayName":
"Timeout Pool Size", "group": "advanced", "label": "advanced", "required":
false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": 10, "description":
"Configures the pool size of the thread pool when timeout is enabled." },
+ "timeoutPoolSize": { "index": 8, "kind": "attribute", "displayName":
"Timeout Pool Size", "group": "advanced", "label": "advanced", "required":
false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": true,
"deprecationNote": "No longer in use", "autowired": false, "secret": false,
"defaultValue": 10, "description": "Deprecated: no longer in use since the
switch to TypedGuard API (CAMEL-21857)." },
"bulkheadEnabled": { "index": 9, "kind": "attribute", "displayName":
"Bulkhead Enabled", "group": "common", "required": false, "type": "boolean",
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "description": "Whether bulkhead is
enabled or not on the circuit breaker." },
"bulkheadMaxConcurrentCalls": { "index": 10, "kind": "attribute",
"displayName": "Bulkhead Max Concurrent Calls", "group": "advanced", "label":
"advanced", "required": false, "type": "integer", "javaType":
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": 10, "description": "Configures the max amount of concurrent
calls the bulkhead will support." },
"bulkheadWaitingTaskQueue": { "index": 11, "kind": "attribute",
"displayName": "Bulkhead Waiting Task Queue", "group": "advanced", "label":
"advanced", "required": false, "type": "integer", "javaType":
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": 10, "description": "Configures the task queue size for holding
waiting tasks to be processed by the bulkhead." },
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
index 7e56fd14b750..a1b529fd3603 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-spring.xsd
@@ -4671,7 +4671,7 @@ Configures the thread execution timeout. Default value is
1 second. Default valu
<xs:annotation>
<xs:documentation xml:lang="en">
<![CDATA[
-Configures the pool size of the thread pool when timeout is enabled. Default
value: 10
+Deprecated: Deprecated: no longer in use since the switch to TypedGuard API
(CAMEL-21857). Default value: 10
]]>
</xs:documentation>
</xs:annotation>
diff --git
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
index 12ffe8606d96..f4e0045b8144 100644
---
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
+++
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/schemas/camel-xml-io.xsd
@@ -3793,7 +3793,7 @@ Configures the thread execution timeout. Default value is
1 second. Default valu
<xs:annotation>
<xs:documentation xml:lang="en">
<![CDATA[
-Configures the pool size of the thread pool when timeout is enabled. Default
value: 10
+Deprecated: Deprecated: no longer in use since the switch to TypedGuard API
(CAMEL-21857). Default value: 10
]]>
</xs:documentation>
</xs:annotation>
diff --git
a/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceConfiguration.java
b/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceConfiguration.java
index 7cb3d4da8bdf..4f0cdc0dc413 100644
---
a/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceConfiguration.java
+++
b/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceConfiguration.java
@@ -78,10 +78,12 @@ public class FaultToleranceConfiguration {
this.timeoutDuration = timeoutDuration;
}
+ @Deprecated(since = "4.22.0")
public int getTimeoutPoolSize() {
return timeoutPoolSize;
}
+ @Deprecated(since = "4.22.0")
public void setTimeoutPoolSize(int timeoutPoolSize) {
this.timeoutPoolSize = timeoutPoolSize;
}
diff --git
a/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceProcessor.java
b/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceProcessor.java
index 2b7cb3a65833..0127ee790f06 100644
---
a/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceProcessor.java
+++
b/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceProcessor.java
@@ -153,7 +153,7 @@ public class FaultToleranceProcessor extends
BaseProcessorSupport
return config.getDelay();
}
- @ManagedAttribute(description = "Returns the current failure rate in
percentage.")
+ @ManagedAttribute(description = "Returns the configured failure ratio
threshold (0.0-1.0).")
public float getFailureRate() {
return config.getFailureRatio();
}
@@ -178,7 +178,8 @@ public class FaultToleranceProcessor extends
BaseProcessorSupport
return config.getTimeoutDuration();
}
- @ManagedAttribute(description = "The timeout pool size for the thread
pool")
+ @Deprecated(since = "4.22.0")
+ @ManagedAttribute(description = "Deprecated: no longer in use since the
switch to TypedGuard API (CAMEL-21857)")
public int getTimeoutPoolSize() {
return config.getTimeoutPoolSize();
}
@@ -248,6 +249,8 @@ public class FaultToleranceProcessor extends
BaseProcessorSupport
// Do fallback if applicable. Note that a fallback handler is
not configured on the TypedGuard builder
// and is instead invoked manually here since we need access
to the message exchange on each FaultToleranceProcessor.process call
if (fallbackProcessor != null) {
+ // store guard exception so the fallback can see it via
Exchange.EXCEPTION_CAUGHT
+ exchange.setException(e);
fallbackTask = (CircuitBreakerFallbackTask)
fallbackTaskFactory.acquire(exchange, null);
fallbackTask.call();
} else {
@@ -260,6 +263,13 @@ public class FaultToleranceProcessor extends
BaseProcessorSupport
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);
+ } catch (TimeoutException e) {
+ // the circuit breaker triggered a timeout (no fallback)
+
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,
false);
+
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_TIMED_OUT,
true);
+ exchange.setException(e);
} catch (Exception e) {
// some other kind of exception
exchange.setException(e);
@@ -511,34 +521,13 @@ public class FaultToleranceProcessor extends
BaseProcessorSupport
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_STATE, state);
}
- Throwable throwable = exchange.getException();
- if (fallbackProcessor == null) {
- if (throwable instanceof TimeoutException) {
- // the circuit breaker triggered a timeout (and there is no
- // fallback) so lets mark the exchange as failed
-
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,
false);
-
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_TIMED_OUT,
true);
- exchange.setException(throwable);
- return exchange;
- } else if (throwable instanceof CircuitBreakerOpenException) {
- // the circuit breaker triggered a call rejected
-
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);
- return exchange;
- } else {
- // throw exception so fault tolerance know it was a failure
- throw
RuntimeExchangeException.wrapRuntimeException(throwable);
- }
- }
-
// fallback route is handling the exception so its short-circuited
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_SUCCESSFUL_EXECUTION,
false);
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_FROM_FALLBACK,
true);
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_SHORT_CIRCUITED,
true);
+ if (exchange.getException() instanceof TimeoutException) {
+
exchange.setProperty(ExchangePropertyKey.CIRCUIT_BREAKER_RESPONSE_TIMED_OUT,
true);
+ }
// store the last to endpoint as the failure endpoint
if (exchange.getProperty(ExchangePropertyKey.FAILURE_ENDPOINT) ==
null) {
diff --git
a/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceReifier.java
b/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceReifier.java
index 10c3fa936261..f7aa9a73f3f0 100644
---
a/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceReifier.java
+++
b/components/camel-microprofile/camel-microprofile-fault-tolerance/src/main/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceReifier.java
@@ -100,6 +100,7 @@ public class FaultToleranceReifier extends
ProcessorReifier<CircuitBreakerDefini
if (!parseBoolean(config.getBulkheadEnabled(), false)) {
return;
}
+ target.setBulkheadEnabled(true);
target.setBulkheadMaxConcurrentCalls(parseInt(config.getBulkheadMaxConcurrentCalls(),
10));
target.setBulkheadWaitingTaskQueue(parseInt(config.getBulkheadWaitingTaskQueue(),
10));
}
diff --git
a/components/camel-microprofile/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceTimeoutExchangePropertyTest.java
b/components/camel-microprofile/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceTimeoutExchangePropertyTest.java
new file mode 100644
index 000000000000..21fcbcacef41
--- /dev/null
+++
b/components/camel-microprofile/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceTimeoutExchangePropertyTest.java
@@ -0,0 +1,64 @@
+/*
+ * 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.component.microprofile.faulttolerance;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.spi.CircuitBreakerConstants;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.test.junit6.TestSupport.assertIsInstanceOf;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotNull;
+
+/**
+ * Tests that the circuit breaker exchange properties are set correctly on
timeout without a fallback.
+ */
+public class FaultToleranceTimeoutExchangePropertyTest extends
CamelTestSupport {
+
+ @Test
+ public void testTimeoutExchangeProperties() {
+ Exchange out = template.send("direct:start", e ->
e.getIn().setBody("Hello World"));
+
+ assertNotNull(out.getException());
+ assertIsInstanceOf(TimeoutException.class, out.getException());
+ assertEquals(false,
out.getProperty(CircuitBreakerConstants.RESPONSE_SUCCESSFUL_EXECUTION));
+ assertEquals(false,
out.getProperty(CircuitBreakerConstants.RESPONSE_FROM_FALLBACK));
+ assertEquals(false,
out.getProperty(CircuitBreakerConstants.RESPONSE_SHORT_CIRCUITED));
+ assertEquals(true,
out.getProperty(CircuitBreakerConstants.RESPONSE_TIMED_OUT));
+ }
+
+ @Override
+ protected RoutesBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct:start")
+ .circuitBreaker()
+
.faultToleranceConfiguration().timeoutEnabled(true).timeoutDuration(2000).end()
+ .to("direct:slow")
+ .end();
+
+ from("direct:slow")
+ .delay(5000).transform().constant("Slow response");
+ }
+ };
+ }
+}
diff --git
a/components/camel-microprofile/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceTimeoutWithFallbackExchangePropertyTest.java
b/components/camel-microprofile/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceTimeoutWithFallbackExchangePropertyTest.java
new file mode 100644
index 000000000000..1b9363772596
--- /dev/null
+++
b/components/camel-microprofile/camel-microprofile-fault-tolerance/src/test/java/org/apache/camel/component/microprofile/faulttolerance/FaultToleranceTimeoutWithFallbackExchangePropertyTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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.component.microprofile.faulttolerance;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.spi.CircuitBreakerConstants;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.eclipse.microprofile.faulttolerance.exceptions.TimeoutException;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.Test;
+
+import static org.apache.camel.test.junit6.TestSupport.assertIsInstanceOf;
+
+/**
+ * Tests that timeout with fallback correctly sets RESPONSE_TIMED_OUT and
makes the guard exception visible to the
+ * fallback via EXCEPTION_CAUGHT.
+ */
+public class FaultToleranceTimeoutWithFallbackExchangePropertyTest extends
CamelTestSupport {
+
+ @Test
+ public void testTimeoutWithFallbackExchangeProperties() throws Exception {
+ getMockEndpoint("mock:result").expectedBodiesReceived("Fallback
response");
+
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_SUCCESSFUL_EXECUTION,
false);
+
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_FROM_FALLBACK,
true);
+
getMockEndpoint("mock:result").expectedPropertyReceived(CircuitBreakerConstants.RESPONSE_TIMED_OUT,
true);
+
+ template.sendBody("direct:start", "Hello World");
+
+ MockEndpoint.assertIsSatisfied(context);
+ }
+
+ @Override
+ protected RoutesBuilder createRouteBuilder() {
+ return new RouteBuilder() {
+ @Override
+ public void configure() {
+ from("direct:start")
+ .circuitBreaker()
+
.faultToleranceConfiguration().timeoutEnabled(true).timeoutDuration(2000).end()
+ .to("direct:slow")
+ .onFallback()
+ .process(e -> {
+ // guard exception must be visible to the fallback
via EXCEPTION_CAUGHT
+ Throwable caught =
e.getProperty(Exchange.EXCEPTION_CAUGHT, Throwable.class);
+ assertIsInstanceOf(TimeoutException.class, caught);
+ Assertions.assertNull(e.getException());
+ })
+ .transform().constant("Fallback response")
+ .end()
+ .to("mock:result");
+
+ from("direct:slow")
+ .delay(5000).transform().constant("Slow response");
+ }
+ };
+ }
+}
diff --git
a/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceConsole.java
b/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceConsole.java
index e9dc6e21b71b..ae0af7cf6590 100644
---
a/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceConsole.java
+++
b/components/camel-resilience4j/src/main/java/org/apache/camel/component/resilience4j/ResilienceConsole.java
@@ -60,12 +60,12 @@ public class ResilienceConsole extends AbstractDevConsole {
int fc = cb.getNumberOfFailedCalls();
long npc = cb.getNumberOfNotPermittedCalls();
float fr = cb.getFailureRate();
- if (fr > 0) {
+ if (fr >= 0) {
sb.append(String.format(" %s/%s: %s (buffered: %d success:
%d failure: %d/%.0f%% not-permitted: %d)%n", rid,
id, state, bc, sc, fc, fr, npc));
} else {
- sb.append(String.format(" %s/%s: %s (buffered: %d success:
%d failure: 0 not-permitted: %d)%n", rid, id,
- state, bc, sc, npc));
+ sb.append(String.format(" %s/%s: %s (buffered: %d success:
%d failure: %d not-permitted: %d)%n", rid, id,
+ state, bc, sc, fc, npc));
}
}
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 0e5a8b929212..3293361bc040 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
@@ -315,7 +315,7 @@ public class ResilienceProcessor extends
BaseProcessorSupport
@ManagedAttribute(description = "Returns the current number of successful
calls which were slower than a certain threshold.")
public int getNumberOfSlowSuccessfulCalls() {
if (circuitBreaker != null) {
- return circuitBreaker.getMetrics().getNumberOfSlowCalls();
+ return
circuitBreaker.getMetrics().getNumberOfSlowSuccessfulCalls();
} else {
return 0;
}
diff --git
a/core/camel-core-engine/src/main/docs/modules/eips/pages/circuitBreaker-eip.adoc
b/core/camel-core-engine/src/main/docs/modules/eips/pages/circuitBreaker-eip.adoc
index 9ca7d860ba2a..209bc0015759 100644
---
a/core/camel-core-engine/src/main/docs/modules/eips/pages/circuitBreaker-eip.adoc
+++
b/core/camel-core-engine/src/main/docs/modules/eips/pages/circuitBreaker-eip.adoc
@@ -39,7 +39,7 @@ include::partial$eip-exchangeProperties.adoc[]
Below is an example route showing a circuit breaker 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.
+In this example, the circuit breaker protects against slow operation by
falling back to the in-lined fallback route.
[tabs]
====
@@ -97,6 +97,12 @@ YAML::
----
====
+== Route lifecycle and breaker state
+
+When a route is stopped and started, the circuit breaker state is reset (an
OPEN breaker returns to CLOSED)
+and any collected metrics are cleared. This is by design — a route stop/start
is a full lifecycle reset,
+equivalent to a fresh boot.
+
== Circuit Breaker components
Camel provides two implementations of this pattern:
diff --git
a/core/camel-core-engine/src/main/docs/modules/eips/pages/fault-tolerance-eip.adoc
b/core/camel-core-engine/src/main/docs/modules/eips/pages/fault-tolerance-eip.adoc
index 27eb542f4ec3..6e17e527c5a4 100644
---
a/core/camel-core-engine/src/main/docs/modules/eips/pages/fault-tolerance-eip.adoc
+++
b/core/camel-core-engine/src/main/docs/modules/eips/pages/fault-tolerance-eip.adoc
@@ -12,7 +12,7 @@ The Fault Tolerance EIP supports two options which are listed
below:
|===
| Name | Description | Default | Type
| *faultToleranceConfiguration* | Configure the Fault Tolerance EIP. When the
configuration is complete, use `end()` to return to the Fault Tolerance EIP. |
| `FaultToleranceConfigurationDefinition`
-| *faultToleranceConfigurationRef* | Refers to a Fault Tolerance configuration
to use for configuring the Fault Tolerance EIP. | | String
+| *configuration* | Refers to a Fault Tolerance configuration (by name) to use
for configuring the Fault Tolerance EIP. | | String
|===
See xref:faultToleranceConfiguration-eip.adoc[Fault Tolerance Configuration]
for all the configuration options
@@ -66,14 +66,14 @@ YAML::
steps:
- circuitBreaker:
steps:
+ - to:
+ uri: http://fooservice.com/faulty
- onFallback:
steps:
- transform:
expression:
constant:
expression: Fallback message
- - to:
- uri: http://fooservice.com/faulty
- to:
uri: mock:result
----
@@ -82,7 +82,9 @@ YAML::
In case the calling the downstream HTTP service is failing, and an exception
is thrown,
then the circuit breaker will react and execute the fallback route instead.
-If there was no fallback, then the circuit breaker will throw an exception.
+If there is no fallback and the protected processor fails, the circuit breaker
will throw an exception.
+However, when the circuit breaker is open and rejects a call, the message
continues routing unchanged
+(no exception is thrown).
TIP: For more information about fallback, see
xref:onFallback-eip.adoc[onFallback].
@@ -253,6 +255,13 @@ Maven users will need to add the following dependency to
their pom.xml to use th
</dependency>
----
+=== Developer Console
+
+The Fault Tolerance dev console (`fault-tolerance`) displays the circuit
breaker state (CLOSED, OPEN, HALF_OPEN)
+for each breaker in the context. Unlike the Resilience4j dev console, it does
not show live metrics
+(success/failure counts, failure rate) because the underlying SmallRye Fault
Tolerance API does not expose
+per-breaker metric counters.
+
=== Using Fault Tolerance with Spring Boot
This component is **not supported** Spring Boot.
diff --git
a/core/camel-core-engine/src/main/docs/modules/eips/pages/resilience4j-eip.adoc
b/core/camel-core-engine/src/main/docs/modules/eips/pages/resilience4j-eip.adoc
index 0186e386d71a..aa84fc1eb53c 100644
---
a/core/camel-core-engine/src/main/docs/modules/eips/pages/resilience4j-eip.adoc
+++
b/core/camel-core-engine/src/main/docs/modules/eips/pages/resilience4j-eip.adoc
@@ -11,8 +11,8 @@ The Resilience4j EIP supports two options which are listed
below:
[width="100%",cols="2,5,^1,2",options="header"]
|===
| Name | Description | Default | Type
-| *resilienceConfiguration* | Configure the Resilience EIP. When the
configuration is complete, use `end()` to return to the Resilience EIP. | |
Resilience4jConfigurationDefinition
-| *resilienceConfigurationRef* | Refers to a Resilience configuration to use
for configuring the Resilience EIP. | | String
+| *resilience4jConfiguration* | Configure the Resilience EIP. When the
configuration is complete, use `end()` to return to the Resilience EIP. | |
Resilience4jConfigurationDefinition
+| *configuration* | Refers to a Resilience configuration (by name) to use for
configuring the Resilience EIP. | | String
|===
NOTE: See xref:resilience4jConfiguration-eip.adoc[Resilience4j Configuration]
for all the configuration options
@@ -82,7 +82,9 @@ YAML::
In case the calling the downstream HTTP service is failing, and an exception
is thrown,
then the circuit breaker will react and execute the fallback route instead.
-If there was no fallback, then the circuit breaker will throw an exception.
+If there is no fallback and the protected processor fails, the circuit breaker
will throw an exception.
+However, when the circuit breaker is open and rejects a call, the message
continues routing unchanged
+(no exception is thrown) unless `throwExceptionWhenHalfOpenOrOpenState` is
enabled.
TIP: For more information about fallback, see
xref:onFallback-eip.adoc[onFallback].
diff --git
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/faultToleranceConfiguration.json
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/faultToleranceConfiguration.json
index 3b049f5d7448..2b2bbbd57eb3 100644
---
a/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/faultToleranceConfiguration.json
+++
b/core/camel-core-model/src/generated/resources/META-INF/org/apache/camel/model/faultToleranceConfiguration.json
@@ -20,7 +20,7 @@
"failureRatio": { "index": 5, "kind": "attribute", "displayName": "Failure
Ratio", "group": "common", "required": false, "type": "integer", "javaType":
"java.lang.Integer", "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." },
"timeoutEnabled": { "index": 6, "kind": "attribute", "displayName":
"Timeout Enabled", "group": "common", "required": false, "type": "boolean",
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "description": "Whether timeout is
enabled or not on the circuit breaker." },
"timeoutDuration": { "index": 7, "kind": "attribute", "displayName":
"Timeout Duration", "group": "common", "required": false, "type": "duration",
"javaType": "java.lang.String", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": "1000", "description": "Configures the thread
execution timeout. Default value is 1 second." },
- "timeoutPoolSize": { "index": 8, "kind": "attribute", "displayName":
"Timeout Pool Size", "group": "advanced", "label": "advanced", "required":
false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false,
"autowired": false, "secret": false, "defaultValue": 10, "description":
"Configures the pool size of the thread pool when timeout is enabled." },
+ "timeoutPoolSize": { "index": 8, "kind": "attribute", "displayName":
"Timeout Pool Size", "group": "advanced", "label": "advanced", "required":
false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": true,
"deprecationNote": "No longer in use", "autowired": false, "secret": false,
"defaultValue": 10, "description": "Deprecated: no longer in use since the
switch to TypedGuard API (CAMEL-21857)." },
"bulkheadEnabled": { "index": 9, "kind": "attribute", "displayName":
"Bulkhead Enabled", "group": "common", "required": false, "type": "boolean",
"javaType": "java.lang.Boolean", "deprecated": false, "autowired": false,
"secret": false, "defaultValue": false, "description": "Whether bulkhead is
enabled or not on the circuit breaker." },
"bulkheadMaxConcurrentCalls": { "index": 10, "kind": "attribute",
"displayName": "Bulkhead Max Concurrent Calls", "group": "advanced", "label":
"advanced", "required": false, "type": "integer", "javaType":
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": 10, "description": "Configures the max amount of concurrent
calls the bulkhead will support." },
"bulkheadWaitingTaskQueue": { "index": 11, "kind": "attribute",
"displayName": "Bulkhead Waiting Task Queue", "group": "advanced", "label":
"advanced", "required": false, "type": "integer", "javaType":
"java.lang.Integer", "deprecated": false, "autowired": false, "secret": false,
"defaultValue": 10, "description": "Configures the task queue size for holding
waiting tasks to be processed by the bulkhead." },
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/FaultToleranceConfigurationCommon.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/FaultToleranceConfigurationCommon.java
index 716561a44b4b..aba2576a014b 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/model/FaultToleranceConfigurationCommon.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/model/FaultToleranceConfigurationCommon.java
@@ -57,7 +57,9 @@ public class FaultToleranceConfigurationCommon extends
IdentifiedType {
private String timeoutDuration;
@XmlAttribute
@Metadata(label = "advanced", defaultValue = "10", javaType =
"java.lang.Integer",
- description = "Configures the pool size of the thread pool when
timeout is enabled.")
+ description = "Deprecated: no longer in use since the switch to
TypedGuard API (CAMEL-21857).",
+ deprecationNote = "No longer in use")
+ @Deprecated(since = "4.22.0")
private String timeoutPoolSize;
@XmlAttribute
@Metadata(defaultValue = "false", javaType = "java.lang.Boolean",
@@ -156,10 +158,12 @@ public class FaultToleranceConfigurationCommon extends
IdentifiedType {
this.timeoutDuration = timeoutDuration;
}
+ @Deprecated(since = "4.22.0")
public String getTimeoutPoolSize() {
return timeoutPoolSize;
}
+ @Deprecated(since = "4.22.0")
public void setTimeoutPoolSize(String timeoutPoolSize) {
this.timeoutPoolSize = timeoutPoolSize;
}
diff --git
a/core/camel-core-model/src/main/java/org/apache/camel/model/FaultToleranceConfigurationDefinition.java
b/core/camel-core-model/src/main/java/org/apache/camel/model/FaultToleranceConfigurationDefinition.java
index 568c2ecf33b0..8abfba6f2c91 100644
---
a/core/camel-core-model/src/main/java/org/apache/camel/model/FaultToleranceConfigurationDefinition.java
+++
b/core/camel-core-model/src/main/java/org/apache/camel/model/FaultToleranceConfigurationDefinition.java
@@ -166,16 +166,18 @@ public class FaultToleranceConfigurationDefinition
extends FaultToleranceConfigu
}
/**
- * Configures the pool size of the thread pool when timeout is enabled.
Default value is 10.
+ * @deprecated No longer in use since the switch to TypedGuard API
(CAMEL-21857).
*/
+ @Deprecated(since = "4.22.0")
public FaultToleranceConfigurationDefinition timeoutPoolSize(int poolSize)
{
setTimeoutPoolSize(Integer.toString(poolSize));
return this;
}
/**
- * Configures the pool size of the thread pool when timeout is enabled.
Supports property placeholders.
+ * @deprecated No longer in use since the switch to TypedGuard API
(CAMEL-21857).
*/
+ @Deprecated(since = "4.22.0")
public FaultToleranceConfigurationDefinition timeoutPoolSize(String
poolSize) {
setTimeoutPoolSize(poolSize);
return this;
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
index 49e692108309..bd73dd58e608 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl-deserializers/src/generated/java/org/apache/camel/dsl/yaml/deserializers/ModelDeserializers.java
@@ -5299,7 +5299,7 @@ public final class ModelDeserializers extends
YamlDeserializerSupport {
@YamlProperty(name = "threadOffloadExecutorService", type
= "string", description = "References a custom thread pool to use when
offloading a guarded action to another thread.", displayName = "Thread Offload
Executor Service"),
@YamlProperty(name = "timeoutDuration", type = "string",
defaultValue = "1000", description = "Configures the thread execution timeout.
Default value is 1 second.", displayName = "Timeout Duration"),
@YamlProperty(name = "timeoutEnabled", type = "boolean",
defaultValue = "false", description = "Whether timeout is enabled or not on the
circuit breaker.", displayName = "Timeout Enabled"),
- @YamlProperty(name = "timeoutPoolSize", type = "number",
defaultValue = "10", description = "Configures the pool size of the thread pool
when timeout is enabled.", displayName = "Timeout Pool Size"),
+ @YamlProperty(name = "timeoutPoolSize", type = "number",
deprecated = true, defaultValue = "10", description = "Deprecated: no longer in
use since the switch to TypedGuard API (CAMEL-21857).", displayName = "Timeout
Pool Size"),
@YamlProperty(name = "typedGuard", type = "string",
description = "Refers to an existing io.smallrye.faulttolerance.api.TypedGuard
instance to lookup and use from the registry. When using this, then any other
TypedGuard circuit breaker options are not in use.", displayName = "Typed
Guard")
}
)
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
index 5d39e4465d8b..a35878691db2 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl-canonical.json
@@ -1472,7 +1472,8 @@
"timeoutPoolSize" : {
"type" : "number",
"title" : "Timeout Pool Size",
- "description" : "Configures the pool size of the thread pool when
timeout is enabled.",
+ "description" : "Deprecated: no longer in use since the switch to
TypedGuard API (CAMEL-21857).",
+ "deprecated" : true,
"default" : 10
},
"typedGuard" : {
diff --git
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
index 291c8c66db81..fc9d04490428 100644
---
a/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
+++
b/dsl/camel-yaml-dsl/camel-yaml-dsl/src/generated/resources/schema/camelYamlDsl.json
@@ -2090,7 +2090,8 @@
"timeoutPoolSize" : {
"type" : "number",
"title" : "Timeout Pool Size",
- "description" : "Configures the pool size of the thread pool when
timeout is enabled.",
+ "description" : "Deprecated: no longer in use since the switch to
TypedGuard API (CAMEL-21857).",
+ "deprecated" : true,
"default" : 10
},
"typedGuard" : {