Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
b7a779c
CAMEL-24961: camel-catalog - the body a component or data format need…
davsclaus Oct 21, 2026
09db3be
CAMEL-24961: camel-catalog - the body types of platform-http, rest, f…
davsclaus Oct 21, 2026
82f4901
CAMEL-24961: camel-catalog - the body types of paho-mqtt5 and mongodb
davsclaus Oct 21, 2026
cd44efe
CAMEL-24961: camel-catalog - an iterator carrier, and the build rejec…
davsclaus Oct 21, 2026
80d2a4d
Merge branch 'feature/CAMEL-24961-catalog-body-types' into feature/CA…
davsclaus Oct 21, 2026
daec206
CAMEL-24961: camel-catalog - csv with lazyLoad gives an iterator, and…
davsclaus Oct 21, 2026
b64c881
CAMEL-24961: camel-yaml-dsl-validator - the body walks read the body …
davsclaus Oct 21, 2026
0be66c5
CAMEL-24961: Rename When.carrier to carriers, as the catalog names it
davsclaus Oct 21, 2026
617b873
Merge branch 'feature/CAMEL-24961-catalog-body-types' into feature/CA…
davsclaus Oct 21, 2026
15aaf46
CAMEL-24961: Use When.carriers in the annotations of slice 2
davsclaus Oct 21, 2026
a3605e6
Merge branch 'feature/CAMEL-24961-catalog-body-types-2' into feature/…
davsclaus Oct 21, 2026
07e8497
CAMEL-24961: camel-yaml-dsl-maven-plugin - ignore the bodyTypes of th…
davsclaus Oct 22, 2026
920feb7
Merge remote-tracking branch 'origin/feature/CAMEL-24961-catalog-body…
davsclaus Oct 22, 2026
8175555
Merge branch 'feature/CAMEL-24961-catalog-body-types-2' into feature/…
davsclaus Oct 22, 2026
4017dd4
CAMEL-24961: camel-jbang - the options that make a body type not know…
davsclaus Oct 22, 2026
d4d61c9
Merge branch 'feature/CAMEL-24961-catalog-body-types-2' into feature/…
davsclaus Oct 22, 2026
5b3a95b
Merge remote-tracking branch 'origin/main' into feature/CAMEL-24961-c…
davsclaus Oct 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/user-manual/modules/ROOT/pages/camel-catalog.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,10 @@ options a side names exist, that `unchanged` is only on the body after a step an
The values are read from the code that sets the body, and checked against the body types the message history records
when the routes run.

The YAML validator of the Camel CLI follows the body through the steps of a route with the body types, and reports a
step that cannot work on it, such as a Map that a `to: file` cannot write (see
xref:camel-jbang-validation.adoc#_what_a_running_integration_saw[Camel CLI validation]).

=== Documentation in the Catalog

The catalog includes the AsciiDoc documentation pages from all modules. This makes the full
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,12 @@ A part of a Java route the parser cannot work out (a value computed at runtime)

The YAML validator follows the message body through the steps of each route, and reports a step that cannot work on
it: a field read such as `+${body.qty}+` on text that was never unmarshalled, or a Map that a `to: file` cannot write.
Where the file does not tell what the body is, such as after a `platform-http` or `kafka` consumer, or after a call
with `to: http`, it says nothing.
What a component or a data format does with the body comes from the
xref:camel-catalog.adoc#_body_types_in_the_catalog[body types in the catalog]: the file consumer gives the file it
read, the `http` producer leaves the response as bytes or a stream, and `unmarshal: json` makes a Map or a List.
Where they do not tell what the body is, the validator says nothing: after a `platform-http` consumer the body
depends on the request, and the deserializer of a `kafka` consumer can be set on the component, which the route file
does not show.

When an integration runs the routes of the file with the message history on, such as with `camel run --dev`, the
validator fills these gaps with what the integration saw at the endpoints of its routes: the body each consumer gave,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

import static org.apache.camel.dsl.yaml.validator.RouteGraph.Route;
import static org.apache.camel.dsl.yaml.validator.RouteGraph.endpointOf;
import static org.apache.camel.dsl.yaml.validator.RouteGraph.from;
import static org.apache.camel.dsl.yaml.validator.RouteGraph.normalize;
import static org.apache.camel.dsl.yaml.validator.RouteGraph.routes;
import static org.apache.camel.dsl.yaml.validator.RouteGraph.scheme;
Expand Down Expand Up @@ -63,21 +64,15 @@ final class BodyTypeFlow {
/** The REST verbs that carry no body, so a route they send to starts with none. */
private static final Set<String> VERBS_WITHOUT_BODY = Set.of("get", "delete", "head");

/** The consumers that produce no body of their own, so the message reaching the route has none. */
private static final Set<String> NO_BODY_CONSUMER = Set.of("timer", "quartz", "scheduler", "cron");

private BodyTypeFlow() {
}

static void check(JsonNode target, NodePath path, List<Error> errors) {
check(target, path, errors, Set.of());
}

/**
* @param known the endpoints the caller knows deliver no body, such as {@code direct:getStock} for the GET
* operation of an OpenAPI specification the route binds to (CAMEL-24844 phase B)
* @param known the endpoints the caller knows deliver no body, such as {@code direct:getStock} for the GET
* operation of an OpenAPI specification the route binds to (CAMEL-24844 phase B)
* @param bodyTypes the body types of the catalog, which say the consumers that give no body (timer, cron)
*/
static void check(JsonNode target, NodePath path, List<Error> errors, Set<String> known) {
static void check(JsonNode target, NodePath path, List<Error> errors, Set<String> known, CatalogBodyTypes bodyTypes) {
List<Route> routes = routes(target);
if (routes.isEmpty()) {
return;
Expand Down Expand Up @@ -106,7 +101,7 @@ static void check(JsonNode target, NodePath path, List<Error> errors, Set<String
if (reader == null) {
continue;
}
if (!certainlyWithoutABody(r, callers, restless, new HashSet<>())) {
if (!certainlyWithoutABody(r, callers, restless, new HashSet<>(), bodyTypes)) {
continue;
}
errors.add(Error.builder()
Expand All @@ -131,15 +126,17 @@ static void check(JsonNode target, NodePath path, List<Error> errors, Set<String
*/
private static boolean certainlyWithoutABody(
Route route, Map<Route, List<Route>> callers, Set<String> restless,
Set<Route> seen) {
Set<Route> seen, CatalogBodyTypes bodyTypes) {
if (!seen.add(route)) {
return false; // a cycle: say nothing
}
String scheme = scheme(route.fromUri());
if (scheme == null) {
return false;
}
if (NO_BODY_CONSUMER.contains(scheme)) {
// a consumer that produces no body of its own, as the catalog says: timer, cron, scheduler, quartz
CatalogBodyTypes.Answer out = bodyTypes.consumerOut(route.fromUri(), from(route.node()));
if (out != null && out.none()) {
return true;
}
if (!"direct".equals(scheme) && !"seda".equals(scheme) && !"direct-vm".equals(scheme)) {
Expand All @@ -155,7 +152,7 @@ private static boolean certainlyWithoutABody(
if (setsTheBodyBeforeSendingTo(caller, route)) {
return false;
}
if (!certainlyWithoutABody(caller, callers, restless, seen)) {
if (!certainlyWithoutABody(caller, callers, restless, seen, bodyTypes)) {
return false;
}
}
Expand Down
Loading
Loading