Repository navigation
CAMEL-24961: camel-yaml-dsl-validator - the body walks read the body types of the catalog instead of their own tables - #28246
Conversation
…s, and the body it leaves after a step A @BodyTypes annotation on the endpoint, data format or language class says the body per side (consumerOut, consumerReply, producerIn, producerOut, marshal, unmarshal and expression in and out): its carriers (null, text, bytes, stream, file, value, map, list, pojo, unchanged, any, unknown), the Java type when it is always the same, the format, the options it depends on, the body for other option values, and a description. The package plugin writes it as a bodyTypes section of the catalog JSON and checks that each side fits the kind and that the options it names exist. A subclass declares its own. The first slice: file, direct, seda, timer, cron, kamelet, http, https, rest-openapi, xslt, sql and the json data format (jackson), read from the code that sets the body and checked against the body types the message history records when routes run. camel_catalog_doc returns them. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
…tp, jms, kafka, aws2-sqs, the csv, jacksonXml and yaml data formats, and the languages The second slice of the catalog body types: - components: platform-http, rest (and the rest-openapi consumer), ftp, ftps, sftp, jms, activemq, activemq6, amqp, kafka, aws2-sqs, log, mock, scheduler, quartz; - data formats: csv, jacksonXml, snakeYaml; - languages: simple, constant, jsonpath, xpath, groovy, jq. Each value is read from the code that sets the body, and checked against the body types the message history recorded when the tests of the modules and reference routes ran (the ftp integration tests included). camel_catalog_doc gives the body types a line per side, and its answer is cut at 18000 characters instead of 16000, so the four sides of the jms components leave the options a limit asks for room. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
paho-mqtt5: the consumer gives the payload as a byte array, the producer sends what converts to one and leaves the body unchanged. mongodb: the consumer gives a Document (or null for a change without its full document with changeStreams); the producer takes a document or a query, and leaves a body by operation: a Document or null for a find of one, a List for findAll, findDistinct and aggregate, a Long for count, the result of the driver for the other writes. Read from the code that sets the body, and checked against a mosquitto and a mongodb container started with camel infra. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
…ts an option value without carriers
From the review of PR 28241:
- An iterator is read once and has no size and no index, so tooling that
reads list as a List accepts ${body.size()} or ${body[0]} on it, which fail
at runtime. The new iterator carrier names it: sql with outputType=StreamList
gives an iterator, not a list.
- A @BodyType.When with no carriers (carrier = {}) wrote "carriers": [] into
the catalog. The build now rejects it, as it does a side without carriers.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
…MEL-24961-catalog-body-types-2 Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
… camel_catalog_doc says unknown for no carriers From the review of PR 28242: - The csv data format with lazyLoad=true gives an iterator, with the iterator carrier of PR 28241, not a list. - camel_catalog_doc says unknown for a body without carriers, instead of failing. The build rejects it now, but a catalog read from elsewhere may have one. - Sqs2Endpoint imports org.apache.camel.spi.* already: only the import of the nested BodyType.Carrier stays. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
…types of the catalog instead of their own tables The YAML validator's body walks read what a component or a data format does with the body from the catalog, instead of from tables in their source: - the consumer a route starts with (consumerOut): the file as read, text, bytes or data, instead of the file consumer only; - the body after a to: (producerOut): unchanged for log and mock and now for a file write, the response of the http producer as bytes or a stream; - the producers that need text (producerIn), instead of file, ftp, ftps and sftp only; - the body after an unmarshal (unmarshalOut), instead of the json, jacksonXml, yaml and csv table and the options that make something else; - the consumers that reply with text (consumerReply), instead of platform-http; - the consumers that give no body, instead of timer, quartz, scheduler and cron. A side holds for a step only when the step decides every option it depends on: an option the component can also be configured with (the valueDeserializer of kafka) counts only when the endpoint sets it, and a placeholder value is not known. The catalog of an older Camel version has no body types, so the validator's own catalog stands in for it. After a step that fails at runtime the walk stops, so a file write that keeps the body is reported once. The rules about HTTP methods, REST bindings and EIPs stay in the validator; the EIPs get body types with CAMEL-25928. The same reports as before on 1204 human-written route files (the Camel repository, the examples, kamelets, camel-k and camel-kit) and on 1209 model-written ones (the r17 benchmark series), and the doc examples of the validator tests still validate. Co-Authored-By: Claude Opus 5.5 (1M context) <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-bot
left a comment
There was a problem hiding this comment.
LGTM. Clean refactoring that replaces the hardcoded body-type sets (NO_BODY_CONSUMER, KEEPS_THE_BODY, WRITES_A_FILE, PARSES, NOT_A_MAP) with catalog-driven lookups via the new CatalogBodyTypes class. The option-dependent logic in answer() is carefully designed, the fallback for older catalog versions is sound, and test coverage is thorough — including the new testACatalogWithoutBodyTypes test that validates the fallback path explicitly.
The body = null; continue addition after reporting a failing step (preventing cascading false positives on the same body) is a nice correctness fix as a side effect of this refactoring.
This review was generated by an AI agent, Hermès on behalf of @gnodet.
The attribute holds an array, and the catalog JSON and BodyTypeModel call the same field carriers. The Javadoc of BodyTypeModel.isUnknown() says that a side with no carriers is unknown too. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
…MEL-24961-catalog-body-types-2
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
…AMEL-24961-catalog-body-types-3
…e data format and language schemas Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
…-types' into feature/CAMEL-24961-catalog-body-types-2
…AMEL-24961-catalog-body-types-3
…n read as a list, as the carriers do Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
…AMEL-24961-catalog-body-types-3
…atalog-body-types-3 Signed-off-by: Claus Ibsen <claus.ibsen@gmail.com>
|
🧪 CI tested the following changed modules:
🔁 1 test passed only after a retry on JDK 21 (1 retried attempt) Recovered flaky tests on JDK 21 (1)
🔬 Scalpel shadow comparison — Scalpel: 7 of 707 tested, 9 compile-only — current: 7 all testedMaveniverse Scalpel detected 7 affected modules (current approach: 7). Skip-tests mode would test 7 modules (2 direct + 6 downstream), skip tests for 9 (generated code, meta-modules) Modules Scalpel would test (7)
Modules with tests skipped (9)
All tested modules (17 modules, 3m 52s total)Total reactor time: 3m 52s
Top 20 slowest modules:
|
Stacked on #28242. This is the third part of the catalog body types (CAMEL-24961): the YAML validator's body walks read the body types of the catalog instead of tables in their own source, so every component, data format and language that declares its body types is covered without a change to the validator.
What moved
consumerOutstreamDownload); aws2-sqs gives text; paho-mqtt5 gives bytes; sql gives a row as a MapKEEPS_THE_BODY: log, mockproducerOutunchangedwaitForTaskToComplete=NeverproducerOutoutput=DOM, a Document, which is neither text nor data); mongodbfindAllgives a ListWRITES_A_FILE: file, ftp, ftps, sftpproducerInPARSESandNOT_A_MAP: json, jacksonXml, yaml, csv;unmarshalType,lazyLoadunmarshalOutlazyLoadgives theiteratorcarrier of #28241, which is not a Map or a List; the options the side depends on also includecollectionTypeandallowUnmarshallType; gson, fastjson and jsonb have no body types yet, so they are not knownconsumerReplyNO_BODY_CONSUMER: timer, quartz, scheduler, cronconsumerOutnulldownload=falseNo guesses. A side holds for a step only when the step sets every option the side depends on, or the option keeps its default:
camel.component.kafka.valueDeserializerinapplication.propertieschanges the body of every kafka consumer, and the route file does not show it. So kafka stays silent, as before, and so does theoperationof aws2-sqs.A catalog of another Camel version.
camel validate --camel-version(CAMEL-24711) validates with the catalog of that version. An older catalog has no body types, so the validator's own catalog stands in for a model without them, and the walk keeps its rules, as it did with the tables.One report for a step that fails. A file write now keeps the body. Without a change, a second write after the first would be reported as well. As the first write fails at runtime, the walk stops after the step it reports.
What stays in the validator:
CamelHttpMethodheader;KEEPING_STEPS,SAME_BODY_BLOCKS), until the EIPs have body types (CAMEL-25928);BodyTypeFlow: the catalog says jsonpath reads any body, which is true, but it fails on no body.Message. "to: file writes the body to a file" is now "to: file needs the body as text, bytes, a stream or a file", from the carriers of the catalog. paho-mqtt5, and any producer annotated later, get the same sentence.
Measured. I ran the validator over two sets of route files, before and after:
The extra coverage found nothing new in these files, as none has those components in a failing shape. The value is that the rules are now data, and each component annotated next is checked.
Tests:
TextBodyFlowTest: the consumers and producers the catalog adds, the options a side depends on, what the component may configure (kafka, aws2-sqs, a placeholder), one report for a failing step, and a catalog without body types.BodyTypeFlowTest: cron, and ftp withdownload=false, give no body.EipDocExamplesTestvalidates (more than 1100, none with a report);Docs: the validation page of the Camel CLI says the body walk reads the catalog, and what it stays silent on. The catalog page says the validator uses the body types.
Claude Code on behalf of davsclaus
🤖 Generated with Claude Code