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

   # Description
   
   Fixes [CAMEL-24847](https://issues.apache.org/jira/browse/CAMEL-24847).
   
   People write the data format the way its artifact or library is named:
   
   ```yaml
   - unmarshal:
       jackson: {}
   - marshal:
       json-jackson: {}
   - unmarshal:
       jackson-xml: {}
   ```
   
   `camel validate yaml` (and the MCP/TUI validation, which share 
`YamlValidator`) answered `property 'jackson' is not defined in the schema and 
the schema does not allow additional properties`, the runtime `Error 
constructing YAML node id: unmarshal: unsupported field: jackson`. Neither 
named the data format that was meant.
   
   ## Why
   
   The YAML key is the data format's **model name** (`json`, `jacksonXml`, 
`yaml`). Ten catalog data formats have a name of their own because one model 
serves several libraries or types: `jackson`, `gson`, `jsonb`, `fastjson` → 
`json` + `library`; `avroJackson` → `avro`; `protobufJackson` → `protobuf`; 
`snakeYaml` → `yaml`; `bindyCsv`/`bindyFixed`/`bindyKvp` → `bindy` + `type`. 
The validator's only recovery was edit distance against the schema keys, which 
fails exactly where the two naming schemes diverge — and gave two *wrong* 
answers: `gson → json` (silently the wrong library) and `bindy-csv → csv` (the 
wrong data format).
   
   ## What changed
   
   - **`DataFormatKeyHints`** (new, `camel-yaml-dsl-common`): the alias table 
with the selecting option, and the spellings people use (`jackson`, `Jackson`, 
`json-jackson`, `jackson-json`, `jackson-avro`, `bindy_csv`, `snake-yaml`). It 
lives in `common` because the runtime deserializer has no catalog; a new 
validator test (`DataFormatKeyHintsCatalogTest`) checks the table agrees with 
the catalog — every data format whose `name` ≠ `modelName` is in it, with the 
model name as key and a value from the model's `library`/`type` enum.
   - **Validator** (`SchemaHints.PROPERTY` row for `marshal|unmarshal` + 
`YamlValidator.dataFormatHint`), in order:
     1. the key spelled differently → `did you mean 'jacksonXml'?` 
(`jackson-xml`, `JSON`, `base-64`)
     2. an alias → `the data format is json, Jackson is its library: write 
json: {library: Jackson}`
     3. the catalog's `suggestDataFormatNames` (CAMEL-24658) for a word of a 
name → `did you mean fhirXml, groovyXml or jacksonXml?` (`xml`), `did you mean 
'gzipDeflater'?` (`gzip`)
     4. the closest key for a typo → `jsn → json`, `yml → yaml`
     5. otherwise what the key is: `the key of unmarshal is the data format: 
json, jacksonXml, csv, yaml, jaxb, avro, protobuf...; camel catalog dataformat 
lists them`
   - **Canonical mode**: the `must have exactly one of [50 data format keys] 
but found none` line that `checkOneOfCardinality` appended at the same location 
as the hinted unknown key is dropped — it only buried the hint.
   - **Runtime** (`YamlDeserializationContext`): for `marshal`/`unmarshal` the 
`unsupported field` message gets the same hint, from the table and the 
deserializer's declared `@YamlType` property names (no catalog needed). The 
runtime already accepts `jackson-xml` (`dashToCamelCase`), so only the aliases 
and case slips reach it.
   
   ## Before / after
   
   | Input | Before | After |
   |---|---|---|
   | `jackson` | *(no hint)* | `the data format is json, Jackson is its 
library: write json: {library: Jackson}` |
   | `json-jackson` | *(no hint)* | same |
   | `jackson-xml` | `did you mean 'jacksonXml'?` | unchanged |
   | `gson` | `did you mean 'json'?` ❌ | `write json: {library: Gson}` |
   | `bindy-csv` | `did you mean 'csv'?` ❌ | `the data format is bindy, Csv is 
its type: write bindy: {type: Csv}` |
   | `xml` | `did you mean 'ubl'?` ❌ | `did you mean fhirXml, groovyXml or 
jacksonXml?` |
   | `xstream` | *(no hint)* | `the key of unmarshal is the data format: ...` |
   | canonical, any of the above | + a 50-key `oneOf` line | hint only |
   
   ## Testing
   
   - `YamlValidatorPropertyHintTest`: 7 new tests (alias, artifact name, 
spelling, catalog words, typo, unknown, canonical).
   - `DataFormatKeyHintsCatalogTest` (new): table ↔ catalog agreement; 
spellings.
   - `UnmarshalTest.groovy`: 6 new runtime cases.
   - `camel-yaml-dsl-common` and `camel-yaml-dsl-validator`: `mvn install 
-Psourcecheck` BUILD SUCCESS (9 + 125 tests); `camel-yaml-dsl` 
Marshal/Unmarshal/OnException tests; `camel-jbang-core` `SourceValidator*` 
tests (111) pass.
   - `formatter:format impsort:sort` applied. No generated files: the change 
touches no component/model metadata. The full root build was not run.
   
   No upgrade-guide entry: diagnostic text only. Not touched: the 
compact-notation row also fires for `unmarshal: {jsonpath: ...}` in canonical 
mode (pre-existing, unrelated).
   
   # Target
   
   - [x] I checked that the commit is targeting the correct branch (Camel 4 
uses the `main` branch)
   
   # Tracking
   - [x] If this is a large change, bug fix, or code improvement, I checked 
there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for 
the change (usually before you start working on it).
   
   # Apache Camel coding standards and style
   
   - [x] I checked that each commit in the pull request has a meaningful 
subject line and body.
   - [ ] I have run `mvn clean install -DskipTests` locally from root folder 
and I have committed all auto-generated changes.
   
   # AI-assisted contributions
   
   - [x] If this PR includes AI-generated code, commits have proper 
co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR 
description identifies the AI tool used.
   
   _Claude Code on behalf of 
   
   🤖 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