davsclaus opened a new pull request, #28178: URL: https://github.com/apache/camel/pull/28178
The message history records the body type at each node, but only for one exchange: `camel history` shows the last one. This keeps, per node, every type the node has been reached with across all the messages, so a tool can show what the body was at each step. That includes a branch the last message did not take, and every type where they varied. It's the first part of [CAMEL-25750](https://issues.apache.org/jira/browse/CAMEL-25750); the validator part follows. ## What it adds - **`BodyTypeRegistry`** (camel-api SPI, a context plugin): per route and node, the distinct body types in the order first seen, at most 8 per node. Each type also has a **kind**, for what a step can do with it: - `null`; - `payload`: text, bytes, a stream, a file, or a single value such as a number; - `data`: a Map, a List or an object; - `iterator`. A step reached with types of one kind is dynamic. A step reached with **more than one kind needs attention**: a step that writes or sends fails for the data, and one that reads fields fails for the payload. - **Fed by all four message history factories** (default, micrometer, metrics, opentelemetry) through `DefaultMessageHistory.captureBody`. So it costs nothing unless the message history is on, as the dev profile turns it on. A route's types are forgotten when the route is removed, so a reload never mixes two versions. - **route-structure console:** `bodyTypes` and `bodyKinds` on each processor line (JSON). In the text output, the types line up in a column after the code. - **route console:** `variedBodyTypes` and `mixedBodyKinds` per route. The CLI status file and `camel_runtime_routes` pass them on, so an AI that lists the routes sees them without asking. - **`camel cmd route-structure`** shows the column. `--varied` shows only the steps reached with more than one type. - **AI and MCP tools:** `get_route_structure` and `camel_runtime_route_structure` describe the fields and take `varied=true`. - **Docs:** a "Body types across messages" section on the Message History page, the Camel CLI diagnostics page, and the MCP tool table. ``` Source: orders.camel.yaml -------------------------------------------------------------------------------- 1: route[orders] 2: from[file:inbox] 5: unmarshal[json] body: GenericFile 8: to[http://stock/api/reserve] body: LinkedHashMap | String (data and payload) 11: log[${body}] body: String | byte[] ``` ## Choices - **Registered eagerly.** The message history feeds the registry from many threads, and a lazy context plugin can be created twice on the first lookup. It's one small object per CamelContext. - **Looked up once.** Each factory looks the registry up in `doInit` and calls the new `captureBody(exchange, registry)`. The old `captureBody(exchange)` stays, and does the lookup, for factories outside Camel. - **Every kind is kept,** also beyond the 8 types a node keeps, because a new kind is what needs attention. A node that has seen a type before records nothing more and takes no lock. - **A single value counts as payload** (a number, a boolean, an enum, a CharSequence), as a type converter turns it into text. This is only in `BodyFacts.kindOf`: `isPayload`, which the hints use, is unchanged. ## Not in this PR - The validator using what the running app saw (part 2 of CAMEL-25750). - The route checksum and revision (CAMEL-25771), which per-line facts on an edited file need. - A runtime error at a step that has also been reached with another kind could say so in its hint (a CAMEL-25749 follow-up). - A view in the TUI. ## Tests Run locally against the changed core modules, through a scratch local repository: - **camel-core** (27): - `BodyTypeRegistryTest`: types across exchanges, the branch the last message did not take, null, no message history, route removal; - `DefaultBodyTypeRegistryTest`: order, the cap, kinds beyond the cap, per route; - `BodyFactsTest` (`kindOf`); - the `MessageHistory*` and route removal tests. - **camel-console:** the whole module (255), including new route-structure tests for the kinds, the text column and the route console counts. - **camel-jbang-core:** - `CamelRouteStructureActionTest`: column, kinds, `--varied` table and JSON; - `ToolRegistryTest`: `varied` for the tool; - the AI tool tests (45). - **camel-jbang-plugin-tui:** `AiPanelPromptBudgetTest` still within budget. - **camel-jbang-mcp:** `RuntimeToolsTest`, `RuntimeToolsWiringTest` (31). - **Components:** the message history tests of camel-micrometer (the registry is fed through its factory), camel-metrics and camel-opentelemetry-metrics. _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]
