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 3dcc374d3e34 CAMEL-26785: camel-management - the steps of a circuit 
breaker's onFallback are processors of the route (#29490)
3dcc374d3e34 is described below

commit 3dcc374d3e347138de032a35d4e55017e0c8e40a
Author: Claus Ibsen <[email protected]>
AuthorDate: Mon Nov 9 22:46:52 2026 +0100

    CAMEL-26785: camel-management - the steps of a circuit breaker's onFallback 
are processors of the route (#29490)
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
---
 .../ResilienceFallbackManagementTest.java          | 86 ++++++++++++++++++++++
 .../management/JmxManagementLifecycleStrategy.java |  9 +++
 2 files changed, 95 insertions(+)

diff --git 
a/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceFallbackManagementTest.java
 
b/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceFallbackManagementTest.java
new file mode 100644
index 000000000000..8dbdc812d353
--- /dev/null
+++ 
b/components/camel-resilience4j/src/test/java/org/apache/camel/component/resilience4j/ResilienceFallbackManagementTest.java
@@ -0,0 +1,86 @@
+/*
+ * 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.resilience4j;
+
+import java.net.ConnectException;
+import java.util.List;
+
+import org.apache.camel.api.management.ManagedCamelContext;
+import org.apache.camel.api.management.mbean.ManagedProcessorMBean;
+import org.apache.camel.api.management.mbean.ManagedRouteMBean;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.component.mock.MockEndpoint;
+import org.apache.camel.test.junit6.CamelTestSupport;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+/**
+ * The steps of the fallback are processors of the route, with their own 
statistics: they are the ones that run while
+ * the protected service is down.
+ */
+public class ResilienceFallbackManagementTest extends CamelTestSupport {
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    @Test
+    public void testTheFallbackStepsAreProcessorsOfTheRoute() throws Exception 
{
+        getMockEndpoint("mock:result").expectedBodiesReceived("from the 
fallback", "from the fallback");
+
+        template.sendBody("direct:check", "CAMEL-MUG");
+        template.sendBody("direct:check", "CAMEL-MUG");
+
+        MockEndpoint.assertIsSatisfied(context);
+
+        ManagedCamelContext mcc = 
context.getCamelContextExtension().getContextPlugin(ManagedCamelContext.class);
+        ManagedRouteMBean route = mcc.getManagedRoute("check");
+        assertTrue(route.processorIds().containsAll(List.of("supplier", 
"fallbackChoice", "fallbackBody", "otherBody")),
+                "the processors of the route: " + route.processorIds());
+
+        ManagedProcessorMBean body = mcc.getManagedProcessor("fallbackBody");
+        assertEquals("check", body.getRouteId());
+        assertEquals(2, body.getExchangesTotal());
+        assertEquals(2, 
mcc.getManagedProcessor("fallbackChoice").getExchangesTotal());
+        // the otherwise branch did not run
+        assertEquals(0, 
mcc.getManagedProcessor("otherBody").getExchangesTotal());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("direct:check").routeId("check")
+                        .circuitBreaker().id("breaker")
+                            .throwException(new ConnectException("supplier 
unreachable")).id("supplier")
+                        .onFallback()
+                            .choice().id("fallbackChoice")
+                                .when(body().isEqualTo("CAMEL-MUG"))
+                                    .setBody(constant("from the 
fallback")).id("fallbackBody")
+                                .otherwise()
+                                    
.setBody(constant("otherwise")).id("otherBody")
+                            .end()
+                        .end()
+                        .to("mock:result");
+            }
+        };
+    }
+}
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementLifecycleStrategy.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementLifecycleStrategy.java
index 6cea6d06718a..0ffdd7c879b6 100644
--- 
a/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementLifecycleStrategy.java
+++ 
b/core/camel-management/src/main/java/org/apache/camel/management/JmxManagementLifecycleStrategy.java
@@ -89,6 +89,7 @@ import 
org.apache.camel.management.mbean.ManagedTransformerRegistry;
 import org.apache.camel.management.mbean.ManagedTypeConverterRegistry;
 import org.apache.camel.management.mbean.ManagedValidatorRegistry;
 import org.apache.camel.management.mbean.ManagedVariableRepository;
+import org.apache.camel.model.CircuitBreakerDefinition;
 import org.apache.camel.model.InterceptDefinition;
 import org.apache.camel.model.OnCompletionDefinition;
 import org.apache.camel.model.OnExceptionDefinition;
@@ -1162,6 +1163,14 @@ public class JmxManagementLifecycleStrategy extends 
ServiceSupport implements Li
             }
         }
 
+        // The steps of a circuit breaker's fallback are not among its 
outputs, but they are steps of the route: the
+        // ones that run while the protected service is down.
+        if (processor instanceof CircuitBreakerDefinition cb && 
cb.getOnFallback() != null) {
+            for (ProcessorDefinition<?> child : 
cb.getOnFallback().getOutputs()) {
+                registerPerformanceCounters(route, child, registeredCounters);
+            }
+        }
+
         // skip processors that should not be registered
         if (!registerProcessor(processor)) {
             return;

Reply via email to