shashank created CAMEL-25721:
--------------------------------
Summary: Route dumps (XML, YAML, Java) leave out an option set to
its documented default, so a verb bindingMode off, an onException
redeliveryDelay or a circuit breaker timeoutEnabled false take the parent value
once the dump is loaded
Key: CAMEL-25721
URL: https://issues.apache.org/jira/browse/CAMEL-25721
Project: Camel
Issue Type: Bug
Components: camel-core
Reporter: shashank
Assignee: shashank
The model writers behind the route dumps ({{LwModelToXMLDumper}},
{{LwModelToYAMLDumper}}, {{LwModelToJavaDumper}}; used by {{camel transform
route}}, {{camel validate normalize}}, {{camel.main.dumpRoutes}} and the
developer console) skip an attribute whose value equals the {{defaultValue}} of
its {{@Metadata}}: the generated calls are {{doWriteAttribute("bindingMode",
def.getBindingMode(), "off")}}, and the base method writes nothing when the
value equals the default (main 9fb9bc911f78: {{YamlModelWriterSupport}} line
61, {{ModelWriter}} line 4025, {{JavaDslModelWriterSupport}} line 604).
That is only safe when "not set" means "the default". For many options it does
not: an option that is not set takes the value of a parent level. When a route
sets such an option to the documented default on purpose, the dump drops it,
and the dumped route, once loaded, runs with the parent's value. Nothing is
logged. Examples, each run on main (loaded from YAML, dumped as YAML and as
XML, loaded again):
* *rest / verb*: {{bindingMode}}, {{skipBindingOnErrorCode}},
{{clientRequestValidation}}, {{clientResponseValidation}}, {{enableCORS}},
{{enableNoContentResponse}} not set take the value of the rest, then of the
rest configuration ({{RestDefinition}} lines 1133-1201, {{RestBindingReifier}}
lines 47-75). A verb with {{bindingMode: "off"}} under
{{camel.rest.bindingMode=json}} replies {{{"format":"raw"}}} instead of the
body as it is; a verb with {{clientRequestValidation: false}} under a rest
configuration that validates answers 415 instead of 200.
* {{skipBindingOnErrorCode}} is documented with default {{false}}, but
{{RestConfiguration}} (camel-api line 84) defaults to {{true}}: a verb with
{{skipBindingOnErrorCode: false}} and the default rest configuration binds its
error replies to JSON; after the dump they are no longer bound ({{{error=bad
request}}} instead of {{{"error":"bad request"}}}).
* *redelivery policy of an onException*:
{{ExceptionPolicy.createRedeliveryPolicy}} copies the error handler's policy
and overrides only the options that are set. An {{onException}} with
{{redeliveryDelay: 1000}} under an error handler with {{redeliveryDelay:
30000}} redelivers after 1 s; after the dump after 30 s. The same for
{{logStackTrace}}, {{logExhausted}}, {{retryAttemptedLogLevel}},
{{backOffMultiplier}}, {{maximumRedeliveryDelay}},
{{allowRedeliveryWhileStopping}} and the others that have a default.
* *circuit breaker*: {{ResilienceReifier.buildResilience4jConfiguration}}
layers the global configuration ({{camel.resilience4j.*}}), the referenced one
and the local one. A {{resilience4jConfiguration}} with {{timeoutEnabled:
false}} under a global {{timeoutEnabled=true}} runs without a timeout; after
the dump the call times out and goes to the fallback. The same for the other
options with a default and for {{faultToleranceConfiguration}}.
* *route*: {{shutdownRoute: Default}} / {{shutdownRunningTask:
CompleteCurrentTaskOnly}} not set take the CamelContext's value
({{DefaultRoute}} lines 611-631).
{{camel validate normalize}} is recommended by the YAML compact-notation
warning and users copy its output over their files (CAMEL-25490); {{camel
transform route}} turns Java and XML routes into YAML (CAMEL-25202). In both
cases the routes the user gets back run differently. The JAXB dumper
(camel-xml-jaxb) writes every attribute that is set.
Trigger: default options; any of the options above set explicitly to its
documented default, in a context where the parent level has another value (and
for {{skipBindingOnErrorCode: false}} even with the default rest configuration).
h3. Reproduction
New tests (dump the loaded routes and run both):
* {{YamlDumpExplicitDefaultValuesTest}} (camel-yaml-dsl, 3 tests): on main
{{expected: "\{format=raw\}" but was: "\{"format":"raw"\}"}}, {{expected:
"\{"error":"bad request"\}" but was: "\{error=bad request\}"}}, {{expected:
"handled" but was: "not redelivered within 10 seconds"}}.
* {{XmlDumpExplicitDefaultValuesTest}} (camel-xml-io-dsl, 2 tests): {{expected:
<200 stored> but was: <415 null>}}, {{expected: <handled> but was: <not
redelivered within 10 seconds>}}.
* {{LwModelToJavaDumperTest.testDumpOptionsSetToTheirDefaultValue}}
(camel-java-io): {{.bindingMode("off")}} and {{.redeliveryDelay("1000")}}
missing from the Java dump.
h3. Proposed fix
The writer each dumper creates writes these options whenever they are set: the
six rest binding options and the route {{shutdownRoute}} /
{{shutdownRunningTask}} by name, and every option of a redelivery policy, a
{{resilience4jConfiguration}} and a {{faultToleranceConfiguration}} (while that
element is written). Other options keep being left out at their default, so
dumps of Java routes do not fill up with values the model or the Java DSL set
by default (writing every set option was tried first: the Java DSL sets
{{pretty="false"}} on every {{simple}}, a {{json}} data format its {{library}},
and the camel-java-io round-trip tests showed it). The generated writers and
their templates are not changed. Note in the 4.24 upgrade guide.
Not changed: the documented default of {{skipBindingOnErrorCode}} ({{false}})
does not match the runtime default ({{true}}); worth its own docs fix.
Affected: main (tested); camel-4.23.x and camel-4.22.x have the same writers
(read, not run); camel-4.18.x XML dump the same (read), its YAML writer differs
(not checked).
Duplicate check (2026-10-17): JIRA text "dump default value", "dumper default",
"route dump bindingMode", "YAML dump redeliveryDelay", "ModelWriter default",
"skipBindingOnErrorCode default", "dump errorHandler": only CAMEL-25651 /
CAMEL-25493 (top-level errorHandler and intercepts dropped, a different cause),
CAMEL-25079 / CAMEL-25255 (other dumper gaps, resolved). GitHub pull requests
"dump default value", "LwModelToYAMLDumper doWriteAttribute", "CAMEL-25651":
none about this.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)