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 <[email protected]>
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