CAMEL-24106: camel-xslt - source option silently ignored when body is InputStream#24772
Conversation
… InputStream Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
|
🌟 Thank you for your contribution to the Apache Camel project! 🌟 🐫 Apache Camel Committers, please review the following items:
|
gnodet
left a comment
There was a problem hiding this comment.
Nice catch and clean fix.
The bug is clear: isInputStreamNeeded(exchange) short-circuits to transform the body before the source expression is ever evaluated. When the body is an InputStream (common with file:, http:, ftp:, or stream caching), source=header:x / source=variable:x / source=property:x is silently ignored — no error, wrong output.
The fix correctly evaluates the source expression first when configured, and only falls through to the isInputStreamNeeded optimization when no source expression is present. This aligns XmlSourceHandlerFactoryImpl with JsonSourceHandlerFactoryImpl in camel-xj, which already handles this correctly.
Checklist:
- ✅ Tests: 5 new tests covering header/variable/property sources with both raw InputStream and StreamCache bodies
- ✅ Test resource (
xslt/transform.xsl) already exists - ✅ No public API changes
- ✅ Backward compatible — no-source-expression code path unchanged
- ✅ No static analysis findings (ast-grep)
- ⏳ CI: builds in progress
Reviewed with Claude Code on behalf of gnodet. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.
|
🧪 CI tested the following changed modules:
🔬 Scalpel shadow comparison — Scalpel: 472 tested, 29 compile-only — current: 472 all testedMaveniverse Scalpel detected 501 affected modules (current approach: 472).
|
oscerd
left a comment
There was a problem hiding this comment.
LGTM. On main getSource(Exchange, Expression) calls isInputStreamNeeded(exchange) (which inspects the body) before ever looking at the source expression, so an InputStream/StreamCache body short-circuited and the source option was silently dropped. Evaluating source first fixes exactly that, and it's well-scoped: the source == null path is byte-identical to before, and when source is set the body stream is never read (no double-consume), with the result flowing through getSource(exchange, Object)'s SAX→Stream→DOM conversion — same pattern as camel-xj. Nice touch that camel-xslt-saxon only overrides the (Exchange, Object) overload, so it inherits the fix. Good test coverage (header/variable/property + two stream-caching cases).
Reviewed with Claude Code on behalf of Andrea Cosentino. This review was generated by an AI agent and may contain inaccuracies; please verify all suggestions before applying.
Summary
XmlSourceHandlerFactoryImpl.getSource(Exchange, Expression)checkedisInputStreamNeeded(exchange)against the message body before evaluating the configuredsourceexpression. When the body was anInputStream,StreamCache, or any type without a directSourceconverter — which is the common case withfile,http,ftp,nettyconsumers or stream caching —source=header:x/source=variable:x/source=property:xsilently transformed the body instead of the configured source. No error, wrong output.Fix
Evaluate the
sourceexpression first when it is configured, and pass the result directly to the type-based conversion method. TheisInputStreamNeededoptimization is only applied when no source expression is configured (i.e. the body is the intended input).This follows the same pattern already used by
JsonSourceHandlerFactoryImplincamel-xj, which correctly evaluates thesourceexpression before handling by type.Affected components
xslt— fix inXmlSourceHandlerFactoryImplxslt-saxon— inherits the fix (does not overridegetSource(Exchange, Expression))xj(XML→JSON) — not affected (already correct)Tests
Added
XsltSaxonSourceInputStreamBodyTestwith 5 tests covering:source=headerwithInputStreambodysource=variablewithInputStreambodysource=propertywithInputStreambodysource=headerwith stream caching enabled (body wrapped asStreamCache)source=variablewith stream caching enabledClaude Code on behalf of davsclaus