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 8318ebaa3b4 CAMEL-18858: camel-core - Mark route as created by Kamelet 
so we know this, so we can filter out in tooling and whereelse (kamelet is a 
blackbox) (#13286)
8318ebaa3b4 is described below

commit 8318ebaa3b48c921ef217013487f1d01dcf4306f
Author: Claus Ibsen <claus.ib...@gmail.com>
AuthorDate: Sun Feb 25 08:59:29 2024 +0100

    CAMEL-18858: camel-core - Mark route as created by Kamelet so we know this, 
so we can filter out in tooling and whereelse (kamelet is a blackbox) (#13286)
    
    CAMEL-18858: camel-core - Mark route as created by Kamelet so we know this, 
so we can filter out in tooling and whereelse (kamelet is a blackbox)
---
 .../main/camel-main-configuration-metadata.json    |   2 +
 .../apache/camel/catalog/schemas/camel-spring.xsd  |   1 +
 components/camel-kamelet/pom.xml                   |   5 +
 .../apache/camel/component/kamelet/Kamelet.java    |   2 +
 .../camel/component/kamelet/KameletProcessor.java  |   3 +
 .../camel/component/kamelet/KameletProducer.java   |  14 ++-
 .../kamelet/ManagedKameletRouteDisabledTest.java   |  87 ++++++++++++++
 .../kamelet/ManagedKameletRouteEnabledTest.java    |  93 +++++++++++++++
 .../metrics/routepolicy/MetricsRoutePolicy.java    |  24 +++-
 .../MicrometerExchangeEventNotifier.java           |  45 ++++++--
 .../MicrometerRouteEventNotifier.java              |  20 ++++
 .../routepolicy/MicrometerRoutePolicy.java         |  19 ++-
 .../src/main/java/org/apache/camel/Route.java      |  16 +++
 .../java/org/apache/camel/spi/ManagementAgent.java |  28 +++++
 .../main/java/org/apache/camel/spi/UnitOfWork.java |  15 +++
 .../camel/impl/engine/AbstractCamelContext.java    | 127 ++++++++++++++++++---
 .../org/apache/camel/impl/engine/DefaultRoute.java |  15 +++
 .../camel/impl/engine/DefaultUnitOfWork.java       |  22 ++++
 .../camel/impl/console/ConsumerDevConsole.java     |   2 +-
 .../apache/camel/impl/console/RouteDevConsole.java |   5 +-
 .../camel/impl/console/RouteDumpDevConsole.java    |   2 +
 .../camel/impl/console/SourceDevConsole.java       |   2 +
 .../apache/camel/impl/console/TopDevConsole.java   |   3 +
 .../org/apache/camel/model/RouteDefinition.java    |  16 ++-
 .../org/apache/camel/processor/SendProcessor.java  |   3 +
 .../org/apache/camel/reifier/RouteReifier.java     |   2 +
 .../MainConfigurationPropertiesConfigurer.java     |  12 ++
 .../camel-main-configuration-metadata.json         |   2 +
 core/camel-main/src/main/docs/main.adoc            |   4 +-
 .../camel/main/DefaultConfigurationConfigurer.java |   4 +
 .../camel/main/DefaultConfigurationProperties.java |  66 +++++++++++
 .../api/management/JmxSystemPropertyKeys.java      |   6 +
 .../api/management/mbean/ManagedRouteMBean.java    |   6 +
 .../camel/management/DefaultManagementAgent.java   |  26 +++++
 .../management/JmxManagementLifecycleStrategy.java |   9 ++
 .../management/mbean/ManagedCamelContext.java      |  21 ++--
 .../camel/management/mbean/ManagedRoute.java       |  10 ++
 .../java/org/apache/camel/xml/in/ModelParser.java  |   1 +
 .../java/org/apache/camel/xml/out/ModelWriter.java |   1 +
 .../org/apache/camel/yaml/out/ModelWriter.java     |   1 +
 .../ROOT/pages/camel-4x-upgrade-guide-4_5.adoc     |  21 ++++
 docs/user-manual/modules/ROOT/pages/jmx.adoc       |  15 ++-
 42 files changed, 726 insertions(+), 52 deletions(-)

diff --git 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
index 127e310a2c6..f1e51f670bf 100644
--- 
a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
+++ 
b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/main/camel-main-configuration-metadata.json
@@ -70,6 +70,8 @@
     { "name": "camel.main.jmxEnabled", "description": "Enable JMX in your 
Camel application.", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": true },
     { "name": "camel.main.jmxManagementMBeansLevel", "description": "Sets the 
mbeans registration level. The default value is Default.", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "object", 
"javaType": "org.apache.camel.ManagementMBeansLevel", "defaultValue": "Default" 
},
     { "name": "camel.main.jmxManagementNamePattern", "description": "The 
naming pattern for creating the CamelContext JMX management name. The default 
pattern is #name#", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "defaultValue": "#name#" },
+    { "name": "camel.main.jmxManagementRegisterRoutesCreateByKamelet", 
"description": "Whether routes created by Kamelets should be registered for JMX 
management. Enabling this allows to have fine-grained monitoring and management 
of every route created via Kamelets. This is default disabled as a Kamelet is 
intended as a component (black-box) and its implementation details as Camel 
route makes the overall management and monitoring of Camel applications more 
verbose. During development of [...]
+    { "name": "camel.main.jmxManagementRegisterRoutesCreateByTemplate", 
"description": "Whether routes created by route templates (not Kamelets) should 
be registered for JMX management. Enabling this allows to have fine-grained 
monitoring and management of every route created via route templates. This is 
default enabled (unlike Kamelets) as routes created via templates is regarded 
as standard routes, and should be available for management and monitoring.", 
"sourceType": "org.apache.camel [...]
     { "name": "camel.main.jmxManagementStatisticsLevel", "description": "Sets 
the JMX statistics level, the level can be set to Extended to gather additional 
information The default value is Default.", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "object", 
"javaType": "org.apache.camel.ManagementStatisticsLevel", "defaultValue": 
"Default", "enum": [ "Extended", "Default", "RoutesOnly", "Off" ] },
     { "name": "camel.main.jmxUpdateRouteEnabled", "description": "Whether to 
allow updating routes at runtime via JMX using the ManagedRouteMBean. This is 
disabled by default, but can be enabled for development and troubleshooting 
purposes, such as updating routes in an existing running Camel via JMX and 
other tools.", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.lightweight", "description": "Configure the context 
to be lightweight. This will trigger some optimizations and memory reduction 
options. Lightweight context have some limitations. At this moment, dynamic 
endpoint destinations are not supported.", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": "false" },
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 bdf7a264bea..87b01646d3f 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
@@ -12258,6 +12258,7 @@ XML. May be null.
             </xs:documentation>
           </xs:annotation>
         </xs:attribute>
+        <xs:attribute name="kamelet" type="xs:boolean"/>
         <xs:attribute name="logMask" type="xs:string">
           <xs:annotation>
             <xs:documentation xml:lang="en">
diff --git a/components/camel-kamelet/pom.xml b/components/camel-kamelet/pom.xml
index 1fdb9f82918..57b70f9155a 100644
--- a/components/camel-kamelet/pom.xml
+++ b/components/camel-kamelet/pom.xml
@@ -44,6 +44,11 @@
         </dependency>
 
         <!-- TESTS  -->
+        <dependency>
+            <groupId>org.apache.camel</groupId>
+            <artifactId>camel-management</artifactId>
+            <scope>test</scope>
+        </dependency>
         <dependency>
             <groupId>org.apache.camel</groupId>
             <artifactId>camel-xml-jaxb</artifactId>
diff --git 
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/Kamelet.java
 
b/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/Kamelet.java
index bda62f27103..3db8c6f8250 100644
--- 
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/Kamelet.java
+++ 
b/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/Kamelet.java
@@ -130,6 +130,8 @@ public final class Kamelet {
         ObjectHelper.notNull(rid, PARAM_ROUTE_ID);
 
         RouteDefinition def = in.asRouteDefinition();
+        // mark this as created from a kamelet
+        def.setKamelet(true);
         def.setLocation(in.getLocation());
         def.setLineNumber(in.getLineNumber());
         def.setId(rid);
diff --git 
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletProcessor.java
 
b/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletProcessor.java
index be684473f55..9bfab346d8f 100644
--- 
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletProcessor.java
+++ 
b/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletProcessor.java
@@ -123,6 +123,9 @@ public class KameletProcessor extends AsyncProcessorSupport
         if (producer == null) {
             producer = (KameletProducer) camelContext.getEndpoint("kamelet://" 
+ name).createAsyncProducer();
         }
+        if (producer != null) {
+            ((RouteIdAware) producer).setRouteId(getRouteId());
+        }
         ServiceHelper.buildService(processor, producer);
 
         // we use the kamelet component (producer) to call the kamelet
diff --git 
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletProducer.java
 
b/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletProducer.java
index cc05702c5e8..1e2d2960647 100644
--- 
a/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletProducer.java
+++ 
b/components/camel-kamelet/src/main/java/org/apache/camel/component/kamelet/KameletProducer.java
@@ -20,12 +20,13 @@ import org.apache.camel.AsyncCallback;
 import org.apache.camel.AsyncProcessor;
 import org.apache.camel.Exchange;
 import org.apache.camel.Route;
+import org.apache.camel.spi.RouteIdAware;
 import org.apache.camel.support.DefaultAsyncProducer;
 import org.apache.camel.support.ExchangeHelper;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-final class KameletProducer extends DefaultAsyncProducer {
+final class KameletProducer extends DefaultAsyncProducer implements 
RouteIdAware {
 
     private static final Logger LOG = 
LoggerFactory.getLogger(KameletProducer.class);
 
@@ -38,6 +39,7 @@ final class KameletProducer extends DefaultAsyncProducer {
     private final boolean block;
     private final long timeout;
     private final boolean sink;
+    private String routeId;
 
     public KameletProducer(KameletEndpoint endpoint, String key) {
         super(endpoint);
@@ -124,6 +126,16 @@ final class KameletProducer extends DefaultAsyncProducer {
         }
     }
 
+    @Override
+    public String getRouteId() {
+        return routeId;
+    }
+
+    @Override
+    public void setRouteId(String routeId) {
+        this.routeId = routeId;
+    }
+
     public String getKey() {
         return key;
     }
diff --git 
a/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/ManagedKameletRouteDisabledTest.java
 
b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/ManagedKameletRouteDisabledTest.java
new file mode 100644
index 00000000000..bfa26bd1990
--- /dev/null
+++ 
b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/ManagedKameletRouteDisabledTest.java
@@ -0,0 +1,87 @@
+/*
+ * 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.kamelet;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.camel.util.StringHelper;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class ManagedKameletRouteDisabledTest extends CamelTestSupport {
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    protected MBeanServer getMBeanServer() {
+        return 
context.getManagementStrategy().getManagementAgent().getMBeanServer();
+    }
+
+    @Test
+    public void testKameletRouteMBeanDisabled() throws Exception {
+        String body = UUID.randomUUID().toString();
+
+        assertThat(
+                
fluentTemplate.toF("direct:single").withBody(body).request(String.class)).isEqualTo("a-"
 + body);
+
+        MBeanServer mbeanServer = getMBeanServer();
+
+        Set<ObjectName> set = mbeanServer.queryNames(new 
ObjectName("*:type=routes,*"), null);
+        assertEquals(1, set.size());
+
+        Set<String> ids = new HashSet<>();
+        for (ObjectName on : set) {
+            String uri = (String) mbeanServer.getAttribute(on, "EndpointUri");
+            String name = StringHelper.before(uri, ":");
+            ids.add(name);
+        }
+        assertTrue(ids.contains("direct"));
+        // is disabled by default
+        assertFalse(ids.contains("kamelet"));
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                routeTemplate("echo")
+                        .templateParameter("prefix")
+                        .from("kamelet:source")
+                        .setBody().simple("{{prefix}}-${body}");
+
+                from("direct:single").routeId("test")
+                        .to("kamelet:echo?prefix=a")
+                        .log("${body}");
+            }
+        };
+    }
+}
diff --git 
a/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/ManagedKameletRouteEnabledTest.java
 
b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/ManagedKameletRouteEnabledTest.java
new file mode 100644
index 00000000000..81df1c2d597
--- /dev/null
+++ 
b/components/camel-kamelet/src/test/java/org/apache/camel/component/kamelet/ManagedKameletRouteEnabledTest.java
@@ -0,0 +1,93 @@
+/*
+ * 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.kamelet;
+
+import java.util.HashSet;
+import java.util.Set;
+import java.util.UUID;
+
+import javax.management.MBeanServer;
+import javax.management.ObjectName;
+
+import org.apache.camel.CamelContext;
+import org.apache.camel.RoutesBuilder;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.test.junit5.CamelTestSupport;
+import org.apache.camel.util.StringHelper;
+import org.junit.jupiter.api.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class ManagedKameletRouteEnabledTest extends CamelTestSupport {
+
+    @Override
+    protected boolean useJmx() {
+        return true;
+    }
+
+    protected MBeanServer getMBeanServer() {
+        return 
context.getManagementStrategy().getManagementAgent().getMBeanServer();
+    }
+
+    @Override
+    protected CamelContext createCamelContext() throws Exception {
+        CamelContext context = super.createCamelContext();
+        
context.getManagementStrategy().getManagementAgent().setRegisterRoutesCreateByKamelet(true);
+        return context;
+    }
+
+    @Test
+    public void testKameletRouteMBean() throws Exception {
+        String body = UUID.randomUUID().toString();
+
+        assertThat(
+                
fluentTemplate.toF("direct:single").withBody(body).request(String.class)).isEqualTo("a-"
 + body);
+
+        MBeanServer mbeanServer = getMBeanServer();
+
+        Set<ObjectName> set = mbeanServer.queryNames(new 
ObjectName("*:type=routes,*"), null);
+        assertEquals(2, set.size());
+
+        Set<String> ids = new HashSet<>();
+        for (ObjectName on : set) {
+            String uri = (String) mbeanServer.getAttribute(on, "EndpointUri");
+            String name = StringHelper.before(uri, ":");
+            ids.add(name);
+        }
+        assertTrue(ids.contains("direct"));
+        assertTrue(ids.contains("kamelet"));
+    }
+
+    @Override
+    protected RoutesBuilder createRouteBuilder() throws Exception {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                routeTemplate("echo")
+                        .templateParameter("prefix")
+                        .from("kamelet:source")
+                        .setBody().simple("{{prefix}}-${body}");
+
+                from("direct:single").routeId("test")
+                        .to("kamelet:echo?prefix=a")
+                        .log("${body}");
+            }
+        };
+    }
+}
diff --git 
a/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/routepolicy/MetricsRoutePolicy.java
 
b/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/routepolicy/MetricsRoutePolicy.java
index f278fba42c9..17cacae8441 100644
--- 
a/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/routepolicy/MetricsRoutePolicy.java
+++ 
b/components/camel-metrics/src/main/java/org/apache/camel/component/metrics/routepolicy/MetricsRoutePolicy.java
@@ -26,6 +26,7 @@ import org.apache.camel.Exchange;
 import org.apache.camel.NonManagedService;
 import org.apache.camel.Route;
 import org.apache.camel.RuntimeCamelException;
+import org.apache.camel.spi.ManagementStrategy;
 import org.apache.camel.support.RoutePolicySupport;
 
 /**
@@ -50,6 +51,8 @@ public class MetricsRoutePolicy extends RoutePolicySupport 
implements NonManaged
     private MetricsStatistics statistics;
     private Route route;
     private String namePattern = String.format("%s.%s.%s", NAME_TOKEN, 
ROUTE_ID_TOKEN, TYPE_TOKEN);
+    boolean registerKamelets;
+    boolean registerTemplates = true;
 
     private static final class MetricsStatistics {
         private final String routeId;
@@ -139,6 +142,12 @@ public class MetricsRoutePolicy extends RoutePolicySupport 
implements NonManaged
     public void onInit(Route route) {
         super.onInit(route);
 
+        ManagementStrategy ms = 
route.getCamelContext().getManagementStrategy();
+        if (ms != null && ms.getManagementAgent() != null) {
+            registerKamelets = 
ms.getManagementAgent().getRegisterRoutesCreateByKamelet();
+            registerTemplates = 
ms.getManagementAgent().getRegisterRoutesCreateByTemplate();
+        }
+
         this.route = route;
         try {
             registryService = 
route.getCamelContext().hasService(MetricsRegistryService.class);
@@ -156,11 +165,16 @@ public class MetricsRoutePolicy extends 
RoutePolicySupport implements NonManaged
             throw RuntimeCamelException.wrapRuntimeCamelException(e);
         }
 
-        // create statistics holder
-        // for know we record only all the timings of a complete exchange 
(responses)
-        // we have in-flight / total statistics already from camel-core
-        Timer responses = 
registryService.getMetricsRegistry().timer(createName("responses"));
-        statistics = new MetricsStatistics(route, responses);
+        // skip routes that should not be included
+        boolean skip = (route.isCreatedByKamelet() && !registerKamelets)
+                || (route.isCreatedByRouteTemplate() && !registerTemplates);
+        if (!skip) {
+            // create statistics holder
+            // for know we record only all the timings of a complete exchange 
(responses)
+            // we have in-flight / total statistics already from camel-core
+            Timer responses = 
registryService.getMetricsRegistry().timer(createName("responses"));
+            statistics = new MetricsStatistics(route, responses);
+        }
     }
 
     private String createName(String type) {
diff --git 
a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifier.java
 
b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifier.java
index 61ce90e9526..8dbac32b26f 100644
--- 
a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifier.java
+++ 
b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerExchangeEventNotifier.java
@@ -26,6 +26,7 @@ import io.micrometer.core.instrument.Meter;
 import io.micrometer.core.instrument.Tags;
 import io.micrometer.core.instrument.Timer;
 import org.apache.camel.Exchange;
+import org.apache.camel.Route;
 import org.apache.camel.spi.CamelEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeCompletedEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeCreatedEvent;
@@ -33,6 +34,8 @@ import org.apache.camel.spi.CamelEvent.ExchangeEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeFailedEvent;
 import org.apache.camel.spi.CamelEvent.ExchangeSentEvent;
 import org.apache.camel.spi.InflightRepository;
+import org.apache.camel.spi.ManagementStrategy;
+import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.support.SimpleEventNotifierSupport;
 
 public class MicrometerExchangeEventNotifier extends 
AbstractMicrometerEventNotifier<ExchangeEvent> {
@@ -42,6 +45,8 @@ public class MicrometerExchangeEventNotifier extends 
AbstractMicrometerEventNoti
     private Predicate<Exchange> ignoreExchanges = exchange -> false;
     private MicrometerExchangeEventNotifierNamingStrategy namingStrategy
             = MicrometerExchangeEventNotifierNamingStrategy.DEFAULT;
+    boolean registerKamelets;
+    boolean registerTemplates = true;
 
     public MicrometerExchangeEventNotifier() {
         super(ExchangeEvent.class);
@@ -63,6 +68,15 @@ public class MicrometerExchangeEventNotifier extends 
AbstractMicrometerEventNoti
         this.namingStrategy = namingStrategy;
     }
 
+    @Override
+    protected void doInit() throws Exception {
+        ManagementStrategy ms = getCamelContext().getManagementStrategy();
+        if (ms != null && ms.getManagementAgent() != null) {
+            registerKamelets = 
ms.getManagementAgent().getRegisterRoutesCreateByKamelet();
+            registerTemplates = 
ms.getManagementAgent().getRegisterRoutesCreateByTemplate();
+        }
+    }
+
     @Override
     protected void doStart() throws Exception {
         super.doStart();
@@ -94,14 +108,29 @@ public class MicrometerExchangeEventNotifier extends 
AbstractMicrometerEventNoti
 
     @Override
     public void notify(CamelEvent eventObject) {
-        if (!(getIgnoreExchanges().test(((ExchangeEvent) 
eventObject).getExchange()))) {
-            handleExchangeEvent((ExchangeEvent) eventObject);
-            if (eventObject instanceof ExchangeCreatedEvent) {
-                handleCreatedEvent((ExchangeCreatedEvent) eventObject);
-            } else if (eventObject instanceof ExchangeSentEvent) {
-                handleSentEvent((ExchangeSentEvent) eventObject);
-            } else if (eventObject instanceof ExchangeCompletedEvent || 
eventObject instanceof ExchangeFailedEvent) {
-                handleDoneEvent((ExchangeEvent) eventObject);
+        if (eventObject instanceof ExchangeEvent ee) {
+            // skip routes that should not be included
+            boolean skip = false;
+            String routeId = ExchangeHelper.getAtRouteId(ee.getExchange());
+            if (routeId != null) {
+                Route route = ee.getExchange().getContext().getRoute(routeId);
+                if (route != null) {
+                    skip = (route.isCreatedByKamelet() && !registerKamelets)
+                            || (route.isCreatedByRouteTemplate() && 
!registerTemplates);
+                }
+            }
+            if (skip) {
+                return;
+            }
+            if (!(getIgnoreExchanges().test(ee.getExchange()))) {
+                handleExchangeEvent(ee);
+                if (eventObject instanceof ExchangeCreatedEvent) {
+                    handleCreatedEvent((ExchangeCreatedEvent) eventObject);
+                } else if (eventObject instanceof ExchangeSentEvent) {
+                    handleSentEvent((ExchangeSentEvent) eventObject);
+                } else if (eventObject instanceof ExchangeCompletedEvent || 
eventObject instanceof ExchangeFailedEvent) {
+                    handleDoneEvent((ExchangeEvent) eventObject);
+                }
             }
         }
     }
diff --git 
a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerRouteEventNotifier.java
 
b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerRouteEventNotifier.java
index 6c638e031ce..04b5cb07266 100644
--- 
a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerRouteEventNotifier.java
+++ 
b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/eventnotifier/MicrometerRouteEventNotifier.java
@@ -26,6 +26,7 @@ import org.apache.camel.spi.CamelEvent.RouteReloadedEvent;
 import org.apache.camel.spi.CamelEvent.RouteRemovedEvent;
 import org.apache.camel.spi.CamelEvent.RouteStartedEvent;
 import org.apache.camel.spi.CamelEvent.RouteStoppedEvent;
+import org.apache.camel.spi.ManagementStrategy;
 
 public class MicrometerRouteEventNotifier extends 
AbstractMicrometerEventNotifier<RouteEvent> {
 
@@ -36,6 +37,8 @@ public class MicrometerRouteEventNotifier extends 
AbstractMicrometerEventNotifie
     private Gauge gaugeRunning;
     private Gauge gaugeReloaded;
     private MicrometerRouteEventNotifierNamingStrategy namingStrategy = 
MicrometerRouteEventNotifierNamingStrategy.DEFAULT;
+    boolean registerKamelets;
+    boolean registerTemplates = true;
 
     public MicrometerRouteEventNotifier() {
         super(RouteEvent.class);
@@ -49,6 +52,15 @@ public class MicrometerRouteEventNotifier extends 
AbstractMicrometerEventNotifie
         this.namingStrategy = namingStrategy;
     }
 
+    @Override
+    protected void doInit() throws Exception {
+        ManagementStrategy ms = getCamelContext().getManagementStrategy();
+        if (ms != null && ms.getManagementAgent() != null) {
+            registerKamelets = 
ms.getManagementAgent().getRegisterRoutesCreateByKamelet();
+            registerTemplates = 
ms.getManagementAgent().getRegisterRoutesCreateByTemplate();
+        }
+    }
+
     @Override
     protected void doStart() throws Exception {
         super.doStart();
@@ -84,6 +96,14 @@ public class MicrometerRouteEventNotifier extends 
AbstractMicrometerEventNotifie
 
     @Override
     public void notify(CamelEvent eventObject) {
+        if (eventObject instanceof RouteEvent re) {
+            // skip routes that should not be included
+            boolean skip = (re.getRoute().isCreatedByKamelet() && 
!registerKamelets)
+                    || (re.getRoute().isCreatedByRouteTemplate() && 
!registerTemplates);
+            if (skip) {
+                return;
+            }
+        }
         if (eventObject instanceof RouteAddedEvent) {
             routesAdded.incrementAndGet();
         } else if (eventObject instanceof RouteRemovedEvent) {
diff --git 
a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicy.java
 
b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicy.java
index 264cb58d6cf..74681d8797d 100644
--- 
a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicy.java
+++ 
b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/routepolicy/MicrometerRoutePolicy.java
@@ -31,6 +31,7 @@ import org.apache.camel.NonManagedService;
 import org.apache.camel.Route;
 import org.apache.camel.RuntimeCamelException;
 import org.apache.camel.component.micrometer.MicrometerUtils;
+import org.apache.camel.spi.ManagementStrategy;
 import org.apache.camel.support.ExchangeHelper;
 import org.apache.camel.support.RoutePolicySupport;
 import org.apache.camel.support.service.ServiceHelper;
@@ -54,6 +55,8 @@ public class MicrometerRoutePolicy extends RoutePolicySupport 
implements NonMana
     private MicrometerRoutePolicyConfiguration configuration = 
MicrometerRoutePolicyConfiguration.DEFAULT;
 
     private final Map<Route, MetricsStatistics> statisticsMap = new 
HashMap<>();
+    boolean registerKamelets;
+    boolean registerTemplates = true;
 
     private static final class MetricsStatistics {
         private final MeterRegistry meterRegistry;
@@ -221,6 +224,12 @@ public class MicrometerRoutePolicy extends 
RoutePolicySupport implements NonMana
     public void onInit(Route route) {
         super.onInit(route);
 
+        ManagementStrategy ms = 
route.getCamelContext().getManagementStrategy();
+        if (ms != null && ms.getManagementAgent() != null) {
+            registerKamelets = 
ms.getManagementAgent().getRegisterRoutesCreateByKamelet();
+            registerTemplates = 
ms.getManagementAgent().getRegisterRoutesCreateByTemplate();
+        }
+
         if (getMeterRegistry() == null) {
             setMeterRegistry(MicrometerUtils.getOrCreateMeterRegistry(
                     route.getCamelContext().getRegistry(), 
METRICS_REGISTRY_NAME));
@@ -248,7 +257,15 @@ public class MicrometerRoutePolicy extends 
RoutePolicySupport implements NonMana
         // for now we record only all the timings of a complete exchange 
(responses)
         // we have in-flight / total statistics already from camel-core
         statisticsMap.computeIfAbsent(route,
-                it -> new MetricsStatistics(getMeterRegistry(), it, 
getNamingStrategy(), configuration));
+                it -> {
+                    // skip routes that should not be included
+                    boolean skip = (it.isCreatedByKamelet() && 
!registerKamelets)
+                            || (it.isCreatedByRouteTemplate() && 
!registerTemplates);
+                    if (skip) {
+                        return null;
+                    }
+                    return new MetricsStatistics(getMeterRegistry(), it, 
getNamingStrategy(), configuration);
+                });
     }
 
     @Override
diff --git a/core/camel-api/src/main/java/org/apache/camel/Route.java 
b/core/camel-api/src/main/java/org/apache/camel/Route.java
index a7d0f0cd054..d247d02240a 100644
--- a/core/camel-api/src/main/java/org/apache/camel/Route.java
+++ b/core/camel-api/src/main/java/org/apache/camel/Route.java
@@ -47,6 +47,7 @@ public interface Route extends RuntimeConfiguration {
     String NODE_PREFIX_ID_PROPERTY = "nodePrefixId";
     String REST_PROPERTY = "rest";
     String TEMPLATE_PROPERTY = "template";
+    String KAMELET_PROPERTY = "kamelet";
     String DESCRIPTION_PROPERTY = "description";
     String CONFIGURATION_ID_PROPERTY = "configurationId";
     String SUPERVISED = "supervised";
@@ -70,6 +71,21 @@ public interface Route extends RuntimeConfiguration {
      */
     boolean isCustomId();
 
+    /**
+     * Whether this route is a Rest DSL route.
+     */
+    boolean isCreatedByRestDsl();
+
+    /**
+     * Whether this route was created from a route template (or a Kamelet).
+     */
+    boolean isCreatedByRouteTemplate();
+
+    /**
+     * Whether this route was created from a Kamelet.
+     */
+    boolean isCreatedByKamelet();
+
     /**
      * Gets the route group
      *
diff --git 
a/core/camel-api/src/main/java/org/apache/camel/spi/ManagementAgent.java 
b/core/camel-api/src/main/java/org/apache/camel/spi/ManagementAgent.java
index 4e1ee22dd01..214d5ddf4d6 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/ManagementAgent.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/ManagementAgent.java
@@ -199,6 +199,34 @@ public interface ManagementAgent extends Service {
      */
     void setRegisterNewRoutes(Boolean registerNewRoutes);
 
+    /**
+     * Whether to register mbeans for routes created by a Kamelet
+     * <p/>
+     * This option is default <tt>false</tt>.
+     */
+    Boolean getRegisterRoutesCreateByKamelet();
+
+    /**
+     * Whether to register mbeans for routes created by a Kamelet
+     * <p/>
+     * This option is default <tt>false</tt>.
+     */
+    void setRegisterRoutesCreateByKamelet(Boolean 
registerRoutesCreateByKamelet);
+
+    /**
+     * Whether to register mbeans for routes created by a route templates (not 
Kamelets)
+     * <p/>
+     * This option is default <tt>true</tt>.
+     */
+    Boolean getRegisterRoutesCreateByTemplate();
+
+    /**
+     * Whether to register mbeans for routes created by a route templates (not 
Kamelets)
+     * <p/>
+     * This option is default <tt>true</tt>.
+     */
+    void setRegisterRoutesCreateByTemplate(Boolean 
registerRoutesCreateByTemplate);
+
     /**
      * Whether to remove detected sensitive information (such as passwords) 
from MBean names and attributes.
      * <p/>
diff --git a/core/camel-api/src/main/java/org/apache/camel/spi/UnitOfWork.java 
b/core/camel-api/src/main/java/org/apache/camel/spi/UnitOfWork.java
index b9d28cb530e..75b5de4cd2a 100644
--- a/core/camel-api/src/main/java/org/apache/camel/spi/UnitOfWork.java
+++ b/core/camel-api/src/main/java/org/apache/camel/spi/UnitOfWork.java
@@ -203,6 +203,21 @@ public interface UnitOfWork {
      */
     int routeStackLevel();
 
+    /**
+     * Gets the {@link Route} level-of-depth that this {@link UnitOfWork} 
currently is being routed through.
+     * <p/>
+     * Notice that an {@link Exchange} can be routed through multiple routes 
and thus the level of depth can change over
+     * time.
+     * <p>
+     * If level is 1 then the current route is at the first route (original 
route). Maybe be <tt>0</tt> if not routed
+     * through a route currently.
+     *
+     * @param  includeRouteTemplate whether to include routes created by route 
templates
+     * @param  includeKamelet       whether to include routes created by 
kamelets
+     * @return                      the route level-of-depth
+     */
+    int routeStackLevel(boolean includeRouteTemplate, boolean includeKamelet);
+
     /**
      * Whether the unit of work should call the before/after process methods 
or not.
      */
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
index 24cb8e2af08..d14bb4760cb 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/AbstractCamelContext.java
@@ -31,6 +31,7 @@ import java.util.List;
 import java.util.Map;
 import java.util.Optional;
 import java.util.Set;
+import java.util.StringJoiner;
 import java.util.TreeSet;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.CopyOnWriteArrayList;
@@ -2567,7 +2568,17 @@ public abstract class AbstractCamelContext extends 
BaseService
                 && LOG.isInfoEnabled()) {
             int started = 0;
             int total = 0;
+            int kamelets = 0;
+            int templates = 0;
+            int rests = 0;
             int disabled = 0;
+            boolean registerKamelets = false;
+            boolean registerTemplates = true;
+            ManagementStrategy ms = getManagementStrategy();
+            if (ms != null && ms.getManagementAgent() != null) {
+                registerKamelets = 
ms.getManagementAgent().getRegisterRoutesCreateByKamelet();
+                registerTemplates = 
ms.getManagementAgent().getRegisterRoutesCreateByTemplate();
+            }
             List<String> lines = new ArrayList<>();
             List<String> configs = new ArrayList<>();
             
routeStartupOrder.sort(Comparator.comparingInt(RouteStartupOrder::getStartupOrder));
@@ -2575,9 +2586,20 @@ public abstract class AbstractCamelContext extends 
BaseService
                 total++;
                 String id = order.getRoute().getRouteId();
                 String status = getRouteStatus(id).name();
-                if (ServiceStatus.Started.name().equals(status)) {
+                if (order.getRoute().isCreatedByKamelet()) {
+                    kamelets++;
+                } else if (order.getRoute().isCreatedByRouteTemplate()) {
+                    templates++;
+                } else if (order.getRoute().isCreatedByRestDsl()) {
+                    rests++;
+                }
+                boolean skip = order.getRoute().isCreatedByRestDsl()
+                        || (!registerKamelets && 
order.getRoute().isCreatedByKamelet())
+                        || (!registerTemplates && 
order.getRoute().isCreatedByRouteTemplate());
+                if (!skip && ServiceStatus.Started.name().equals(status)) {
                     started++;
                 }
+
                 // use basic endpoint uri to not log verbose details or 
potential sensitive data
                 String uri = 
order.getRoute().getEndpoint().getEndpointBaseUri();
                 uri = URISupport.sanitizeUri(uri);
@@ -2585,7 +2607,9 @@ public abstract class AbstractCamelContext extends 
BaseService
                 if (startupSummaryLevel == StartupSummaryLevel.Verbose && loc 
!= null) {
                     lines.add(String.format("    %s %s (%s) (source: %s)", 
status, id, uri, loc));
                 } else {
-                    lines.add(String.format("    %s %s (%s)", status, id, 
uri));
+                    if (!skip) {
+                        lines.add(String.format("    %s %s (%s)", status, id, 
uri));
+                    }
                 }
                 String cid = order.getRoute().getConfigurationId();
                 if (cid != null) {
@@ -2601,6 +2625,15 @@ public abstract class AbstractCamelContext extends 
BaseService
                     if (ServiceStatus.Stopped.name().equals(status)) {
                         status = "Disabled";
                     }
+                    if (route.isCreatedByKamelet()) {
+                        kamelets++;
+                    } else if (route.isCreatedByRouteTemplate()) {
+                        templates++;
+                    } else if (route.isCreatedByRestDsl()) {
+                        rests++;
+                    }
+                    boolean skip = route.isCreatedByRestDsl() || 
(!registerKamelets && route.isCreatedByKamelet())
+                            || (!registerTemplates && 
route.isCreatedByRouteTemplate());
                     // use basic endpoint uri to not log verbose details or 
potential sensitive data
                     String uri = route.getEndpoint().getEndpointBaseUri();
                     uri = URISupport.sanitizeUri(uri);
@@ -2608,7 +2641,9 @@ public abstract class AbstractCamelContext extends 
BaseService
                     if (startupSummaryLevel == StartupSummaryLevel.Verbose && 
loc != null) {
                         lines.add(String.format("    %s %s (%s) (source: %s)", 
status, id, uri, loc));
                     } else {
-                        lines.add(String.format("    %s %s (%s)", status, id, 
uri));
+                        if (!skip) {
+                            lines.add(String.format("    %s %s (%s)", status, 
id, uri));
+                        }
                     }
 
                     String cid = route.getConfigurationId();
@@ -2617,19 +2652,38 @@ public abstract class AbstractCamelContext extends 
BaseService
                     }
                 }
             }
+            int newTotal = total;
+            if (!registerKamelets) {
+                newTotal -= kamelets;
+            }
+            if (!registerTemplates) {
+                newTotal -= templates;
+            }
+            newTotal -= rests;
+            StringJoiner sj = new StringJoiner(" ");
+            sj.add("total:" + newTotal);
+            if (total != started) {
+                sj.add("started:" + started);
+            }
+            if (kamelets > 0) {
+                sj.add("kamelets:" + kamelets);
+            }
+            if (templates > 0) {
+                sj.add("templates:" + templates);
+            }
+            if (rests > 0) {
+                sj.add("rest-dsl:" + rests);
+            }
             if (disabled > 0) {
-                LOG.info("Routes startup (total:{} started:{} disabled:{})", 
total, started, disabled);
-            } else if (total != started) {
-                LOG.info("Routes startup (total:{} started:{})", total, 
started);
-            } else {
-                LOG.info("Routes startup (started:{})", started);
+                sj.add("disabled:" + disabled);
             }
+            LOG.info(String.format("Routes startup (%s)", sj));
             // if we are default/verbose then log each route line
             if (startupSummaryLevel == StartupSummaryLevel.Default || 
startupSummaryLevel == StartupSummaryLevel.Verbose) {
                 for (String line : lines) {
                     LOG.info(line);
                 }
-                if (startupSummaryLevel == StartupSummaryLevel.Verbose) {
+                if (startupSummaryLevel == StartupSummaryLevel.Verbose && 
!configs.isEmpty()) {
                     LOG.info("Routes configuration:");
                     for (String line : configs) {
                         LOG.info(line);
@@ -3024,6 +3078,16 @@ public abstract class AbstractCamelContext extends 
BaseService
             int total = 0;
             int stopped = 0;
             int forced = 0;
+            int kamelets = 0;
+            int templates = 0;
+            int rests = 0;
+            boolean registerKamelets = false;
+            boolean registerTemplates = true;
+            ManagementStrategy ms = getManagementStrategy();
+            if (ms != null && ms.getManagementAgent() != null) {
+                registerKamelets = 
ms.getManagementAgent().getRegisterRoutesCreateByKamelet();
+                registerTemplates = 
ms.getManagementAgent().getRegisterRoutesCreateByTemplate();
+            }
             List<String> lines = new ArrayList<>();
 
             final ShutdownStrategy shutdownStrategy = 
camelContextExtension.getShutdownStrategy();
@@ -3036,7 +3100,17 @@ public abstract class AbstractCamelContext extends 
BaseService
                 total++;
                 String id = order.getRoute().getRouteId();
                 String status = getRouteStatus(id).name();
-                if (ServiceStatus.Stopped.name().equals(status)) {
+                if (order.getRoute().isCreatedByKamelet()) {
+                    kamelets++;
+                } else if (order.getRoute().isCreatedByRouteTemplate()) {
+                    templates++;
+                } else if (order.getRoute().isCreatedByRestDsl()) {
+                    rests++;
+                }
+                boolean skip = order.getRoute().isCreatedByRestDsl()
+                        || (!registerKamelets && 
order.getRoute().isCreatedByKamelet())
+                        || (!registerTemplates && 
order.getRoute().isCreatedByRouteTemplate());
+                if (!skip && ServiceStatus.Stopped.name().equals(status)) {
                     stopped++;
                 }
                 if 
(order.getRoute().getProperties().containsKey("forcedShutdown")) {
@@ -3046,15 +3120,36 @@ public abstract class AbstractCamelContext extends 
BaseService
                 // use basic endpoint uri to not log verbose details or 
potential sensitive data
                 String uri = 
order.getRoute().getEndpoint().getEndpointBaseUri();
                 uri = URISupport.sanitizeUri(uri);
-                lines.add(String.format("    %s %s (%s)", status, id, uri));
+                if (startupSummaryLevel == StartupSummaryLevel.Verbose || 
!skip) {
+                    lines.add(String.format("    %s %s (%s)", status, id, 
uri));
+                }
+            }
+            int newTotal = total;
+            if (!registerKamelets) {
+                newTotal -= kamelets;
+            }
+            if (!registerTemplates) {
+                newTotal -= templates;
+            }
+            newTotal -= rests;
+            StringJoiner sj = new StringJoiner(" ");
+            sj.add("total:" + newTotal);
+            if (total != stopped) {
+                sj.add("stopped:" + stopped);
+            }
+            if (kamelets > 0) {
+                sj.add("kamelets:" + kamelets);
+            }
+            if (templates > 0) {
+                sj.add("templates:" + templates);
+            }
+            if (rests > 0) {
+                sj.add("rest-dsl:" + rests);
             }
             if (forced > 0) {
-                logger.log(String.format("Routes stopped (total:%s stopped:%s 
forced:%s)", total, stopped, forced));
-            } else if (total != stopped) {
-                logger.log(String.format("Routes stopped (total:%s 
stopped:%s)", total, stopped));
-            } else {
-                logger.log(String.format("Routes stopped (stopped:%s)", 
stopped));
+                sj.add("forced:" + forced);
             }
+            logger.log(String.format("Routes stopped (%s)", sj));
             // if we are default/verbose then log each route line
             if (startupSummaryLevel == StartupSummaryLevel.Default || 
startupSummaryLevel == StartupSummaryLevel.Verbose) {
                 for (String line : lines) {
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
index 1e90f04be21..eab52da2dfd 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultRoute.java
@@ -141,6 +141,21 @@ public class DefaultRoute extends ServiceSupport 
implements Route {
         return "true".equals(properties.get(Route.CUSTOM_ID_PROPERTY));
     }
 
+    @Override
+    public boolean isCreatedByRestDsl() {
+        return "true".equals(properties.get(Route.REST_PROPERTY));
+    }
+
+    @Override
+    public boolean isCreatedByRouteTemplate() {
+        return "true".equals(properties.get(Route.TEMPLATE_PROPERTY));
+    }
+
+    @Override
+    public boolean isCreatedByKamelet() {
+        return "true".equals(properties.get(Route.KAMELET_PROPERTY));
+    }
+
     @Override
     public String getGroup() {
         return (String) properties.get(Route.GROUP_PROPERTY);
diff --git 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultUnitOfWork.java
 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultUnitOfWork.java
index c5230567ec3..51f8680b33f 100644
--- 
a/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultUnitOfWork.java
+++ 
b/core/camel-base-engine/src/main/java/org/apache/camel/impl/engine/DefaultUnitOfWork.java
@@ -367,6 +367,28 @@ public class DefaultUnitOfWork implements UnitOfWork {
         return routes.size();
     }
 
+    public int routeStackLevel(boolean includeRouteTemplate, boolean 
includeKamelet) {
+        if (includeKamelet && includeRouteTemplate) {
+            return routes.size();
+        }
+
+        int level = 0;
+        for (Route r : routes) {
+            if (r.isCreatedByKamelet()) {
+                if (includeKamelet) {
+                    level++;
+                }
+            } else if (r.isCreatedByRouteTemplate()) {
+                if (includeRouteTemplate) {
+                    level++;
+                }
+            } else {
+                level++;
+            }
+        }
+        return level;
+    }
+
     @Override
     public boolean isBeforeAfterProcess() {
         return false;
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ConsumerDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ConsumerDevConsole.java
index 3341c80c43d..a75ea58d2fb 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/ConsumerDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/ConsumerDevConsole.java
@@ -139,7 +139,7 @@ public class ConsumerDevConsole extends AbstractDevConsole {
                 String id = route.getId();
                 ManagedRouteMBean mr = mcc.getManagedRoute(id);
                 ManagedConsumerMBean mc = mcc.getManagedConsumer(id);
-                if (mc != null) {
+                if (mr != null && mc != null) {
                     JsonObject jo = new JsonObject();
                     Integer inflight = mc.getInflightExchanges();
                     if (inflight == null) {
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
index e060fb93607..1e6ee27a284 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDevConsole.java
@@ -22,6 +22,7 @@ import java.util.Comparator;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.Function;
 
 import org.apache.camel.Exchange;
@@ -359,6 +360,7 @@ public class RouteDevConsole extends AbstractDevConsole {
             routes.sort((o1, o2) -> 
o1.getRouteId().compareToIgnoreCase(o2.getRouteId()));
             routes.stream()
                     .map(route -> mcc.getManagedRoute(route.getRouteId()))
+                    .filter(Objects::nonNull)
                     .filter(r -> accept(r, filter))
                     .filter(r -> accept(r, subPath))
                     .sorted(RouteDevConsole::sort)
@@ -378,8 +380,7 @@ public class RouteDevConsole extends AbstractDevConsole {
     }
 
     private static int sort(ManagedRouteMBean o1, ManagedRouteMBean o2) {
-        // sort by id
-        return o1.getRouteId().compareTo(o2.getRouteId());
+        return o1.getRouteId().compareToIgnoreCase(o2.getRouteId());
     }
 
     private String getLoad1(ManagedRouteMBean mrb) {
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
index 659f388c439..63c127b0d82 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/RouteDumpDevConsole.java
@@ -20,6 +20,7 @@ import java.io.StringReader;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.Function;
 
 import org.apache.camel.Exchange;
@@ -151,6 +152,7 @@ public class RouteDumpDevConsole extends AbstractDevConsole 
{
             routes.sort((o1, o2) -> 
o1.getRouteId().compareToIgnoreCase(o2.getRouteId()));
             routes.stream()
                     .map(route -> mcc.getManagedRoute(route.getRouteId()))
+                    .filter(Objects::nonNull)
                     .filter(r -> accept(r, filter))
                     .filter(r -> accept(r, subPath))
                     .sorted(RouteDumpDevConsole::sort)
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/SourceDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/SourceDevConsole.java
index ea96a307af6..c848030b181 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/SourceDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/SourceDevConsole.java
@@ -20,6 +20,7 @@ import java.io.LineNumberReader;
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.Function;
 
 import org.apache.camel.Exchange;
@@ -138,6 +139,7 @@ public class SourceDevConsole extends AbstractDevConsole {
             routes.sort((o1, o2) -> 
o1.getRouteId().compareToIgnoreCase(o2.getRouteId()));
             routes.stream()
                     .map(route -> mcc.getManagedRoute(route.getRouteId()))
+                    .filter(Objects::nonNull)
                     .filter(r -> accept(r, filter))
                     .filter(r -> accept(r, subPath))
                     .sorted(SourceDevConsole::sort)
diff --git 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/TopDevConsole.java
 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/TopDevConsole.java
index 995c25a952a..54358b71059 100644
--- 
a/core/camel-console/src/main/java/org/apache/camel/impl/console/TopDevConsole.java
+++ 
b/core/camel-console/src/main/java/org/apache/camel/impl/console/TopDevConsole.java
@@ -21,6 +21,7 @@ import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
 import java.util.Map;
+import java.util.Objects;
 import java.util.function.Function;
 
 import org.apache.camel.Exchange;
@@ -270,6 +271,7 @@ public class TopDevConsole extends AbstractDevConsole {
         List<Route> routes = getCamelContext().getRoutes();
         routes.stream()
                 .map(route -> mcc.getManagedRoute(route.getRouteId()))
+                .filter(Objects::nonNull)
                 .filter(r -> acceptRoute(r, filter))
                 .sorted(TopDevConsole::top)
                 .limit(max)
@@ -284,6 +286,7 @@ public class TopDevConsole extends AbstractDevConsole {
 
         routes.stream()
                 .map(route -> mcc.getManagedRoute(route.getRouteId()))
+                .filter(Objects::nonNull)
                 .filter(r -> acceptRoute(r, subPath))
                 .forEach(r -> {
                     try {
diff --git 
a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
 
b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
index 7b274a5ef1c..aa78b73fdc4 100644
--- 
a/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
+++ 
b/core/camel-core-model/src/main/java/org/apache/camel/model/RouteDefinition.java
@@ -86,6 +86,7 @@ public class RouteDefinition extends 
OutputDefinition<RouteDefinition>
     private boolean contextScopedErrorHandler = true;
     private Boolean rest;
     private Boolean template;
+    private Boolean kamelet;
     private RestDefinition restDefinition;
     private RestBindingDefinition restBindingDefinition;
     private InputTypeDefinition inputType;
@@ -1178,7 +1179,7 @@ public class RouteDefinition extends 
OutputDefinition<RouteDefinition>
     }
 
     /**
-     * This route is created from a route template.
+     * This route is created from a route template (or from a Kamelet).
      */
     public void setTemplate(Boolean template) {
         this.template = template;
@@ -1190,6 +1191,19 @@ public class RouteDefinition extends 
OutputDefinition<RouteDefinition>
         return template;
     }
 
+    /**
+     * This route is created from a Kamelet.
+     */
+    public void setKamelet(Boolean kamelet) {
+        this.kamelet = kamelet;
+    }
+
+    @XmlAttribute
+    @Metadata(label = "advanced")
+    public Boolean isKamelet() {
+        return kamelet;
+    }
+
     public RestDefinition getRestDefinition() {
         return restDefinition;
     }
diff --git 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/SendProcessor.java
 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/SendProcessor.java
index b04e75a88fb..04840285980 100644
--- 
a/core/camel-core-processor/src/main/java/org/apache/camel/processor/SendProcessor.java
+++ 
b/core/camel-core-processor/src/main/java/org/apache/camel/processor/SendProcessor.java
@@ -313,6 +313,9 @@ public class SendProcessor extends AsyncProcessorSupport 
implements Traceable, E
         // yes we can optimize and use the producer directly for sending
         if (destination.isSingletonProducer()) {
             this.producer = destination.createAsyncProducer();
+            if (this.producer instanceof RouteIdAware ria) {
+                ria.setRouteId(getRouteId());
+            }
             // ensure the producer is managed and started
             camelContext.addService(this.producer, true, true);
         } else {
diff --git 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java
 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java
index 31a92c2582e..a41d8cbf34c 100644
--- 
a/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java
+++ 
b/core/camel-core-reifier/src/main/java/org/apache/camel/reifier/RouteReifier.java
@@ -395,6 +395,8 @@ public class RouteReifier extends 
ProcessorReifier<RouteDefinition> {
         routeProperties.put(Route.REST_PROPERTY, rest);
         String template = Boolean.toString(definition.isTemplate() != null && 
definition.isTemplate());
         routeProperties.put(Route.TEMPLATE_PROPERTY, template);
+        String kamelet = Boolean.toString(definition.isKamelet() != null && 
definition.isKamelet());
+        routeProperties.put(Route.KAMELET_PROPERTY, kamelet);
         if (definition.getAppliedRouteConfigurationIds() != null) {
             routeProperties.put(Route.CONFIGURATION_ID_PROPERTY,
                     String.join(",", 
definition.getAppliedRouteConfigurationIds()));
diff --git 
a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
 
b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
index ca08ad52360..7d2f91e74db 100644
--- 
a/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
+++ 
b/core/camel-main/src/generated/java/org/apache/camel/main/MainConfigurationPropertiesConfigurer.java
@@ -125,6 +125,10 @@ public class MainConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "JmxManagementMBeansLevel": 
target.setJmxManagementMBeansLevel(property(camelContext, 
org.apache.camel.ManagementMBeansLevel.class, value)); return true;
         case "jmxmanagementnamepattern":
         case "JmxManagementNamePattern": 
target.setJmxManagementNamePattern(property(camelContext, 
java.lang.String.class, value)); return true;
+        case "jmxmanagementregisterroutescreatebykamelet":
+        case "JmxManagementRegisterRoutesCreateByKamelet": 
target.setJmxManagementRegisterRoutesCreateByKamelet(property(camelContext, 
boolean.class, value)); return true;
+        case "jmxmanagementregisterroutescreatebytemplate":
+        case "JmxManagementRegisterRoutesCreateByTemplate": 
target.setJmxManagementRegisterRoutesCreateByTemplate(property(camelContext, 
boolean.class, value)); return true;
         case "jmxmanagementstatisticslevel":
         case "JmxManagementStatisticsLevel": 
target.setJmxManagementStatisticsLevel(property(camelContext, 
org.apache.camel.ManagementStatisticsLevel.class, value)); return true;
         case "jmxupdaterouteenabled":
@@ -366,6 +370,10 @@ public class MainConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "JmxManagementMBeansLevel": return 
org.apache.camel.ManagementMBeansLevel.class;
         case "jmxmanagementnamepattern":
         case "JmxManagementNamePattern": return java.lang.String.class;
+        case "jmxmanagementregisterroutescreatebykamelet":
+        case "JmxManagementRegisterRoutesCreateByKamelet": return 
boolean.class;
+        case "jmxmanagementregisterroutescreatebytemplate":
+        case "JmxManagementRegisterRoutesCreateByTemplate": return 
boolean.class;
         case "jmxmanagementstatisticslevel":
         case "JmxManagementStatisticsLevel": return 
org.apache.camel.ManagementStatisticsLevel.class;
         case "jmxupdaterouteenabled":
@@ -608,6 +616,10 @@ public class MainConfigurationPropertiesConfigurer extends 
org.apache.camel.supp
         case "JmxManagementMBeansLevel": return 
target.getJmxManagementMBeansLevel();
         case "jmxmanagementnamepattern":
         case "JmxManagementNamePattern": return 
target.getJmxManagementNamePattern();
+        case "jmxmanagementregisterroutescreatebykamelet":
+        case "JmxManagementRegisterRoutesCreateByKamelet": return 
target.isJmxManagementRegisterRoutesCreateByKamelet();
+        case "jmxmanagementregisterroutescreatebytemplate":
+        case "JmxManagementRegisterRoutesCreateByTemplate": return 
target.isJmxManagementRegisterRoutesCreateByTemplate();
         case "jmxmanagementstatisticslevel":
         case "JmxManagementStatisticsLevel": return 
target.getJmxManagementStatisticsLevel();
         case "jmxupdaterouteenabled":
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 127e310a2c6..f1e51f670bf 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
@@ -70,6 +70,8 @@
     { "name": "camel.main.jmxEnabled", "description": "Enable JMX in your 
Camel application.", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": true },
     { "name": "camel.main.jmxManagementMBeansLevel", "description": "Sets the 
mbeans registration level. The default value is Default.", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "object", 
"javaType": "org.apache.camel.ManagementMBeansLevel", "defaultValue": "Default" 
},
     { "name": "camel.main.jmxManagementNamePattern", "description": "The 
naming pattern for creating the CamelContext JMX management name. The default 
pattern is #name#", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "string", 
"javaType": "java.lang.String", "defaultValue": "#name#" },
+    { "name": "camel.main.jmxManagementRegisterRoutesCreateByKamelet", 
"description": "Whether routes created by Kamelets should be registered for JMX 
management. Enabling this allows to have fine-grained monitoring and management 
of every route created via Kamelets. This is default disabled as a Kamelet is 
intended as a component (black-box) and its implementation details as Camel 
route makes the overall management and monitoring of Camel applications more 
verbose. During development of [...]
+    { "name": "camel.main.jmxManagementRegisterRoutesCreateByTemplate", 
"description": "Whether routes created by route templates (not Kamelets) should 
be registered for JMX management. Enabling this allows to have fine-grained 
monitoring and management of every route created via route templates. This is 
default enabled (unlike Kamelets) as routes created via templates is regarded 
as standard routes, and should be available for management and monitoring.", 
"sourceType": "org.apache.camel [...]
     { "name": "camel.main.jmxManagementStatisticsLevel", "description": "Sets 
the JMX statistics level, the level can be set to Extended to gather additional 
information The default value is Default.", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "object", 
"javaType": "org.apache.camel.ManagementStatisticsLevel", "defaultValue": 
"Default", "enum": [ "Extended", "Default", "RoutesOnly", "Off" ] },
     { "name": "camel.main.jmxUpdateRouteEnabled", "description": "Whether to 
allow updating routes at runtime via JMX using the ManagedRouteMBean. This is 
disabled by default, but can be enabled for development and troubleshooting 
purposes, such as updating routes in an existing running Camel via JMX and 
other tools.", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": "false" },
     { "name": "camel.main.lightweight", "description": "Configure the context 
to be lightweight. This will trigger some optimizations and memory reduction 
options. Lightweight context have some limitations. At this moment, dynamic 
endpoint destinations are not supported.", "sourceType": 
"org.apache.camel.main.DefaultConfigurationProperties", "type": "boolean", 
"javaType": "boolean", "defaultValue": "false" },
diff --git a/core/camel-main/src/main/docs/main.adoc 
b/core/camel-main/src/main/docs/main.adoc
index c709db4e390..a12a25f0edb 100644
--- a/core/camel-main/src/main/docs/main.adoc
+++ b/core/camel-main/src/main/docs/main.adoc
@@ -19,7 +19,7 @@ The following tables lists all the options:
 
 // main options: START
 === Camel Main configurations
-The camel.main supports 117 options, which are listed below.
+The camel.main supports 119 options, which are listed below.
 
 [width="100%",cols="2,5,^1,2",options="header"]
 |===
@@ -76,6 +76,8 @@ The camel.main supports 117 options, which are listed below.
 | *camel.main.jmxEnabled* | Enable JMX in your Camel application. | true | 
boolean
 | *camel.main.jmxManagementMBeans{zwsp}Level* | Sets the mbeans registration 
level. The default value is Default. | Default | ManagementMBeansLevel
 | *camel.main.jmxManagementName{zwsp}Pattern* | The naming pattern for 
creating the CamelContext JMX management name. The default pattern is #name# | 
#name# | String
+| *camel.main.jmxManagement{zwsp}RegisterRoutesCreateByKamelet* | Whether 
routes created by Kamelets should be registered for JMX management. Enabling 
this allows to have fine-grained monitoring and management of every route 
created via Kamelets. This is default disabled as a Kamelet is intended as a 
component (black-box) and its implementation details as Camel route makes the 
overall management and monitoring of Camel applications more verbose. During 
development of Kamelets then enabli [...]
+| *camel.main.jmxManagement{zwsp}RegisterRoutesCreateByTemplate* | Whether 
routes created by route templates (not Kamelets) should be registered for JMX 
management. Enabling this allows to have fine-grained monitoring and management 
of every route created via route templates. This is default enabled (unlike 
Kamelets) as routes created via templates is regarded as standard routes, and 
should be available for management and monitoring. | true | boolean
 | *camel.main.jmxManagement{zwsp}StatisticsLevel* | Sets the JMX statistics 
level, the level can be set to Extended to gather additional information The 
default value is Default. | Default | ManagementStatisticsLevel
 | *camel.main.jmxUpdateRoute{zwsp}Enabled* | Whether to allow updating routes 
at runtime via JMX using the ManagedRouteMBean. This is disabled by default, 
but can be enabled for development and troubleshooting purposes, such as 
updating routes in an existing running Camel via JMX and other tools. | false | 
boolean
 | *camel.main.lightweight* | Configure the context to be lightweight. This 
will trigger some optimizations and memory reduction options. Lightweight 
context have some limitations. At this moment, dynamic endpoint destinations 
are not supported. | false | boolean
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
index 4d4f664c20f..22674dad7f2 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationConfigurer.java
@@ -294,6 +294,10 @@ public final class DefaultConfigurationConfigurer {
                     
.setManagementNamePattern(config.getJmxManagementNamePattern());
             camelContext.getManagementStrategy().getManagementAgent()
                     .setUpdateRouteEnabled(config.isJmxUpdateRouteEnabled());
+            camelContext.getManagementStrategy().getManagementAgent()
+                    
.setRegisterRoutesCreateByKamelet(config.isJmxManagementRegisterRoutesCreateByKamelet());
+            camelContext.getManagementStrategy().getManagementAgent()
+                    
.setRegisterRoutesCreateByTemplate(config.isJmxManagementRegisterRoutesCreateByTemplate());
         }
         if (config.isCamelEventsTimestampEnabled()) {
             
camelContext.getManagementStrategy().getEventFactory().setTimestampEnabled(true);
diff --git 
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
 
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
index 2e3fc64a8f3..921db5e0faa 100644
--- 
a/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
+++ 
b/core/camel-main/src/main/java/org/apache/camel/main/DefaultConfigurationProperties.java
@@ -101,6 +101,8 @@ public abstract class DefaultConfigurationProperties<T> {
     @Metadata(defaultValue = "Default")
     private ManagementStatisticsLevel jmxManagementStatisticsLevel = 
ManagementStatisticsLevel.Default;
     private String jmxManagementNamePattern = "#name#";
+    private boolean jmxManagementRegisterRoutesCreateByKamelet;
+    private boolean jmxManagementRegisterRoutesCreateByTemplate = true;
     private boolean camelEventsTimestampEnabled;
     private boolean useMdcLogging;
     private String mdcLoggingKeysPattern;
@@ -997,6 +999,41 @@ public abstract class DefaultConfigurationProperties<T> {
         this.jmxManagementNamePattern = jmxManagementNamePattern;
     }
 
+    public boolean isJmxManagementRegisterRoutesCreateByKamelet() {
+        return jmxManagementRegisterRoutesCreateByKamelet;
+    }
+
+    /**
+     * Whether routes created by Kamelets should be registered for JMX 
management. Enabling this allows to have
+     * fine-grained monitoring and management of every route created via 
Kamelets.
+     *
+     * This is default disabled as a Kamelet is intended as a component 
(black-box) and its implementation details as
+     * Camel route makes the overall management and monitoring of Camel 
applications more verbose.
+     *
+     * During development of Kamelets then enabling this will make it possible 
for developers to do fine-grained
+     * performance inspection and identify potential bottlenecks in the 
Kamelet routes.
+     *
+     * However, for production usage then keeping this disabled is recommended.
+     */
+    public void setJmxManagementRegisterRoutesCreateByKamelet(boolean 
jmxManagementRegisterRoutesCreateByKamelet) {
+        this.jmxManagementRegisterRoutesCreateByKamelet = 
jmxManagementRegisterRoutesCreateByKamelet;
+    }
+
+    public boolean isJmxManagementRegisterRoutesCreateByTemplate() {
+        return jmxManagementRegisterRoutesCreateByTemplate;
+    }
+
+    /**
+     * Whether routes created by route templates (not Kamelets) should be 
registered for JMX management. Enabling this
+     * allows to have fine-grained monitoring and management of every route 
created via route templates.
+     *
+     * This is default enabled (unlike Kamelets) as routes created via 
templates is regarded as standard routes, and
+     * should be available for management and monitoring.
+     */
+    public void setJmxManagementRegisterRoutesCreateByTemplate(boolean 
jmxManagementRegisterRoutesCreateByTemplate) {
+        this.jmxManagementRegisterRoutesCreateByTemplate = 
jmxManagementRegisterRoutesCreateByTemplate;
+    }
+
     public boolean isCamelEventsTimestampEnabled() {
         return camelEventsTimestampEnabled;
     }
@@ -2201,6 +2238,35 @@ public abstract class DefaultConfigurationProperties<T> {
         return (T) this;
     }
 
+    /**
+     * Whether routes created by Kamelets should be registered for JMX 
management. Enabling this allows to have
+     * fine-grained monitoring and management of every route created via 
Kamelets.
+     *
+     * This is default disabled as a Kamelet is intended as a component 
(black-box) and its implementation details as
+     * Camel route makes the overall management and monitoring of Camel 
applications more verbose.
+     *
+     * During development of Kamelets then enabling this will make it possible 
for developers to do fine-grained
+     * performance inspection and identify potential bottlenecks in the 
Kamelet routes.
+     *
+     * However, for production usage then keeping this disabled is recommended.
+     */
+    public T withJmxManagementRegisterRoutesCreateByKamelet(boolean 
jmxManagementRegisterRoutesCreateByKamelet) {
+        this.jmxManagementRegisterRoutesCreateByKamelet = 
jmxManagementRegisterRoutesCreateByKamelet;
+        return (T) this;
+    }
+
+    /**
+     * Whether routes created by route templates (not Kamelets) should be 
registered for JMX management. Enabling this
+     * allows to have fine-grained monitoring and management of every route 
created via route templates.
+     *
+     * This is default enabled (unlike Kamelets) as routes created via 
templates is regarded as standard routes, and
+     * should be available for management and monitoring.
+     */
+    public T withJmxManagementRegisterRoutesCreateByTemplate(boolean 
jmxManagementRegisterRoutesCreateByTemplate) {
+        this.jmxManagementRegisterRoutesCreateByTemplate = 
jmxManagementRegisterRoutesCreateByTemplate;
+        return (T) this;
+    }
+
     /**
      * Whether to include timestamps for all emitted Camel Events. Enabling 
this allows to know fine-grained at what
      * time each event was emitted, which can be used for reporting to report 
exactly the time of the events. This is by
diff --git 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/JmxSystemPropertyKeys.java
 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/JmxSystemPropertyKeys.java
index 51eafd2897f..dfe24f32a79 100644
--- 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/JmxSystemPropertyKeys.java
+++ 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/JmxSystemPropertyKeys.java
@@ -52,6 +52,12 @@ public final class JmxSystemPropertyKeys {
     // whether to register when starting new routes
     public static final String REGISTER_NEW_ROUTES = 
"org.apache.camel.jmx.registerNewRoutes";
 
+    // whether to register routes created by route templates (not kamelets)
+    public static final String REGISTER_ROUTES_CREATED_BY_TEMPLATE = 
"org.apache.camel.jmx.registerRoutesCreateByTemplate";
+
+    // whether to register routes created by Kamelets
+    public static final String REGISTER_ROUTES_CREATED_BY_KAMELET = 
"org.apache.camel.jmx.registerRoutesCreateByKamelet";
+
     // Whether to remove detected sensitive information (such as passwords) 
from MBean names and attributes.
     public static final String MASK = "org.apache.camel.jmx.mask";
 
diff --git 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
index a431ce16d6a..e22e393b6a5 100644
--- 
a/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
+++ 
b/core/camel-management-api/src/main/java/org/apache/camel/api/management/mbean/ManagedRouteMBean.java
@@ -34,6 +34,12 @@ public interface ManagedRouteMBean extends 
ManagedPerformanceCounterMBean {
     @ManagedAttribute(description = "Route Group")
     String getRouteGroup();
 
+    @ManagedAttribute(description = "Is this route created from a route 
template (or Kamelet)")
+    boolean isCreatedByRouteTemplate();
+
+    @ManagedAttribute(description = "Is this route created from a Kamelet")
+    boolean isCreatedByKamelet();
+
     @ManagedAttribute(description = "Route Properties")
     TabularData getRouteProperties();
 
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
index ae761567c8a..fb6c3ef83e0 100644
--- 
a/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
+++ 
b/core/camel-management/src/main/java/org/apache/camel/management/DefaultManagementAgent.java
@@ -69,6 +69,8 @@ public class DefaultManagementAgent extends ServiceSupport 
implements Management
     private Boolean endpointRuntimeStatisticsEnabled;
     private Boolean registerAlways = false;
     private Boolean registerNewRoutes = true;
+    private Boolean registerRoutesCreateByKamelet = false;
+    private Boolean registerRoutesCreateByTemplate = true;
     private Boolean mask = true;
     private Boolean includeHostName = false;
     private Boolean useHostIPAddress = false;
@@ -113,6 +115,14 @@ public class DefaultManagementAgent extends ServiceSupport 
implements Management
             registerNewRoutes = 
Boolean.getBoolean(JmxSystemPropertyKeys.REGISTER_NEW_ROUTES);
             values.put(JmxSystemPropertyKeys.REGISTER_NEW_ROUTES, 
registerNewRoutes);
         }
+        if 
(System.getProperty(JmxSystemPropertyKeys.REGISTER_ROUTES_CREATED_BY_TEMPLATE) 
!= null) {
+            registerRoutesCreateByTemplate = 
Boolean.getBoolean(JmxSystemPropertyKeys.REGISTER_ROUTES_CREATED_BY_TEMPLATE);
+            
values.put(JmxSystemPropertyKeys.REGISTER_ROUTES_CREATED_BY_TEMPLATE, 
registerRoutesCreateByTemplate);
+        }
+        if 
(System.getProperty(JmxSystemPropertyKeys.REGISTER_ROUTES_CREATED_BY_KAMELET) 
!= null) {
+            registerRoutesCreateByKamelet = 
Boolean.getBoolean(JmxSystemPropertyKeys.REGISTER_ROUTES_CREATED_BY_KAMELET);
+            
values.put(JmxSystemPropertyKeys.REGISTER_ROUTES_CREATED_BY_KAMELET, 
registerRoutesCreateByKamelet);
+        }
         if (System.getProperty(JmxSystemPropertyKeys.MASK) != null) {
             mask = Boolean.getBoolean(JmxSystemPropertyKeys.MASK);
             values.put(JmxSystemPropertyKeys.MASK, mask);
@@ -222,6 +232,22 @@ public class DefaultManagementAgent extends ServiceSupport 
implements Management
         this.registerNewRoutes = registerNewRoutes;
     }
 
+    public Boolean getRegisterRoutesCreateByKamelet() {
+        return registerRoutesCreateByKamelet != null && 
registerRoutesCreateByKamelet;
+    }
+
+    public void setRegisterRoutesCreateByKamelet(Boolean 
registerRoutesCreateByKamelet) {
+        this.registerRoutesCreateByKamelet = registerRoutesCreateByKamelet;
+    }
+
+    public Boolean getRegisterRoutesCreateByTemplate() {
+        return registerRoutesCreateByTemplate != null && 
registerRoutesCreateByTemplate;
+    }
+
+    public void setRegisterRoutesCreateByTemplate(Boolean 
registerRoutesCreateByTemplate) {
+        this.registerRoutesCreateByTemplate = registerRoutesCreateByTemplate;
+    }
+
     @Override
     public Boolean getMask() {
         return mask != null && mask;
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 426ce12f53b..16d230ce87a 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
@@ -931,6 +931,15 @@ public class JmxManagementLifecycleStrategy extends 
ServiceSupport implements Li
             return false;
         }
 
+        if (route != null && route.isCreatedByKamelet() && 
!agent.getRegisterRoutesCreateByKamelet()) {
+            // skip routes created from kamelets
+            return false;
+        }
+        if (route != null && route.isCreatedByRouteTemplate() && 
!agent.getRegisterRoutesCreateByTemplate()) {
+            // skip routes created from route templates
+            return false;
+        }
+
         // always register if we are starting CamelContext
         if (getCamelContext().getStatus().isStarting()
                 || getCamelContext().getStatus().isInitializing()) {
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
index 7f1fecc0631..000b07c00de 100644
--- 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
+++ 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedCamelContext.java
@@ -61,10 +61,14 @@ public class ManagedCamelContext extends 
ManagedPerformanceCounter implements Ti
     private final LoadTriplet load = new LoadTriplet();
     private final LoadThroughput thp = new LoadThroughput();
     private final String jmxDomain;
+    private final boolean includeRouteTemplates;
+    private final boolean includeKamelets;
 
     public ManagedCamelContext(CamelContext context) {
         this.context = context;
         this.jmxDomain = 
context.getManagementStrategy().getManagementAgent().getMBeanObjectDomainName();
+        this.includeRouteTemplates = 
context.getManagementStrategy().getManagementAgent().getRegisterRoutesCreateByTemplate();
+        this.includeKamelets = 
context.getManagementStrategy().getManagementAgent().getRegisterRoutesCreateByKamelet();
     }
 
     @Override
@@ -83,7 +87,7 @@ public class ManagedCamelContext extends 
ManagedPerformanceCounter implements Ti
         // we should only count this as 1 instead of 3.
         UnitOfWork uow = exchange.getUnitOfWork();
         if (uow != null) {
-            int level = uow.routeStackLevel();
+            int level = uow.routeStackLevel(includeRouteTemplates, 
includeKamelets);
             if (level <= 1) {
                 super.completedExchange(exchange, time);
             }
@@ -100,7 +104,7 @@ public class ManagedCamelContext extends 
ManagedPerformanceCounter implements Ti
         // we should only count this as 1 instead of 3.
         UnitOfWork uow = exchange.getUnitOfWork();
         if (uow != null) {
-            int level = uow.routeStackLevel();
+            int level = uow.routeStackLevel(includeRouteTemplates, 
includeKamelets);
             if (level <= 1) {
                 super.failedExchange(exchange);
             }
@@ -117,7 +121,7 @@ public class ManagedCamelContext extends 
ManagedPerformanceCounter implements Ti
         // we should only count this as 1 instead of 3.
         UnitOfWork uow = exchange.getUnitOfWork();
         if (uow != null) {
-            int level = uow.routeStackLevel();
+            int level = uow.routeStackLevel(includeRouteTemplates, 
includeKamelets);
             if (level <= 1) {
                 super.processExchange(exchange, type);
             }
@@ -790,15 +794,4 @@ public class ManagedCamelContext extends 
ManagedPerformanceCounter implements Ti
         }
     }
 
-    /**
-     * Used for sorting the routes mbeans accordingly to their ids.
-     */
-    private static final class RouteMBeans implements 
Comparator<ManagedRouteMBean> {
-
-        @Override
-        public int compare(ManagedRouteMBean o1, ManagedRouteMBean o2) {
-            return o1.getRouteId().compareToIgnoreCase(o2.getRouteId());
-        }
-    }
-
 }
diff --git 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
index 3cb8b1581f4..3d46f5f824f 100644
--- 
a/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
+++ 
b/core/camel-management/src/main/java/org/apache/camel/management/mbean/ManagedRoute.java
@@ -129,6 +129,16 @@ public class ManagedRoute extends 
ManagedPerformanceCounter implements TimerList
         return route.getGroup();
     }
 
+    @Override
+    public boolean isCreatedByRouteTemplate() {
+        return 
"true".equals(route.getProperties().getOrDefault(Route.TEMPLATE_PROPERTY, 
"false"));
+    }
+
+    @Override
+    public boolean isCreatedByKamelet() {
+        return 
"true".equals(route.getProperties().getOrDefault(Route.KAMELET_PROPERTY, 
"false"));
+    }
+
     @Override
     public TabularData getRouteProperties() {
         try {
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 1e3b60f0e2d..a1823324f52 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
@@ -1077,6 +1077,7 @@ public class ModelParser extends BaseParser {
                 case "from": def.setInput(doParseFromDefinition()); break;
                 case "inputType": 
def.setInputType(doParseInputTypeDefinition()); break;
                 case "outputType": 
def.setOutputType(doParseOutputTypeDefinition()); break;
+                case "kamelet": 
def.setKamelet(Boolean.valueOf(doParseText())); break;
                 case "rest": def.setRest(Boolean.valueOf(doParseText())); 
break;
                 case "routeProperty": doAdd(doParsePropertyDefinition(), 
def.getRouteProperties(), def::setRouteProperties); break;
                 case "template": 
def.setTemplate(Boolean.valueOf(doParseText())); break;
diff --git 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
index b476ea80af6..4101ef5bc7b 100644
--- 
a/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
+++ 
b/core/camel-xml-io/src/generated/java/org/apache/camel/xml/out/ModelWriter.java
@@ -2098,6 +2098,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("logMask", def.getLogMask());
         doWriteAttribute("nodePrefixId", def.getNodePrefixId());
         doWriteAttribute("messageHistory", def.getMessageHistory());
+        doWriteAttribute("kamelet", toString(def.isKamelet()));
         doWriteAttribute("autoStartup", def.getAutoStartup());
         doWriteAttribute("delayer", def.getDelayer());
         doWriteAttribute("group", def.getGroup());
diff --git 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
index d0e72f25c78..16468140df5 100644
--- 
a/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
+++ 
b/core/camel-yaml-io/src/generated/java/org/apache/camel/yaml/out/ModelWriter.java
@@ -2098,6 +2098,7 @@ public class ModelWriter extends BaseWriter {
         doWriteAttribute("logMask", def.getLogMask());
         doWriteAttribute("nodePrefixId", def.getNodePrefixId());
         doWriteAttribute("messageHistory", def.getMessageHistory());
+        doWriteAttribute("kamelet", toString(def.isKamelet()));
         doWriteAttribute("autoStartup", def.getAutoStartup());
         doWriteAttribute("delayer", def.getDelayer());
         doWriteAttribute("group", def.getGroup());
diff --git 
a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc 
b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc
index d63ab7d76bd..379f81d2370 100644
--- a/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc
+++ b/docs/user-manual/modules/ROOT/pages/camel-4x-upgrade-guide-4_5.adoc
@@ -8,6 +8,10 @@ from both 4.0 to 4.1 and 4.1 to 4.2.
 
 === camel-core
 
+Camel startup summary will now report total number of routes without (internal 
routes created by Kamelets or Rest DSL).
+This ensures the total number better reflect the total number of user created 
routes. The summary now includes a separate
+number of Kamelets and Rest DSL routes. See also the camel-kamelet section.
+
 === Intercept EIP
 
 The `interceptFrom` and `interceptSentToEndpoint` EIPs is now storing the 
intercepted endpoint using key `Exchange.INTERCEPTED_ENDPOINT`
@@ -26,3 +30,20 @@ After:
 ----
 String uri = exchange.getProperty(Exchange.INTERCEPTED_ENDPOINT, String.class);
 ----
+
+=== camel-kamelet
+
+Routes created by Kamelets are no longer registered as JMX MBeans to avoid 
cluttering up with unwanted MBeans, as a Kamelet
+is intended to act like a Camel component, despite its implementation is Camel 
routes. This means that the number of routes
+listed from JMX will no longer include Kamelet routes.
+
+The old behaviour can be enabled by setting 
`registerRoutesCreateByKamelet=true`
+on the `ManagementAgent` object. See more in the xref:jmx.adoc[JMX] 
documentation.
+
+=== camel-micrometer and camel-metrics
+
+Due to Kamelets are changed to act more like a Camel component, and not expose 
internal details as JMX MBeans, then
+micrometer and metrics no longer include statistics for those Kamelet routes.
+
+The old behaviour can be enabled by setting 
`registerRoutesCreateByKamelet=true`
+on the `ManagementAgent` object. See more in the xref:jmx.adoc[JMX] 
documentation.
diff --git a/docs/user-manual/modules/ROOT/pages/jmx.adoc 
b/docs/user-manual/modules/ROOT/pages/jmx.adoc
index d428877efa6..705566d71b0 100644
--- a/docs/user-manual/modules/ROOT/pages/jmx.adoc
+++ b/docs/user-manual/modules/ROOT/pages/jmx.adoc
@@ -133,9 +133,9 @@ MBeans are registered at startup. The levels are:
 
 * `ContextOnly` -  Camel will register MBeans for the context (neither for any 
route nor for any processor).
 
-=== Registering new MBeans for new routes or endpoints
+=== Registering new MBeans for new routes, created by route templates, Kamelets
 
-Camel provides two settings to control when to register mbeans.
+Camel provides the following settings to control when to register mbeans.
 
 [width="100%",cols="34%,33%,33%",options="header",]
 |=======================================================================
@@ -145,6 +145,11 @@ Camel provides two settings to control when to register 
mbeans.
 |`registerNewRoutes` |`true` |If enabled then adding new routes after
 CamelContext has been started will also register
 MBeans from that given route.
+
+|`registerRoutesCreateByKamelet` |`false` |If enabled then adding routes 
created by Kamelet will also register MBeans from that given route.
+
+|`registerRoutesCreateByTemplate` |`true` |If enabled then adding routes 
created by route template (not Kamelet, see option above) will also register 
MBeans from that given route.
+
 |=======================================================================
 
 By default, Camel automatically registers MBeans for all routes configured at
@@ -153,6 +158,12 @@ registered for new routes added later on. This feature can 
be disabled, for
 example, if you are adding and removing temporary routes that do not require
 management.
 
+In *Camel 4.5* onwards there are additional options to configure whether 
routes created from route templates or Kamelets
+should be registered as MBeans or not. By default, Kamelets are now disabled 
with the intention to regard a Kamelet
+as a component, instead of a set of additional routes and processors MBeans 
that is essentially not needed for management
+and monitoring. The option `registerRoutesCreateByKamelet` can be set to 
`true` to enable MBeans which is how Camel 4.4 or
+older behaves. On the other hand routes created from route templates (not 
Kamelets) are default enabled.
+
 CAUTION: However, be cautious when using the `registerAlways` option in
 conjunction with dynamic EIP patterns, such as the 
xref:components:eips:recipientList-eip.adoc[Recipient List],
 which have unique endpoints. This can potentially lead to system degradation


Reply via email to