Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 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
23d2dce
CAMEL-24961: docs - the component, data format and language pages sho…
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
928f1f8
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
6db53b3
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
66219e9
Merge branch 'feature/CAMEL-24961-catalog-body-types-2' into feature/…
davsclaus Oct 22, 2026
8eb7135
Merge remote-tracking branch 'origin/main' into feature/CAMEL-24961-c…
davsclaus Oct 23, 2026
e8c5237
CAMEL-24961: camel-jbang - the catalog doc test uses weather as the c…
davsclaus Oct 24, 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
44 changes: 44 additions & 0 deletions docs/components/modules/ROOT/examples/js/camel.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,48 @@ module.exports = {
return e.msg()
}
},

// the body types of the catalog (CAMEL-24961): one row per side of the bodyTypes section
bodySide: (side) => {
const sides = {
consumerOut: 'Consumer',
consumerReply: 'Consumer reply',
producerIn: 'Producer input',
producerOut: 'Producer output',
marshalIn: 'Marshal input',
marshalOut: 'Marshal output',
unmarshalIn: 'Unmarshal input',
unmarshalOut: 'Unmarshal output',
expressionIn: 'Expression input',
expressionOut: 'Expression result',
}
return `*${sides[side] || side}*`
},

// text, bytes or stream, with the Java type when the body is always of that type
bodyCarriers: (value) => {
const carriers = (value.carriers || []).map((carrier) => '`' + carrier + '`')
const words = carriers.length === 0 ? '`unknown`'
: carriers.length === 1 ? carriers[0]
: carriers.slice(0, -1).join(', ') + ' or ' + carriers[carriers.length - 1]
return words + (value.javaType ? ' (`' + value.javaType + '`)' : '') + (value.format ? ', as ' + value.format : '')
},

// the description, the bodies for other values of an option, and the options the body depends on
bodyDescription: (value) => {
// only what reads as an attribute reference ({body}, not {header.foo}, which keeps a backslash), and the cell separator
const escape = (text) => text.replace(/\{(\w[\w-]*)\}/g, '\\{$1}').split('|').join('\\|')
const parts = []
if (value.description) {
parts.push(escape(value.description) + (value.description.endsWith('.') ? '' : '.'))
}
if (value.byOption && value.byOption.length) {
parts.push(value.byOption.map((option) => `* With \`${option.option}=${option.value}\`: `
+ module.exports.bodyCarriers(option)).join('\n'))
}
if (value.dependsOn && value.dependsOn.length) {
parts.push('Not known when ' + value.dependsOn.map((option) => '`' + option + '`').join(' or ') + ' is set.')
}
return parts.join('\n\n')
},
}
21 changes: 21 additions & 0 deletions docs/components/modules/ROOT/partials/body-types.adoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
// body types: START
// the including partial sets body-types-module (the module of the page) and body-types-intro
include::jsonpathcount${body-types-module}:example$json/{shortname}.json[queries='bodytypecount=nodes$.bodyTypes.*']

ifeval::[{bodytypecount} != 0]
== Message Body

[subs="attributes,quotes"]
{body-types-intro}

[width="100%",cols="2,3,6a",options="header"]
|===
| Side | Body | Description
|===

jsonpathTable::{body-types-module}:example$json/{shortname}.json['nodes$.bodyTypes.*','camel.bodySide(path[2])|camel.bodyCarriers(value)|camel.bodyDescription(value)','camel=xref:ROOT:js/camel.js']

The bodies are the ones with the default options. A side that is not listed is not known, and tooling does not guess
it. The carriers are described in the xref:manual::camel-catalog.adoc[Camel Catalog].
endif::[]
// body types: END
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,8 @@ The {doctitle} component supports the following message header(s), which is/are
jsonpathTable::example$json/{shortname}.json['nodes$.headers.*',{cellformats},'util=camel-website-util,camel=xref:js/camel.js']

endif::[]
// component headers: END
// component headers: END

:body-types-module: ROOT
:body-types-intro: The message body at each side of the {doctitle} component: _Consumer_ is the body of the messages the consumer creates, _Consumer reply_ the bodies a consumer that answers its caller can reply with, _Producer input_ the bodies the producer can send or write, and _Producer output_ the body after the producer.
include::partial$body-types.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ The {doctitle} dataformat supports the following options which are listed below.

jsonpathTable::example$json/{shortname}.json['nodes$.properties[?(@.displayName!="Id")]',{cellformats},{requires}]


:body-types-module: dataformats
:body-types-intro: The message body at each side of the {doctitle} data format: _Marshal input_ and _Unmarshal input_ are the bodies marshal and unmarshal can take, and _Marshal output_ and _Unmarshal output_ the body after them.
include::ROOT:partial$body-types.adoc[]
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,7 @@ The {doctitle} language supports the following options which are listed below.

jsonpathTable::example$json/{shortname}.json['nodes$.properties[?(@.kind=="attribute" && @.displayName!="Id")]',{cellformats},{requires}]


:body-types-module: languages
:body-types-intro: The message body at each side of the {doctitle} language: _Expression input_ is the body its expressions can read, and _Expression result_ what they return.
include::ROOT:partial$body-types.adoc[]
3 changes: 2 additions & 1 deletion docs/user-manual/modules/ROOT/pages/camel-catalog.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,8 @@ description:
----

The sides say what the body is with the default options. A side that is not in the catalog is not known, and tooling
should not guess it. The Java API gives them on the model:
should not guess it. The documentation page of a component, data format or language shows them in its _Message Body_
section, and `camel catalog doc` prints them. The Java API gives them on the model:

[source,java]
----
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1649,7 +1649,7 @@ private static void addCommonModelFields(JsonObject result, BaseModel<?> model)
* The body types a line per side, as compact as the options are: the carriers, the Java type, the format, the
* description, the body for other option values, and the options that make it not known (CAMEL-24961).
*/
static JsonObject bodyTypes(Map<String, BodyTypeModel> bodyTypes) {
public static JsonObject bodyTypes(Map<String, BodyTypeModel> bodyTypes) {
JsonObject answer = new JsonObject();
for (Map.Entry<String, BodyTypeModel> entry : bodyTypes.entrySet()) {
BodyTypeModel side = entry.getValue();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.Collection;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.stream.Collectors;

import com.github.freva.asciitable.AsciiTable;
Expand All @@ -46,6 +47,7 @@
import org.apache.camel.main.util.SuggestSimilarHelper;
import org.apache.camel.tooling.maven.MavenGav;
import org.apache.camel.tooling.model.BaseOptionModel;
import org.apache.camel.tooling.model.BodyTypeModel;
import org.apache.camel.tooling.model.ComponentModel;
import org.apache.camel.tooling.model.DataFormatModel;
import org.apache.camel.tooling.model.EipModel;
Expand Down Expand Up @@ -124,6 +126,19 @@ public class CatalogDoc extends CamelCommand {
description = "Output in JSON Format: the documentation the MCP tool camel_catalog_doc gives")
boolean jsonOutput;

/** The sides of the body types, as the documentation pages name them. */
private static final Map<String, String> BODY_SIDES = Map.of(
BodyTypeModel.CONSUMER_OUT, "Consumer",
BodyTypeModel.CONSUMER_REPLY, "Consumer reply",
BodyTypeModel.PRODUCER_IN, "Producer input",
BodyTypeModel.PRODUCER_OUT, "Producer output",
BodyTypeModel.MARSHAL_IN, "Marshal input",
BodyTypeModel.MARSHAL_OUT, "Marshal output",
BodyTypeModel.UNMARSHAL_IN, "Unmarshal input",
BodyTypeModel.UNMARSHAL_OUT, "Unmarshal output",
BodyTypeModel.EXPRESSION_IN, "Expression input",
BodyTypeModel.EXPRESSION_OUT, "Expression result");

CamelCatalog catalog;

public CatalogDoc(CamelJBangMain main) {
Expand Down Expand Up @@ -579,6 +594,7 @@ private void docComponent(ComponentModel cm) throws Exception {
printer().println(optionTable(filtered));
printer().println("");
}
printBodyTypes(cm.getBodyTypes());

if (link != null) {
printer().println(link);
Expand Down Expand Up @@ -628,6 +644,7 @@ private void docDataFormat(DataFormatModel dm) throws Exception {
}
printer().println(optionTable(filtered));
printer().println("");
printBodyTypes(dm.getBodyTypes());

if (link != null) {
printer().println(link);
Expand Down Expand Up @@ -677,6 +694,7 @@ private void docLanguage(LanguageModel lm) throws Exception {
}
printer().println(optionTable(filtered));
printer().println("");
printBodyTypes(lm.getBodyTypes());

if (link != null) {
printer().println(link);
Expand Down Expand Up @@ -775,6 +793,29 @@ private int[] docColumnWidths(int nameMax, int descMax, int defaultMax, int type
};
}

/**
* The message body at each side, as the body types of the catalog say (CAMEL-24961) and the documentation page
* shows it: one line per side, with the default options. Nothing when the catalog does not say.
*/
private void printBodyTypes(Map<String, BodyTypeModel> bodyTypes) {
if (bodyTypes.isEmpty()) {
return;
}
JsonObject lines = CatalogDocs.bodyTypes(bodyTypes);
// the side in one line (Expression result, with the padding of the cell), the body in the rest of the terminal
int sideWidth = BODY_SIDES.values().stream().mapToInt(String::length).max().orElse(17) + 2;
int bodyWidth = Math.max(15, Math.min(120, terminalWidth() - TerminalWidthHelper.fancyBorderOverhead(2) - sideWidth));
printer().println("Message body (with the default options; a side that is not listed is not known):");
printer().println(AsciiTable.getTable(AsciiTable.FANCY_ASCII, lines.entrySet(), Arrays.asList(
new Column().header("SIDE").dataAlign(HorizontalAlign.LEFT)
.maxWidth(sideWidth, OverflowBehaviour.NEWLINE)
.with(e -> BODY_SIDES.getOrDefault(e.getKey(), e.getKey())),
new Column().header("BODY").dataAlign(HorizontalAlign.LEFT)
.maxWidth(bodyWidth, OverflowBehaviour.NEWLINE)
.with(e -> String.valueOf(e.getValue())))));
printer().println("");
}

private String optionTable(List<? extends BaseOptionModel> options) {
int[] w = docColumnWidths(35, 80, 25, 25);
return AsciiTable.getTable(AsciiTable.FANCY_ASCII, options, Arrays.asList(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,28 @@ public void shouldDocumentADataFormatAndALanguage() throws Exception {
Assertions.assertTrue(printer.getOutput().startsWith("Language Name: simple"), printer.getOutput());
}

@Test
public void shouldPrintTheMessageBody() throws Exception {
// CAMEL-24961: the body at each side, as the documentation page shows it
CatalogDoc command = createCommand("file", false);
Assertions.assertEquals(0, command.doCall());
String output = printer.getOutput();
Assertions.assertTrue(output.contains("Message body (with the default options"), output);
Assertions.assertTrue(output.contains("Producer input"), output);
Assertions.assertTrue(output.contains("text, bytes, stream or file"), output);

printer = new StringPrinter();
command = createCommand("jackson", false);
Assertions.assertEquals(0, command.doCall());
Assertions.assertTrue(printer.getOutput().contains("Unmarshal output"), printer.getOutput());

// a component whose body types are not in the catalog has no such table
printer = new StringPrinter();
command = createCommand("weather", false);
Assertions.assertEquals(0, command.doCall());
Assertions.assertFalse(printer.getOutput().contains("Message body"), printer.getOutput());
}

@Test
public void shouldFilterTheOptions() throws Exception {
CatalogDoc command = createCommand("timer", false);
Expand Down
Loading