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]
