This is an automated email from the ASF dual-hosted git repository.
oscerd pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/camel-kafka-connector.git
The following commit(s) were added to refs/heads/main by this push:
new e969b4503e Fix #1860: make camel.connector.dumpRoutes dump the routes,
disabled by default (#1864)
e969b4503e is described below
commit e969b4503e56fdd412f2bac27bf4db3fe38f0a67
Author: Andrea Cosentino <[email protected]>
AuthorDate: Thu Nov 5 13:08:16 2026 +0100
Fix #1860: make camel.connector.dumpRoutes dump the routes, disabled by
default (#1864)
CamelKafkaConnectMain passed the boolean option to Camel Main as the
string "true", but in Camel 4 dumpRoutes is the format of the dump
(xml, yaml or java), so nothing was ever dumped.
- When camel.connector.dumpRoutes is true, dump the routes as XML, the
format every connector can write with the camel-xml-jaxb dependency of
core.
- Default the option to false: Camel resolves property placeholders in
a route dump, so it can contain configuration values. Since nothing
was dumped before, users see no difference.
- Document the option in the basic configuration tables.
Signed-off-by: Andrea Cosentino <[email protected]>
Co-authored-by: Claude Opus 5.5 <[email protected]>
---
.../camel/kafkaconnector/CamelConnectorConfig.java | 5 +-
.../utils/CamelKafkaConnectMain.java | 8 +-
.../camel/kafkaconnector/DumpRoutesTest.java | 120 +++++++++++++++++++++
.../ROOT/pages/user-guide/basic-configuration.adoc | 2 +
4 files changed, 131 insertions(+), 4 deletions(-)
diff --git
a/core/src/main/java/org/apache/camel/kafkaconnector/CamelConnectorConfig.java
b/core/src/main/java/org/apache/camel/kafkaconnector/CamelConnectorConfig.java
index 0bd3797762..98980bf419 100644
---
a/core/src/main/java/org/apache/camel/kafkaconnector/CamelConnectorConfig.java
+++
b/core/src/main/java/org/apache/camel/kafkaconnector/CamelConnectorConfig.java
@@ -98,9 +98,10 @@ public abstract class CamelConnectorConfig extends
AbstractConfig {
public static final String
CAMEL_CONNECTOR_IDEMPOTENCY_KAFKA_POLL_DURATION_CONF =
"camel.idempotency.kafka.poll.duration.ms";
public static final String
CAMEL_CONNECTOR_IDEMPOTENCY_KAFKA_POLL_DURATION_DOC = "Sets the poll duration
(in milliseconds) of the Kafka consumer";
- public static final Boolean CAMEL_CONNECTOR_DUMP_ROUTES_DEFAULT = true;
+ public static final Boolean CAMEL_CONNECTOR_DUMP_ROUTES_DEFAULT = false;
public static final String CAMEL_CONNECTOR_DUMP_ROUTES_CONF =
"camel.connector.dumpRoutes";
- public static final String CAMEL_CONNECTOR_DUMP_ROUTES_DOC = "Whether to
dump Camel routes on startup";
+ public static final String CAMEL_CONNECTOR_DUMP_ROUTES_DOC = "Whether to
log the Camel routes of the task as XML when it starts."
+ + " Camel resolves property placeholders in the dump, so it can
contain configuration values";
protected CamelConnectorConfig(ConfigDef definition, Map<?, ?> originals,
Map<String, ?> configProviderProps, boolean doLog) {
super(definition, originals, configProviderProps, doLog);
diff --git
a/core/src/main/java/org/apache/camel/kafkaconnector/utils/CamelKafkaConnectMain.java
b/core/src/main/java/org/apache/camel/kafkaconnector/utils/CamelKafkaConnectMain.java
index 87d2a825b3..183e9ceada 100644
---
a/core/src/main/java/org/apache/camel/kafkaconnector/utils/CamelKafkaConnectMain.java
+++
b/core/src/main/java/org/apache/camel/kafkaconnector/utils/CamelKafkaConnectMain.java
@@ -44,6 +44,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CamelKafkaConnectMain extends SimpleMain {
+ public static final String DUMP_ROUTES_FORMAT = "xml";
public static final String KAMELET_MARSHAL_TEMPLATE_PARAMETERS_PREFIX =
"camel.kamelet.ckcMarshal.";
public static final String KAMELET_UNMARSHAL_TEMPLATE_PARAMETERS_PREFIX =
"camel.kamelet.ckcUnMarshal.";
public static final String KAMELET_AGGREGATORL_TEMPLATE_PARAMETERS_PREFIX
= "camel.kamelet.ckcAggregator.";
@@ -122,7 +123,7 @@ public class CamelKafkaConnectMain extends SimpleMain {
private String headersExcludePattern;
private boolean removeHeadersFirst;
private UnaryOperator<AggregationStrategy>
aggregationStrategyDecorator;
- private boolean dumpRoutes = true;
+ private boolean dumpRoutes;
public Builder(String from, String to) {
this.from = from;
@@ -271,7 +272,10 @@ public class CamelKafkaConnectMain extends SimpleMain {
public CamelKafkaConnectMain build(CamelContext camelContext) {
CamelKafkaConnectMain camelMain = new
CamelKafkaConnectMain(camelContext);
camelMain.configure().setAutoConfigurationLogSummary(false);
- camelMain.configure().setDumpRoutes(Boolean.toString(dumpRoutes));
+ if (dumpRoutes) {
+ // Camel 4 takes the format of the dump, not a flag: XML is
the format the jars of every connector can write
+ camelMain.configure().setDumpRoutes(DUMP_ROUTES_FORMAT);
+ }
Properties camelProperties = new Properties();
camelProperties.putAll(props);
diff --git
a/core/src/test/java/org/apache/camel/kafkaconnector/DumpRoutesTest.java
b/core/src/test/java/org/apache/camel/kafkaconnector/DumpRoutesTest.java
new file mode 100644
index 0000000000..514137646b
--- /dev/null
+++ b/core/src/test/java/org/apache/camel/kafkaconnector/DumpRoutesTest.java
@@ -0,0 +1,120 @@
+/*
+ * 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.kafkaconnector;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import org.apache.camel.impl.DefaultDumpRoutesStrategy;
+import org.apache.camel.kafkaconnector.utils.CamelKafkaConnectMain;
+import org.apache.logging.log4j.Level;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.core.LogEvent;
+import org.apache.logging.log4j.core.LoggerContext;
+import org.apache.logging.log4j.core.appender.AbstractAppender;
+import org.apache.logging.log4j.core.config.Configuration;
+import org.apache.logging.log4j.core.config.LoggerConfig;
+import org.apache.logging.log4j.core.config.Property;
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+public class DumpRoutesTest {
+
+ private CapturingAppender appender;
+ private LoggerConfig loggerConfig;
+
+ @BeforeEach
+ public void attachAppender() {
+ appender = new CapturingAppender();
+ appender.start();
+
+ LoggerContext context = (LoggerContext) LogManager.getContext(false);
+ Configuration configuration = context.getConfiguration();
+ configuration.addAppender(appender);
+ loggerConfig = new
LoggerConfig(DefaultDumpRoutesStrategy.class.getName(), Level.INFO, true);
+ loggerConfig.addAppender(appender, Level.INFO, null);
+ configuration.addLogger(DefaultDumpRoutesStrategy.class.getName(),
loggerConfig);
+ context.updateLoggers();
+ }
+
+ @AfterEach
+ public void detachAppender() {
+ LoggerContext context = (LoggerContext) LogManager.getContext(false);
+
context.getConfiguration().removeLogger(DefaultDumpRoutesStrategy.class.getName());
+ appender.stop();
+ context.updateLoggers();
+ }
+
+ private CamelSourceTask startSourceTask(Map<String, String> extraProps) {
+ Map<String, String> props = new HashMap<>(extraProps);
+ props.put(CamelSourceConnectorConfig.TOPIC_CONF, "my-topic");
+ props.put(CamelSourceConnectorConfig.CAMEL_SOURCE_URL_CONF,
"direct:start");
+
+ CamelSourceTask sourceTask = new CamelSourceTask();
+ sourceTask.start(props);
+ return sourceTask;
+ }
+
+ @Test
+ public void testRoutesAreDumpedAsXmlWhenEnabled() {
+ CamelSourceTask sourceTask = startSourceTask(
+
Collections.singletonMap(CamelConnectorConfig.CAMEL_CONNECTOR_DUMP_ROUTES_CONF,
"true"));
+ try {
+ assertEquals(CamelKafkaConnectMain.DUMP_ROUTES_FORMAT,
sourceTask.getCms().getCamelContext().getDumpRoutes());
+ assertTrue(appender.messages.stream().anyMatch(m ->
m.startsWith("Dumping") && m.endsWith("routes as XML")),
+ "the routes should be dumped as XML: " +
appender.messages);
+ assertTrue(appender.messages.stream().anyMatch(m ->
m.contains("<route")),
+ "the dump should contain the routes: " +
appender.messages);
+ } finally {
+ sourceTask.stop();
+ }
+ }
+
+ @Test
+ public void testRoutesAreNotDumpedByDefault() {
+ CamelSourceTask sourceTask = startSourceTask(Collections.emptyMap());
+ try {
+ assertNull(sourceTask.getCms().getCamelContext().getDumpRoutes());
+ assertFalse(appender.messages.stream().anyMatch(m ->
m.startsWith("Dumping")),
+ "no route dump expected: " + appender.messages);
+ } finally {
+ sourceTask.stop();
+ }
+ }
+
+ private static final class CapturingAppender extends AbstractAppender {
+ private final List<String> messages = Collections.synchronizedList(new
ArrayList<>());
+
+ CapturingAppender() {
+ super("dump-routes-capture", null, null, true,
Property.EMPTY_ARRAY);
+ }
+
+ @Override
+ public void append(LogEvent event) {
+ messages.add(event.getMessage().getFormattedMessage());
+ }
+ }
+}
diff --git a/docs/modules/ROOT/pages/user-guide/basic-configuration.adoc
b/docs/modules/ROOT/pages/user-guide/basic-configuration.adoc
index f9927db862..53d2a55204 100644
--- a/docs/modules/ROOT/pages/user-guide/basic-configuration.adoc
+++ b/docs/modules/ROOT/pages/user-guide/basic-configuration.adoc
@@ -18,6 +18,7 @@ For a Sink connector the basic options are:
| camel.error.handler.max.redeliveries | The maximum redeliveries to be use in
case of Default Error Handler | 0 | MEDIUM
| camel.error.handler.redelivery.delay | The initial redelivery delay in
milliseconds in case of Default Error Handler | 1000L | MEDIUM
| camel.remove.headers.pattern | The pattern of the headers we want to exclude
from the exchange | null | MEDIUM
+| camel.connector.dumpRoutes | Whether to log the Camel routes of the task as
XML when it starts. Camel resolves property placeholders in the dump, so it can
contain configuration values: keep it disabled in production. | false | LOW
| camel.idempotency.enabled | If idempotency must be enabled or not | false |
LOW
| camel.idempotency.repository.type | The idempotent repository type to use,
possible values are memory and kafka | memory | LOW
| camel.idempotency.expression.type | How the idempotency will be evaluated:
possible values are body and header | body | LOW
@@ -50,6 +51,7 @@ For a Source connector the basic options are:
| camel.error.handler.max.redeliveries | The maximum redeliveries to be use in
case of Default Error Handler | 0 | MEDIUM
| camel.error.handler.redelivery.delay | The initial redelivery delay in
milliseconds in case of Default Error Handler | 1000L | MEDIUM
| camel.remove.headers.pattern | The pattern of the headers we want to exclude
from the exchange | null | MEDIUM
+| camel.connector.dumpRoutes | Whether to log the Camel routes of the task as
XML when it starts. Camel resolves property placeholders in the dump, so it can
contain configuration values: keep it disabled in production. | false | LOW
| camel.idempotency.enabled | If idempotency must be enabled or not | false |
LOW
| camel.idempotency.repository.type | The idempotent repository type to use,
possible values are memory and kafka | memory | LOW
| camel.idempotency.expression.type | How the idempotency will be evaluated:
possible values are body and header | body | LOW