Skip to content

CAMEL-23521: camel-core - XML route dumping is missing target element closing tags#23305

Merged
davsclaus merged 3 commits into
mainfrom
fix/camel-23521-xml-dump-missing-closing-tags
May 19, 2026
Merged

CAMEL-23521: camel-core - XML route dumping is missing target element closing tags#23305
davsclaus merged 3 commits into
mainfrom
fix/camel-23521-xml-dump-missing-closing-tags

Conversation

@davsclaus
Copy link
Copy Markdown
Contributor

Summary

Fixes CAMEL-23521: When XML route dumping is performed via DefaultDumpRoutesStrategy, the output contains the opening <routes>, <rests>, or <routeTemplates> tag with its namespace attribute but is missing the corresponding closing tag, producing malformed XML.

Root cause: doDumpXml() strips the outer container element by matching its opening and closing tags via simple string replacement. The old JAXB/Spring dumper emitted xmlns="http://camel.apache.org/schema/spring", which was explicitly stripped first to produce a bare <routes>. The lightweight xml-io dumper (LwModelToXMLDumper, the current default) uses xmlns="http://camel.apache.org/schema/xml-io" instead. Because only the Spring namespace was handled, the regex <routes> never matched the opening tag (which still had the xml-io namespace attribute), but </routes> (no attributes) was correctly matched and removed — leaving an orphaned opening tag.

Fix: Replace the exact <routes> string match with a regex <routes(?:\s[^>]*)?> that matches the opening tag with or without any namespace/xmlns attributes. This handles both dumpers (xml-io and Spring/JAXB) and any future dumpers regardless of their namespace conventions.

Changes

  • core/camel-core-engine/src/main/java/org/apache/camel/impl/DefaultDumpRoutesStrategy.java — fix in doDumpXml(): use regex to match outer container opening tag with optional attributes
  • core/camel-core/src/test/java/org/apache/camel/impl/DefaultDumpRoutesStrategyXmlTest.java — new test verifying that dumped XML has correct structure (outer containers stripped, individual elements properly closed, <camel> wrapper present)

Test plan

  • New test DefaultDumpRoutesStrategyXmlTest.testDumpXmlHasCorrectStructure verifies that routes and routeTemplates dump files are well-structured (outer container stripped, individual elements present and closed, <camel> wrapper intact)
  • All existing DumpModel* tests pass
  • Full root build (mvn clean install -DskipTests) passes

Claude Code on behalf of Claus Ibsen

… closing tags

The doDumpXml() method in DefaultDumpRoutesStrategy was stripping the outer
container element (routes, rests, routeTemplates) using simple string matching.
The opening tag removal only matched bare `<routes>` but the LwModelToXMLDumper
(the default xml-io based dumper) always emits a namespace attribute:
`<routes xmlns="http://camel.apache.org/schema/xml-io">`.

This caused the opening container tag to remain in the output while the closing
tag was correctly removed, producing malformed XML in both logged and file output.

Fix: use a regex that matches the opening container tag with or without any
namespace/xmlns attributes, so both opening and closing tags are consistently
stripped regardless of which dumper is in use.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
@github-actions github-actions Bot added the core label May 18, 2026
@github-actions
Copy link
Copy Markdown
Contributor

🌟 Thank you for your contribution to the Apache Camel project! 🌟
🤖 CI automation will test this PR automatically.

🐫 Apache Camel Committers, please review the following items:

  • First-time contributors require MANUAL approval for the GitHub Actions to run
  • You can use the command /component-test (camel-)component-name1 (camel-)component-name2.. to request a test from the test bot although they are normally detected and executed by CI.
  • You can label PRs using skip-tests and test-dependents to fine-tune the checks executed by this PR.
  • Build and test logs are available in the summary page. Only Apache Camel committers have access to the summary.

⚠️ Be careful when sharing logs. Review their contents before sharing them publicly.

Comment on lines +64 to +75
assertTrue(xml.contains("<camel>"), "Expected <camel> root wrapper");
assertTrue(xml.contains("</camel>"), "Expected </camel> root wrapper closing tag");

// outer container tags must be stripped entirely (both opening and closing) - CAMEL-23521
assertFalse(xml.contains("<routes"), "Outer <routes> wrapper must be stripped");
assertFalse(xml.contains("<routeTemplates"), "Outer <routeTemplates> wrapper must be stripped");

// individual route elements must be present and properly closed
assertTrue(xml.contains("<route "), "Expected individual <route> elements");
assertTrue(xml.contains("</route>"), "Expected </route> closing tag");
assertTrue(xml.contains("<routeTemplate "), "Expected individual <routeTemplate> elements");
assertTrue(xml.contains("</routeTemplate>"), "Expected </routeTemplate> closing tag");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

using AssertJ/XMLUnit, it would help to have better readability when the test is failing. For instance to show what is current content of xml

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done — switched all assertions to AssertJ assertThat(...).as("...\nActual xml:\n%s", xml).contains(...) / doesNotContain(...). When a check fails, the full dumped XML is now included in the failure message, which makes debugging much easier. Committed in d6c7492.

Claude Code on behalf of Claus Ibsen

@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented May 18, 2026

🧪 CI tested the following changed modules:

  • core/camel-core-engine
  • core/camel-core

ℹ️ Dependent modules were not tested because the total number of affected modules exceeded the threshold (50). Use the test-dependents label to force testing all dependents.

⚠️ Some tests are disabled on GitHub Actions (@DisabledIfSystemProperty(named = "ci.env.name")) and require manual verification:

  • core/camel-core: 2 test(s) disabled on GitHub Actions
Build reactor — dependencies compiled but only changed modules were tested (2 modules)
  • Camel :: Core
  • Camel :: Core Engine

⚙️ View full build and test results

Switch assertions in DefaultDumpRoutesStrategyXmlTest from JUnit
assertTrue/assertFalse to AssertJ assertThat, so that the actual XML
content is included in the failure message when an assertion fails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@davsclaus davsclaus merged commit c70e46c into main May 19, 2026
6 checks passed
@davsclaus davsclaus deleted the fix/camel-23521-xml-dump-missing-closing-tags branch May 19, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants