davsclaus opened a new pull request, #28047:
URL: https://github.com/apache/camel/pull/28047

   ## What
   
   Quick win 2 of the plan on 
[CAMEL-24844](https://issues.apache.org/jira/browse/CAMEL-24844) (comment of 
2026-10-18).
   
   After `unmarshal` (json, jacksonXml, yaml, csv) the body is a Map or a List. 
The YAML validator's body walk (`TextBodyFlow`) now carries that state and 
reports it where a step needs text and fails at runtime with *"No type 
converter available to convert from type: java.util.LinkedHashMap to the 
required type: java.io.InputStream"*:
   
   - a `to: file` (ftp, ftps, sftp) that writes it;
   - an http producer that sends it with POST;
   - the end of a `platform-http` route, where the body is the reply.
   
   The state survives the steps that keep the body (setHeader, log...), a 
Groovy collection call whose result is data again (`body.findAll {...}`, or 
`body.find { it.sku == ... }`, which picks an element whose fields it reads), a 
`to: direct:` route that returns it, and a `split` of the body or a field of it 
whose steps read fields of each element.
   
   Example (what the local model wrote in the benchmark; `toD` meant a GET 
lookup):
   
   ```
   route check-stock: toD: http sends the body as the request (a message with a 
body is sent as a POST), but the body here is
   parsed data (a Map or a List), not text - unmarshal: json turns the text 
into data, and split ${body[lines]} gives its
   elements as data: add marshal: json before this step, or set httpMethod: GET 
when the call sends no body
   ```
   
   ## Staying quiet where it is not certain
   
   These are validation errors, so the walk only reports what will fail:
   
   - **http producer.** Only in a route whose consumer brings no HTTP headers 
(file, ftp, sftp, timer, scheduler, cron, quartz). After an HTTP consumer, the 
request's `CamelHttpMethod` header picks the method. It also stays silent when 
the route sets or reads a `CamelHttp*` header, the uri has a query, a parameter 
is not an http producer option (camel-http is lenient: unknown parameters 
become the query, which makes it a GET), or `httpMethod` is not POST/PUT/PATCH.
   - **unmarshal.** `unmarshalType`/`unmarshalTypeName` (an object) and csv 
`lazyLoad` (an iterator) make the body unknown.
   - **Groovy.** Anything after the closure (`body.find {...}?.qty`), or a 
`find` whose closure does not read fields of the element, makes the body 
unknown.
   - **split.** Unknown when no step reads a field of the element before 
changing it, since a List may hold text.
   
   ## Measured
   
   | corpus | route files | reports |
   |---|---|---|
   | human-written YAML: camel (docs, tests), camel-jbang-examples, 
camel-examples, camel-kamelets, camel-k, camel-kit, camel-spring-boot-examples, 
camel-quarkus-examples | 1101 | 0 |
   | benchmark output: final files of every series | 14251 | 2, both real (a 
Map written with `to: file` in both branches of a choice) |
   | r17 series: every intermediate version the model wrote, rebuilt from the 
traces | 1169 | 3, in 2 of the 3 `connect-http-client` runs that failed on this 
collision |
   
   Walking into a split also reaches one more real bug of the existing text 
rule: a `${body.qty}` read after a simple template set the body to text, inside 
a split (r17-8, contracts-openapi-client).
   
   ## Not in this PR
   
   In r17, 14 of the 17 body type collisions were parsed data reaching 
something that needs text. This PR catches the 2 above. Most of the rest need 
facts that only the caller (camel-jbang) has:
   
   - **rest-openapi producer (6):** the operation's verb is in the 
specification.
   - **REST DSL / contract-first replies (3):** the binding mode can be set in 
`application.properties` (`camel.rest.bindingMode`), which the validator does 
not see; contract-first operations are in the specification.
   - **a file write in a called `direct:` route (2):** reports are made from 
the route's own walk, which starts unknown.
   
   Proposed next step: camel-jbang passes these project facts to the validator, 
as it already passes the bodyless endpoints of the OpenAPI specification.
   
   _Claude Code on behalf of davsclaus_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to