This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch feature/CAMEL-24961-catalog-body-types-most-used-3 in repository https://gitbox.apache.org/repos/asf/camel.git
commit c69f0b2b0c73e8f3002f551c862ae9c160b62fd7 Author: Claus Ibsen <[email protected]> AuthorDate: Thu Oct 22 23:54:56 2026 +0200 CAMEL-24961: Catalog body types for as2, jdbc, smooks, vertx-http and eight more Declares the body types of as2, jdbc, spring-jdbc, smooks, vertx-http, tika, snmp, pdf, file-watch, scp, graphql and micrometer. All were checked at runtime with camel run, against local servers where needed: an H2 data source, a fake HTTP server, an SSH server with scp, an SNMP agent and the as2 server of the component itself. The producers that read the body: jdbc (the SQL statement), scp (the file), vertx-http (the request), tika, smooks and pdf (the document or the text), graphql (the query, when no query option is set), the as2 client (the EDI message, text or a stream only) and the snmp trap producer (an SNMP4J PDU). micrometer keeps the body. tika parse and pdf create, append and merge give a ByteArrayOutputStream; the smooks output depends on the exports of its config. Fixes the doc prose about the body of jdbc, graphql, tika, pdf, smooks and snmp. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../org/apache/camel/catalog/components/as2.json | 5 + .../camel/catalog/components/file-watch.json | 3 + .../apache/camel/catalog/components/graphql.json | 4 + .../org/apache/camel/catalog/components/jdbc.json | 4 + .../camel/catalog/components/micrometer.json | 4 + .../org/apache/camel/catalog/components/pdf.json | 4 + .../org/apache/camel/catalog/components/scp.json | 4 + .../apache/camel/catalog/components/smooks.json | 4 + .../org/apache/camel/catalog/components/snmp.json | 5 + .../camel/catalog/components/spring-jdbc.json | 4 + .../org/apache/camel/catalog/components/tika.json | 4 + .../camel/catalog/components/vertx-http.json | 4 + .../camel/catalog/docs/graphql-component.adoc | 2 +- .../apache/camel/catalog/docs/jdbc-component.adoc | 10 +- .../apache/camel/catalog/docs/pdf-component.adoc | 3 + .../camel/catalog/docs/smooks-component.adoc | 2 + .../apache/camel/catalog/docs/snmp-component.adoc | 11 +- .../apache/camel/catalog/docs/tika-component.adoc | 8 +- .../org/apache/camel/component/as2/as2.json | 5 + .../apache/camel/component/as2/AS2Endpoint.java | 28 ++++ .../camel/component/file/watch/file-watch.json | 3 + .../component/file/watch/FileWatchEndpoint.java | 22 ++- .../apache/camel/component/graphql/graphql.json | 4 + .../src/main/docs/graphql-component.adoc | 2 +- .../camel/component/graphql/GraphqlEndpoint.java | 17 ++- .../org/apache/camel/component/jdbc/jdbc.json | 4 + .../camel-jdbc/src/main/docs/jdbc-component.adoc | 10 +- .../apache/camel/component/jdbc/JdbcEndpoint.java | 22 +++ .../org/apache/camel/component/scp/scp.json | 4 + .../apache/camel/component/scp/ScpEndpoint.java | 13 ++ .../camel/component/micrometer/micrometer.json | 4 + .../component/micrometer/MicrometerEndpoint.java | 8 + .../org/apache/camel/component/pdf/pdf.json | 4 + .../camel-pdf/src/main/docs/pdf-component.adoc | 3 + .../apache/camel/component/pdf/PdfEndpoint.java | 21 +++ .../org/apache/camel/component/smooks/smooks.json | 4 + .../src/main/docs/smooks-component.adoc | 2 + .../camel/component/smooks/SmooksEndpoint.java | 10 ++ .../org/apache/camel/component/snmp/snmp.json | 5 + .../camel-snmp/src/main/docs/snmp-component.adoc | 11 +- .../apache/camel/component/snmp/SnmpEndpoint.java | 23 +++ .../camel/component/spring/jdbc/spring-jdbc.json | 4 + .../component/spring/jdbc/SpringJdbcEndpoint.java | 22 +++ .../org/apache/camel/component/tika/tika.json | 4 + .../camel-tika/src/main/docs/tika-component.adoc | 8 +- .../apache/camel/component/tika/TikaEndpoint.java | 14 ++ .../camel/component/vertx/http/vertx-http.json | 4 + .../component/vertx/http/VertxHttpEndpoint.java | 13 ++ .../jbang/core/commands/ai/CatalogDocsTest.java | 6 +- .../camel/dsl/yaml/validator/TextBodyFlowTest.java | 168 +++++++++++++++++++++ 50 files changed, 523 insertions(+), 34 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/as2.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/as2.json index b348e9105ce7..dd094da41c7b 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/as2.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/as2.json @@ -32,6 +32,11 @@ "sslContextParameters": { "index": 4, "kind": "property", "displayName": "Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "autowired": false, "secret": false, "description": "To configure security using SSLContextParameters" }, "useGlobalSslContextParameters": { "index": 5, "kind": "property", "displayName": "Use Global Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable usage of global SSL context parameters." } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream" ], "byOption": [ { "option": "apiName", "value": "RECEIPT", "carriers": [ "pojo" ] } ], "description": "The EDI message that server\/listen receives, decrypted, decompressed and without its signature: text in the charset of its Content-Type, or a stream when the sender used the base64 or binary transfer encoding. The component answers with its own receipt (MDN), never the body of the route. receipt\/receive gives the receipt: a Disposit [...] + "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "inBody", "value": "ediMessage", "carriers": [ "text", "stream" ] } ], "description": "The EDI message of client\/send with inBody=ediMessage, as it is: text, encoded in ediMessageCharset (us-ascii when not set), or a stream. Bytes, a file or a Map fail: convertBodyTo String first. Without inBody, the message comes from the CamelAs2.ediMessage header" }, + "producerOut": { "carriers": [ "pojo", "null" ], "description": "The receipt (MDN) in the response when dispositionNotificationTo asks for one: a DispositionNotificationMultipartReportEntity, or a MultipartSignedEntity when it is signed. null without a receipt, when receiptDeliveryOption sends it to a receipt\/receive consumer, or when the response has none, such as an HTTP error, which does not fail the exchange: the CamelAs2.interchange exchange property holds the HttpCoreContext w [...] + }, "properties": { "apiName": { "index": 0, "kind": "path", "displayName": "Api Name", "group": "common", "label": "", "required": true, "type": "enum", "javaType": "org.apache.camel.component.as2.internal.AS2ApiName", "enum": [ "CLIENT", "SERVER", "RECEIPT" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.as2.AS2Configuration", "configurationField": "configuration", "description": "What kind of operation to perform" }, "methodName": { "index": 1, "kind": "path", "displayName": "Method Name", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.as2.AS2Configuration", "configurationField": "configuration", "description": "What sub operation to use for the selected operation" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/file-watch.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/file-watch.json index 2e66d88fe3c9..e0fb4ccc0731 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/file-watch.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/file-watch.json @@ -44,6 +44,9 @@ "CamelFileParent": { "index": 8, "kind": "header", "displayName": "", "group": "consumer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The parent path.", "constantName": "org.apache.camel.component.file.watch.FileWatchConstants#FILE_PARENT" }, "CamelFileLastModified": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "A Long value containing the last modified timestamp of the file.", "constantName": "org.apache.camel.component.file.watch.FileWatchConstants#FILE_LAST_MODIFIED" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "file" ], "javaType": "java.io.File", "description": "The java.io.File of the file or directory of the event, also for DELETE, with the event in the CamelFileEventType header. The consumer does not read it: it converts to text, bytes or a stream by reading the file, which fails after a DELETE" } + }, "properties": { "path": { "index": 0, "kind": "path", "displayName": "Path", "group": "consumer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Path of directory to consume events from." }, "antInclude": { "index": 1, "kind": "parameter", "displayName": "Ant Include", "group": "consumer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "**", "description": "ANT style pattern to match files. The file is matched against path relative to endpoint path. Pattern must be also relative (not starting with slash)" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/graphql.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/graphql.json index 73ef1d1a19f3..06daa6c1ad22 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/graphql.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/graphql.json @@ -30,6 +30,10 @@ "httpClient": { "index": 3, "kind": "property", "displayName": "Http Client", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.hc.client5.http.classic.HttpClient", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom pre-existing Http Client. Beware that when using this, then other configurations such as proxy, access token, is not applied and all this must be pre-configured on the Http Client." }, "headerFilterStrategy": { "index": 4, "kind": "property", "displayName": "Header Filter Strategy", "group": "filter", "label": "filter", "required": false, "type": "object", "javaType": "org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter header to and from Camel message." } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "dependsOn": [ "query", "queryFile", "queryHeader" ], "description": "The query, when none of query, queryFile and queryHeader is set: text, or bytes, a stream or a file of it. A Map is not a query. With one of them the body is not sent, except that an org.apache.camel.util.json.JsonObject body is the variables when neither variables nor variablesHeader is set" }, + "producerOut": { "carriers": [ "text", "null" ], "description": "The response as text, the JSON with the data and errors of GraphQL: unmarshal it to read them. Errors in the response do not fail the exchange; a status outside 2xx does, unless throwExceptionOnFailure=false, which keeps the response as text. null for a response without a body" } + }, "properties": { "httpUri": { "index": 0, "kind": "path", "displayName": "Http Uri", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.net.URI", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The GraphQL server URI." }, "headerFilterStrategy": { "index": 1, "kind": "parameter", "displayName": "Header Filter Strategy", "group": "common (advanced)", "label": "common,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom HeaderFilterStrategy to filter header to and from Camel message." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jdbc.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jdbc.json index 5109e6432688..141b79d25a3e 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jdbc.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jdbc.json @@ -39,6 +39,10 @@ "CamelGeneratedKeysRowCount": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of rows in the header that contains generated keys.", "constantName": "org.apache.camel.component.jdbc.JdbcConstants#JDBC_GENERATED_KEYS_ROW_COUNT" }, "CamelGeneratedKeysRows": { "index": 7, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "List<Map<String, Object>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Rows that contains the generated keys.", "constantName": "org.apache.camel.component.jdbc.JdbcConstants#JDBC_GENERATED_KEYS_DATA" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "The SQL statement as text, or bytes, a stream or a file of it; a Map or a List is not a statement: set the SQL as the body. With useHeadersAsParameters, the values of its placeholders come from the CamelJdbcParameters header, or else from the headers" }, + "producerOut": { "carriers": [ "list", "unchanged" ], "dependsOn": [ "outputClass" ], "byOption": [ { "option": "outputType", "value": "SelectOne", "carriers": [ "map", "text", "value", "bytes", "pojo", "null", "unchanged" ] }, { "option": "outputType", "value": "StreamList", "carriers": [ "iterator", "unchanged" ] } ], "description": "The rows of a select: a List of Maps of the column names and their values (beans of outputClass when set). SelectOne gives the Map of the one row, the [...] + }, "properties": { "dataSourceName": { "index": 0, "kind": "path", "displayName": "Data Source Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Name of DataSource to lookup in the Registry. If the name is dataSource or default, then Camel will attempt to lookup a default DataSource from the registry, meaning if there is a only one instance of DataS [...] "allowNamedParameters": { "index": 1, "kind": "parameter", "displayName": "Allow Named Parameters", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to allow using named parameters in the queries." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/micrometer.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/micrometer.json index f7e9210de897..8896fc905db2 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/micrometer.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/micrometer.json @@ -37,6 +37,10 @@ "CamelMetricsDescription": { "index": 5, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Override description value in URI", "constantName": "org.apache.camel.component.micrometer.MicrometerConstants#HEADER_METRIC_DESCRIPTION" }, "CamelMetricsTags": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "java.lang.Iterable<Tag>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "To augment meter tags defined as URI parameters", "constantName": "org.apache.camel.component.micrometer.MicrometerConstants#HEADER_METRIC_TAGS" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "any" ], "description": "Not used, unless an option such as increment, decrement or value is a simple expression that reads it, which must then give a number. The CamelMetrics headers override the options" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged; the CamelMetrics headers are removed" } + }, "properties": { "metricsType": { "index": 0, "kind": "path", "displayName": "Metrics Type", "group": "producer", "label": "", "required": true, "type": "enum", "javaType": "io.micrometer.core.instrument.Meter.Type", "enum": [ "counter", "summary", "timer" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Type of metrics" }, "metricsName": { "index": 1, "kind": "path", "displayName": "Metrics Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportSimpleExpression": true, "description": "Name of metrics" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pdf.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pdf.json index f2edff0482dd..5a579be3f433 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pdf.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pdf.json @@ -33,6 +33,10 @@ "CamelPdfDecryptionMaterial": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "org.apache.pdfbox.pdmodel.encryption.DecryptionMaterial", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Expected type is https:\/\/pdfbox.apache.org\/docs\/2.0.13\/javadocs\/org\/apache\/pdfbox\/pdmodel\/encryption\/DecryptionMaterial.htmlDecryptionMaterial. Mandatory header if PDF documen [...] "CamelPdfFilesToMerge": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "java.util.List<java.io.File>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Mandatory header for merge operation and ignored in all other operations. The array of pdf files that will be merged.", "constantName": "org.apache.camel.component.pdf.PdfHeaderConstants#FILES_TO_MERGE_HEADER_NAME" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "byOption": [ { "option": "operation", "value": "extractText", "carriers": [ "bytes", "stream", "file", "pojo" ] }, { "option": "operation", "value": "merge", "carriers": [ "any" ] } ], "description": "The text to write for create and append, which takes the document from the CamelPdfDocument header; a Map or a POJO is written as its toString: marshal it first. extractText reads a PDF from bytes, a stream, a file or a [...] + "producerOut": { "carriers": [ "pojo" ], "javaType": "java.io.ByteArrayOutputStream", "byOption": [ { "option": "operation", "value": "extractText", "carriers": [ "text" ], "javaType": "java.lang.String" } ], "description": "The PDF of create, append and merge in a ByteArrayOutputStream, which converts to bytes (convertBodyTo byte[] before extractText). The text of the document for extractText" } + }, "properties": { "operation": { "index": 0, "kind": "path", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "enum", "javaType": "org.apache.camel.component.pdf.PdfOperation", "enum": [ "create", "append", "extractText", "merge" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.pdf.PdfConfiguration", "configurationField": "pdfConfiguration", "description": "Operation type" }, "font": { "index": 1, "kind": "parameter", "displayName": "Font", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "COURIER", "COURIER_BOLD", "COURIER_OBLIQUE", "COURIER_BOLD_OBLIQUE", "HELVETICA", "HELVETICA_BOLD", "HELVETICA_OBLIQUE", "HELVETICA_BOLD_OBLIQUE", "TIMES_ROMAN", "TIMES_BOLD", "TIMES_ITALIC", "TIMES_BOLD_ITALIC", "SYMBOL", "ZAPF_DINGBATS" ], "deprecated": false, "autowired": false, "secret": false, "defaultVa [...] diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/scp.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/scp.json index c725d39cb7a8..a5fafc55d1fa 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/scp.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/scp.json @@ -30,6 +30,10 @@ "healthCheckConsumerEnabled": { "index": 3, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, "healthCheckProducerEnabled": { "index": 4, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on producer [...] }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "byOption": [ { "option": "allowNullBody", "value": "true", "carriers": [ "null", "text", "bytes", "stream", "file" ] } ], "description": "The content of the file: text, bytes, a stream or a file, which is read into memory first to send its size. A Map or a List fails: marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the name of the remote file in the CamelFileNameProduced header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.scp.ScpConfiguration", "configurationField": "configuration", "description": "Hostname of the FTP server" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.scp.ScpConfiguration", "configurationField": "configuration", "description": "Port of the FTP server" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json index d96eead22f1f..b1ab2749020f 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smooks.json @@ -31,6 +31,10 @@ "headers": { "CamelSmooksExecutionContext": { "index": 0, "kind": "header", "displayName": "", "group": "advanced", "label": "advanced", "required": false, "javaType": "org.smooks.api.ExecutionContext", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Smooks execution context.", "constantName": "org.apache.camel.component.smooks.SmooksConstants#SMOOKS_EXECUTION_CONTEXT" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "The data the reader of the smooks config reads: XML by default, or EDI, CSV or JSON with a reader. A Map, a List or a POJO fails" }, + "producerOut": { "carriers": [ "unknown" ], "description": "What the exports of the smooks config give: the bean a JavaSink export extracts (a Map of the beans when it extracts none), or the text of a StringSink. Without exports, the input as a stream" } + }, "properties": { "smooksConfig": { "index": 0, "kind": "path", "displayName": "Smooks Config", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "description": "Path to the Smooks configuration file" }, "reportPath": { "index": 1, "kind": "parameter", "displayName": "Report Path", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "File path to place the generated HTML execution report. The report is a useful tool in the developers arsenal for diagnosing issues or comprehending a transformation. Do not set in production since this is a major performance drain" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/snmp.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/snmp.json index 4dc8c5a836cd..5033597bc5c6 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/snmp.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/snmp.json @@ -30,6 +30,11 @@ "healthCheckConsumerEnabled": { "index": 3, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, "healthCheckProducerEnabled": { "index": 4, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on producer [...] }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", "format": "xml", "description": "The variable bindings of the response of a poll or of a trap as XML text: an snmp element with an entry of an oid and a value for each, and the community of a trap in the securityName header" }, + "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "type", "value": "TRAP", "carriers": [ "pojo" ], "javaType": "org.snmp4j.PDU" } ], "description": "Not used by a POLL or GET_NEXT, which requests the oids. A TRAP sends the body, which must be a PDU of SNMP4J for the snmpVersion: a PDUv1 for 0, the default, a PDU for 1 and a ScopedPDU for 3. Another body fails" }, + "producerOut": { "carriers": [ "pojo" ], "javaType": "org.apache.camel.component.snmp.SnmpMessage", "byOption": [ { "option": "type", "value": "GET_NEXT", "carriers": [ "list" ], "javaType": "java.util.List<org.apache.camel.component.snmp.SnmpMessage>" }, { "option": "type", "value": "TRAP", "carriers": [ "unchanged" ] } ], "description": "The response of a POLL as an SnmpMessage, a Camel message as the body, whose own body is the XML text of the consumer; it does not convert to text [...] + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Hostname of the SNMP enabled device" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": true, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Port number of the SNMP enabled device" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-jdbc.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-jdbc.json index 3e5e9fbd4669..9cfba1b8222e 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-jdbc.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-jdbc.json @@ -39,6 +39,10 @@ "CamelGeneratedKeysRowCount": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of rows in the header that contains generated keys.", "constantName": "org.apache.camel.component.jdbc.JdbcConstants#JDBC_GENERATED_KEYS_ROW_COUNT" }, "CamelGeneratedKeysRows": { "index": 7, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "List<Map<String, Object>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Rows that contains the generated keys.", "constantName": "org.apache.camel.component.jdbc.JdbcConstants#JDBC_GENERATED_KEYS_DATA" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "The SQL statement as text, or bytes, a stream or a file of it; a Map or a List is not a statement: set the SQL as the body. With useHeadersAsParameters, the values of its placeholders come from the CamelJdbcParameters header, or else from the headers" }, + "producerOut": { "carriers": [ "list", "unchanged" ], "dependsOn": [ "outputClass" ], "byOption": [ { "option": "outputType", "value": "SelectOne", "carriers": [ "map", "text", "value", "bytes", "pojo", "null", "unchanged" ] }, { "option": "outputType", "value": "StreamList", "carriers": [ "iterator", "unchanged" ] } ], "description": "The rows of a select: a List of Maps of the column names and their values (beans of outputClass when set). SelectOne gives the Map of the one row, the [...] + }, "properties": { "dataSourceName": { "index": 0, "kind": "path", "displayName": "Data Source Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Name of DataSource to lookup in the Registry. If the name is dataSource or default, then Camel will attempt to lookup a default DataSource from the registry, meaning if there is a only one instance of DataS [...] "allowNamedParameters": { "index": 1, "kind": "parameter", "displayName": "Allow Named Parameters", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to allow using named parameters in the queries." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tika.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tika.json index ddc7c899b1b7..0f8029d743e1 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tika.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/tika.json @@ -27,6 +27,10 @@ "lazyStartProducer": { "index": 0, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...] "autowiredEnabled": { "index": 1, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...] }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "The document: text, bytes, a stream or a file. A Map, a List, a POJO or no body fails, and parse fails on an empty document" }, + "producerOut": { "carriers": [ "pojo" ], "javaType": "java.io.ByteArrayOutputStream", "byOption": [ { "option": "operation", "value": "detect", "carriers": [ "text" ], "javaType": "java.lang.String" } ], "description": "parse gives a ByteArrayOutputStream with the content as XHTML, or as HTML or plain text with tikaParseOutputFormat, in tikaParseOutputEncoding, and the metadata of the document in headers; camel-tika parses HTML and text, other types need their Tika parser module. det [...] + }, "properties": { "operation": { "index": 0, "kind": "path", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "enum", "javaType": "org.apache.camel.component.tika.TikaOperation", "enum": [ "parse", "detect" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.tika.TikaConfiguration", "configurationField": "tikaConfiguration", "description": "Operation type" }, "tikaParseOutputEncoding": { "index": 1, "kind": "parameter", "displayName": "Tika Parse Output Encoding", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.tika.TikaConfiguration", "configurationField": "tikaConfiguration", "description": "Tika Parse Output Encoding" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/vertx-http.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/vertx-http.json index 81042fb956a6..e3091d4173ea 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/vertx-http.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/vertx-http.json @@ -55,6 +55,10 @@ "CamelHttpPath": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Request URI's path, the header will be used to build the request URI with the HTTP_URI.", "constantName": "org.apache.camel.component.vertx.http.VertxHttpConstants#HTTP_PATH" }, "Content-Encoding": { "index": 7, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HTTP content encoding. Is set to provide a content encoding, such as gzip.", "constantName": "org.apache.camel.component.vertx.http.VertxHttpConstants#CONTENT_ENCODING" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "description": "The request body: text, bytes, a stream or a file (a file as a multipart form with multipartUpload), or a Vert.x Buffer, MultiMap (a form) or MultipartForm. A Map, a List or a POJO fails: marshal it first. Without httpMethod, a query string in the URI or no body sends a GET, and a body a POST" }, + "producerOut": { "carriers": [ "bytes", "null" ], "description": "The response body as a byte array, or null for a response without a body. A Vert.x Buffer with responsePayloadAsByteArray=false, which stream caching turns into a stream" } + }, "properties": { "httpUri": { "index": 0, "kind": "path", "displayName": "Http Uri", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.net.URI", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.vertx.http.VertxHttpConfiguration", "configurationField": "configuration", "description": "The HTTP URI to connect to" }, "bridgeEndpoint": { "index": 1, "kind": "parameter", "displayName": "Bridge Endpoint", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.vertx.http.VertxHttpConfiguration", "configurationField": "configuration", "description": "If the option is true, the Exchange.HTTP_URI header will be ignored and the [...] diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/graphql-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/graphql-component.adoc index 3ec1d0083d54..63f921a7ac59 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/graphql-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/graphql-component.adoc @@ -37,7 +37,7 @@ include::partial$component-endpoint-headers.adoc[] == Message Body -If the `variables` and `variablesHeader` parameters are not set and the IN body is a JsonObject instance, Camel will use it for the operation's variables. If the `query` and `queryFile` parameters are not set and the IN body is a String, Camel will use it as the query. Camel will store the GraphQL response from the external server on the OUT message body. +If the `variables` and `variablesHeader` parameters are not set and the IN body is an `org.apache.camel.util.json.JsonObject` instance, Camel will use it for the operation's variables (another `Map` is not used). If the `query`, `queryFile` and `queryHeader` parameters are not set, Camel will use the IN body as the query: text, or bytes, a stream or a file of it. Camel will store the GraphQL response from the external server on the OUT message body, as a `String` of the JSON response, wi [...] All headers from the IN message will be copied to the OUT message, so headers are preserved during routing. Additionally, Camel will add the HTTP response headers as well to the OUT message headers. diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jdbc-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jdbc-component.adoc index 04943660e73f..059bdd5b9f6a 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jdbc-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jdbc-component.adoc @@ -54,11 +54,15 @@ include::partial$component-endpoint-headers.adoc[] === Result -By default, the result is returned in the OUT body as an -`ArrayList<HashMap<String, Object>>`. The `List` object contains the +By default, the result of a select is returned in the OUT body as an +`ArrayList<LinkedHashMap<String, Object>>`. The `List` object contains the list of rows and the `Map` objects contain each row with the `String` key as the column name. You can use the option `outputType` to control -the result. +the result: `SelectOne` gives the `Map` of the one row, the value of its +column when it has one column, or `null` when there is no row, and +`StreamList` gives an `Iterator` of the rows, which can be read once. +A statement that is not a select leaves the body as it is, with the count +in the `CamelJdbcUpdateCount` header. *Note:* This component fetches `ResultSetMetaData` to be able to return the column name as the key in the `Map`. diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pdf-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pdf-component.adoc index e2e9dcebcb9a..fd890c034ca6 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pdf-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/pdf-component.adoc @@ -95,5 +95,8 @@ YAML:: It is now possible to get the body as a PD Document by using `PDDocument doc = exchange.getIn().getBody(PDDocument.class);`, which saves the trouble of converting the byte-array to a document. +The body after `create`, `append` and `merge` is a `ByteArrayOutputStream` with the PDF, which does not convert to a +`PDDocument`: convert it to `byte[]` before `extractText`. + NOTE: this only works for unprotected PDF files. For password-protected, the files still need to be converted manually. diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smooks-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smooks-component.adoc index 677f8b82670f..a3568ee63eee 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smooks-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smooks-component.adoc @@ -14,6 +14,8 @@ The Camel Smooks component uses https://www.smooks.org/[Smooks] to break up the structured data (EDI, CSV, POJO, etc...) of a Camel message body into fragments. These fragments can be processed independently of one another from within Smooks. +The body is read by the reader of the Smooks configuration (XML by default) as text, bytes, a stream or a file. A POJO is read when the body is a `org.smooks.io.source.JavaSource` that holds it: a POJO, a `Map` or a `List` as the body itself fails. + Common applications of Smooks include: * transformation: EDI to CSV, POJO to EDI, POJO to XML, and so on. diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/snmp-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/snmp-component.adoc index 2f0eda76b8e8..c0409fcea38c 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/snmp-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/snmp-component.adoc @@ -41,7 +41,9 @@ and receiving traps. It can also be used to request information using GET method. -The response body type is `org.apache.camel.component.snmp.SnmpMessage`. +After a `POLL`, the body is an `org.apache.camel.component.snmp.SnmpMessage`: a Camel message whose own body is the +response as XML text. It does not convert to a `String` itself. A `GET_NEXT` gives a `List` of them, one per variable +of the walk. A `TRAP` producer sends the body, which must be an `org.snmp4j.PDU`, and leaves it as it is. // component options: START @@ -64,13 +66,10 @@ Given the situation, that I poll for the following OIDs: 1.3.6.1.2.1.43.5.1.1.11.1 ------------------------- -The result will be the following: - -*Result of toString conversion* +The body is the result as XML text, written on one line without an XML declaration (indented here): [source,xml] ----------------------------------------------------------- -<?xml version="1.0" encoding="UTF-8"?> <snmp> <entry> <oid>1.3.6.1.2.1.1.3.0</oid> @@ -127,7 +126,7 @@ snmp:127.0.0.1:162?protocol=udp&type=TRAP You can get the community of SNMP TRAP with message header `securityName`, peer address of the SNMP TRAP with message header `peerAddress`. -Routing example in Java: (converts the SNMP PDU to XML String) +Routing example in Java: (the body of the consumer is the SNMP PDU as XML text) [tabs] ==== diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/tika-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/tika-component.adoc index 52c7916bdd82..89071eaedbe4 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/tika-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/tika-component.adoc @@ -43,7 +43,8 @@ include::partial$component-endpoint-headers.adoc[] === To Detect a file's MIME Type -The file should be placed in the Body. +The body is the document: text, bytes, a stream or a file. After `detect`, the body is the MIME type as text, such as +`text/html`. [tabs] ==== @@ -80,7 +81,10 @@ YAML:: === To Parse a File -The file should be placed in the Body. +The body is the document: text, bytes, a stream or a file. After `parse`, the body is a `ByteArrayOutputStream` with +the content as XHTML, or as HTML or plain text with `tikaParseOutputFormat`, which converts to a `String`, and the +metadata of the document are headers, such as `dc:title`. The component has the Tika parsers of HTML and text: other +types need their Tika parser module, such as `org.apache.tika:tika-parser-pdf-module` for PDF, or the content is empty. [tabs] ==== diff --git a/components/camel-as2/camel-as2-component/src/generated/resources/META-INF/org/apache/camel/component/as2/as2.json b/components/camel-as2/camel-as2-component/src/generated/resources/META-INF/org/apache/camel/component/as2/as2.json index b348e9105ce7..dd094da41c7b 100644 --- a/components/camel-as2/camel-as2-component/src/generated/resources/META-INF/org/apache/camel/component/as2/as2.json +++ b/components/camel-as2/camel-as2-component/src/generated/resources/META-INF/org/apache/camel/component/as2/as2.json @@ -32,6 +32,11 @@ "sslContextParameters": { "index": 4, "kind": "property", "displayName": "Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "object", "javaType": "org.apache.camel.support.jsse.SSLContextParameters", "deprecated": false, "autowired": false, "secret": false, "description": "To configure security using SSLContextParameters" }, "useGlobalSslContextParameters": { "index": 5, "kind": "property", "displayName": "Use Global Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable usage of global SSL context parameters." } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream" ], "byOption": [ { "option": "apiName", "value": "RECEIPT", "carriers": [ "pojo" ] } ], "description": "The EDI message that server\/listen receives, decrypted, decompressed and without its signature: text in the charset of its Content-Type, or a stream when the sender used the base64 or binary transfer encoding. The component answers with its own receipt (MDN), never the body of the route. receipt\/receive gives the receipt: a Disposit [...] + "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "inBody", "value": "ediMessage", "carriers": [ "text", "stream" ] } ], "description": "The EDI message of client\/send with inBody=ediMessage, as it is: text, encoded in ediMessageCharset (us-ascii when not set), or a stream. Bytes, a file or a Map fail: convertBodyTo String first. Without inBody, the message comes from the CamelAs2.ediMessage header" }, + "producerOut": { "carriers": [ "pojo", "null" ], "description": "The receipt (MDN) in the response when dispositionNotificationTo asks for one: a DispositionNotificationMultipartReportEntity, or a MultipartSignedEntity when it is signed. null without a receipt, when receiptDeliveryOption sends it to a receipt\/receive consumer, or when the response has none, such as an HTTP error, which does not fail the exchange: the CamelAs2.interchange exchange property holds the HttpCoreContext w [...] + }, "properties": { "apiName": { "index": 0, "kind": "path", "displayName": "Api Name", "group": "common", "label": "", "required": true, "type": "enum", "javaType": "org.apache.camel.component.as2.internal.AS2ApiName", "enum": [ "CLIENT", "SERVER", "RECEIPT" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.as2.AS2Configuration", "configurationField": "configuration", "description": "What kind of operation to perform" }, "methodName": { "index": 1, "kind": "path", "displayName": "Method Name", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.as2.AS2Configuration", "configurationField": "configuration", "description": "What sub operation to use for the selected operation" }, diff --git a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java index 14b4b8dbba47..5d1c122aa260 100644 --- a/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java +++ b/components/camel-as2/camel-as2-component/src/main/java/org/apache/camel/component/as2/AS2Endpoint.java @@ -44,6 +44,9 @@ import org.apache.camel.component.as2.internal.AS2ApiName; import org.apache.camel.component.as2.internal.AS2ConnectionHelper; import org.apache.camel.component.as2.internal.AS2Constants; import org.apache.camel.component.as2.internal.AS2PropertiesHelper; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; @@ -60,6 +63,31 @@ import org.apache.camel.support.jsse.SSLContextParameters; category = { Category.FILE }) @Metadata(excludeProperties = "startScheduler,initialDelay,delay,timeUnit,useFixedDelay,pollStrategy,runLoggingLevel,sendEmptyMessageWhenIdle" + ",greedy,scheduler,schedulerProperties,scheduledExecutorService,backoffMultiplier,backoffIdleThreshold,backoffErrorThreshold,repeatCount,bridgeErrorHandler") +@BodyTypes(consumerOut = @BodyType(value = { Carrier.TEXT, Carrier.STREAM }, + byOption = @BodyType.When(option = "apiName", value = "RECEIPT", carriers = Carrier.POJO), + description = "The EDI message that server/listen receives, decrypted, decompressed and" + + " without its signature: text in the charset of its Content-Type, or a" + + " stream when the sender used the base64 or binary transfer encoding. The" + + " component answers with its own receipt (MDN), never the body of the route." + + " receipt/receive gives the receipt: a" + + " DispositionNotificationMultipartReportEntity, or a MultipartSignedEntity" + + " when it is signed. The CamelAs2.interchange exchange property holds the" + + " HttpCoreContext"), + producerIn = @BodyType(value = Carrier.ANY, + byOption = @BodyType.When(option = "inBody", value = "ediMessage", + carriers = { Carrier.TEXT, Carrier.STREAM }), + description = "The EDI message of client/send with inBody=ediMessage, as it is: text, encoded" + + " in ediMessageCharset (us-ascii when not set), or a stream. Bytes, a file or" + + " a Map fail: convertBodyTo String first. Without inBody, the message comes" + + " from the CamelAs2.ediMessage header"), + producerOut = @BodyType(value = { Carrier.POJO, Carrier.NULL }, + description = "The receipt (MDN) in the response when dispositionNotificationTo asks for" + + " one: a DispositionNotificationMultipartReportEntity, or a" + + " MultipartSignedEntity when it is signed. null without a receipt, when" + + " receiptDeliveryOption sends it to a receipt/receive consumer, or when the" + + " response has none, such as an HTTP error, which does not fail the" + + " exchange: the CamelAs2.interchange exchange property holds the" + + " HttpCoreContext with the response")) public class AS2Endpoint extends AbstractApiEndpoint<AS2ApiName, AS2Configuration> { @UriParam diff --git a/components/camel-file-watch/src/generated/resources/META-INF/org/apache/camel/component/file/watch/file-watch.json b/components/camel-file-watch/src/generated/resources/META-INF/org/apache/camel/component/file/watch/file-watch.json index 2e66d88fe3c9..e0fb4ccc0731 100644 --- a/components/camel-file-watch/src/generated/resources/META-INF/org/apache/camel/component/file/watch/file-watch.json +++ b/components/camel-file-watch/src/generated/resources/META-INF/org/apache/camel/component/file/watch/file-watch.json @@ -44,6 +44,9 @@ "CamelFileParent": { "index": 8, "kind": "header", "displayName": "", "group": "consumer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The parent path.", "constantName": "org.apache.camel.component.file.watch.FileWatchConstants#FILE_PARENT" }, "CamelFileLastModified": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "A Long value containing the last modified timestamp of the file.", "constantName": "org.apache.camel.component.file.watch.FileWatchConstants#FILE_LAST_MODIFIED" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "file" ], "javaType": "java.io.File", "description": "The java.io.File of the file or directory of the event, also for DELETE, with the event in the CamelFileEventType header. The consumer does not read it: it converts to text, bytes or a stream by reading the file, which fails after a DELETE" } + }, "properties": { "path": { "index": 0, "kind": "path", "displayName": "Path", "group": "consumer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Path of directory to consume events from." }, "antInclude": { "index": 1, "kind": "parameter", "displayName": "Ant Include", "group": "consumer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "**", "description": "ANT style pattern to match files. The file is matched against path relative to endpoint path. Pattern must be also relative (not starting with slash)" }, diff --git a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchEndpoint.java b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchEndpoint.java index 60d0a08a3461..742dd9ba72ff 100644 --- a/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchEndpoint.java +++ b/components/camel-file-watch/src/main/java/org/apache/camel/component/file/watch/FileWatchEndpoint.java @@ -22,6 +22,9 @@ import org.apache.camel.Consumer; import org.apache.camel.MultipleConsumersSupport; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; @@ -33,6 +36,11 @@ import org.apache.camel.support.DefaultEndpoint; */ @UriEndpoint(firstVersion = "3.0.0", scheme = "file-watch", title = "File Watch", syntax = "file-watch:path", category = { Category.FILE }, consumerOnly = true, headersClass = FileWatchConstants.class) +@BodyTypes(consumerOut = @BodyType(value = Carrier.FILE, javaType = "java.io.File", + description = "The java.io.File of the file or directory of the event, also for DELETE, with" + + " the event in the CamelFileEventType header. The consumer does not read it:" + + " it converts to text, bytes or a stream by reading the file, which fails" + + " after a DELETE")) public class FileWatchEndpoint extends DefaultEndpoint implements MultipleConsumersSupport { @UriPath(description = "Path of directory to consume events from.") @@ -47,11 +55,13 @@ public class FileWatchEndpoint extends DefaultEndpoint implements MultipleConsum defaultValue = "true") private boolean recursive = true; @UriParam(label = "advanced", - description = "The number of concurrent consumers. Increase this value, if your route is slow to prevent buffering in queue.", + description = "The number of concurrent consumers. Increase this value, if your route is slow to prevent" + + " buffering in queue.", defaultValue = "1") private int concurrentConsumers; @UriParam(label = "advanced", - description = "The number of threads polling WatchService. Increase this value, if you see OVERFLOW messages in log.", + description = "The number of threads polling WatchService. Increase this value, if you see OVERFLOW messages in" + + " log.", defaultValue = "1") private int pollThreads; @UriParam(description = "ANT style pattern to match files. The file is matched against path relative to endpoint path. " @@ -63,10 +73,10 @@ public class FileWatchEndpoint extends DefaultEndpoint implements MultipleConsum defaultValue = "" + Integer.MAX_VALUE) private int queueSize; @UriParam(label = "advanced", - description = "Reference to io.methvin.watcher.hashing.FileHasher. " - + "This prevents emitting duplicate events on some platforms. " - + "For working with large files and if you dont need detect multiple modifications per second per file, " - + "use #lastModifiedTimeFileHasher. You can also provide custom implementation in registry.", + description = "Reference to io.methvin.watcher.hashing.FileHasher. This prevents emitting duplicate events on" + + " some platforms. For working with large files and if you dont need detect multiple modifications" + + " per second per file, use #lastModifiedTimeFileHasher. You can also provide custom" + + " implementation in registry.", defaultValue = "#murmur3FFileHasher") private FileHasher fileHasher; @UriParam(description = "Enables or disables file hashing to detect duplicate events. " diff --git a/components/camel-graphql/src/generated/resources/META-INF/org/apache/camel/component/graphql/graphql.json b/components/camel-graphql/src/generated/resources/META-INF/org/apache/camel/component/graphql/graphql.json index 73ef1d1a19f3..06daa6c1ad22 100644 --- a/components/camel-graphql/src/generated/resources/META-INF/org/apache/camel/component/graphql/graphql.json +++ b/components/camel-graphql/src/generated/resources/META-INF/org/apache/camel/component/graphql/graphql.json @@ -30,6 +30,10 @@ "httpClient": { "index": 3, "kind": "property", "displayName": "Http Client", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.hc.client5.http.classic.HttpClient", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom pre-existing Http Client. Beware that when using this, then other configurations such as proxy, access token, is not applied and all this must be pre-configured on the Http Client." }, "headerFilterStrategy": { "index": 4, "kind": "property", "displayName": "Header Filter Strategy", "group": "filter", "label": "filter", "required": false, "type": "object", "javaType": "org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom org.apache.camel.spi.HeaderFilterStrategy to filter header to and from Camel message." } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "dependsOn": [ "query", "queryFile", "queryHeader" ], "description": "The query, when none of query, queryFile and queryHeader is set: text, or bytes, a stream or a file of it. A Map is not a query. With one of them the body is not sent, except that an org.apache.camel.util.json.JsonObject body is the variables when neither variables nor variablesHeader is set" }, + "producerOut": { "carriers": [ "text", "null" ], "description": "The response as text, the JSON with the data and errors of GraphQL: unmarshal it to read them. Errors in the response do not fail the exchange; a status outside 2xx does, unless throwExceptionOnFailure=false, which keeps the response as text. null for a response without a body" } + }, "properties": { "httpUri": { "index": 0, "kind": "path", "displayName": "Http Uri", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.net.URI", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The GraphQL server URI." }, "headerFilterStrategy": { "index": 1, "kind": "parameter", "displayName": "Header Filter Strategy", "group": "common (advanced)", "label": "common,advanced", "required": false, "type": "object", "javaType": "org.apache.camel.spi.HeaderFilterStrategy", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom HeaderFilterStrategy to filter header to and from Camel message." }, diff --git a/components/camel-graphql/src/main/docs/graphql-component.adoc b/components/camel-graphql/src/main/docs/graphql-component.adoc index 3ec1d0083d54..63f921a7ac59 100644 --- a/components/camel-graphql/src/main/docs/graphql-component.adoc +++ b/components/camel-graphql/src/main/docs/graphql-component.adoc @@ -37,7 +37,7 @@ include::partial$component-endpoint-headers.adoc[] == Message Body -If the `variables` and `variablesHeader` parameters are not set and the IN body is a JsonObject instance, Camel will use it for the operation's variables. If the `query` and `queryFile` parameters are not set and the IN body is a String, Camel will use it as the query. Camel will store the GraphQL response from the external server on the OUT message body. +If the `variables` and `variablesHeader` parameters are not set and the IN body is an `org.apache.camel.util.json.JsonObject` instance, Camel will use it for the operation's variables (another `Map` is not used). If the `query`, `queryFile` and `queryHeader` parameters are not set, Camel will use the IN body as the query: text, or bytes, a stream or a file of it. Camel will store the GraphQL response from the external server on the OUT message body, as a `String` of the JSON response, wi [...] All headers from the IN message will be copied to the OUT message, so headers are preserved during routing. Additionally, Camel will add the HTTP response headers as well to the OUT message headers. diff --git a/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlEndpoint.java b/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlEndpoint.java index 1a0fb874023c..6ca952f33ec9 100644 --- a/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlEndpoint.java +++ b/components/camel-graphql/src/main/java/org/apache/camel/component/graphql/GraphqlEndpoint.java @@ -30,6 +30,9 @@ import org.apache.camel.Producer; import org.apache.camel.RuntimeCamelException; import org.apache.camel.component.http.HttpClientConfigurer; import org.apache.camel.http.base.HttpHeaderFilterStrategy; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.EndpointServiceLocation; import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.spi.Metadata; @@ -60,6 +63,17 @@ import org.slf4j.LoggerFactory; */ @UriEndpoint(firstVersion = "3.0.0", scheme = "graphql", title = "GraphQL", syntax = "graphql:httpUri", category = { Category.API }, producerOnly = true, lenientProperties = true) +@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + dependsOn = { "query", "queryFile", "queryHeader" }, + description = "The query, when none of query, queryFile and queryHeader is set: text, or" + + " bytes, a stream or a file of it. A Map is not a query. With one of them the" + + " body is not sent, except that an org.apache.camel.util.json.JsonObject body" + + " is the variables when neither variables nor variablesHeader is set"), + producerOut = @BodyType(value = { Carrier.TEXT, Carrier.NULL }, + description = "The response as text, the JSON with the data and errors of GraphQL: unmarshal" + + " it to read them. Errors in the response do not fail the exchange; a status" + + " outside 2xx does, unless throwExceptionOnFailure=false, which keeps the" + + " response as text. null for a response without a body")) public class GraphqlEndpoint extends DefaultEndpoint implements EndpointServiceLocation { private static final Logger LOG = LoggerFactory.getLogger(GraphqlEndpoint.class); @@ -92,7 +106,8 @@ public class GraphqlEndpoint extends DefaultEndpoint implements EndpointServiceL @UriParam(label = "advanced") private HttpClient httpClient; @UriParam(label = "producer", defaultValue = "true", - description = "Option to disable throwing the HttpOperationFailedException in case of failed responses from the remote server. This allows you to get all responses regardless of the HTTP status code.") + description = "Option to disable throwing the HttpOperationFailedException in case of failed responses from the" + + " remote server. This allows you to get all responses regardless of the HTTP status code.") private boolean throwExceptionOnFailure = true; @UriParam(label = "common,advanced", description = "To use a custom HeaderFilterStrategy to filter header to and from Camel message.") diff --git a/components/camel-jdbc/src/generated/resources/META-INF/org/apache/camel/component/jdbc/jdbc.json b/components/camel-jdbc/src/generated/resources/META-INF/org/apache/camel/component/jdbc/jdbc.json index 5109e6432688..141b79d25a3e 100644 --- a/components/camel-jdbc/src/generated/resources/META-INF/org/apache/camel/component/jdbc/jdbc.json +++ b/components/camel-jdbc/src/generated/resources/META-INF/org/apache/camel/component/jdbc/jdbc.json @@ -39,6 +39,10 @@ "CamelGeneratedKeysRowCount": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of rows in the header that contains generated keys.", "constantName": "org.apache.camel.component.jdbc.JdbcConstants#JDBC_GENERATED_KEYS_ROW_COUNT" }, "CamelGeneratedKeysRows": { "index": 7, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "List<Map<String, Object>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Rows that contains the generated keys.", "constantName": "org.apache.camel.component.jdbc.JdbcConstants#JDBC_GENERATED_KEYS_DATA" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "The SQL statement as text, or bytes, a stream or a file of it; a Map or a List is not a statement: set the SQL as the body. With useHeadersAsParameters, the values of its placeholders come from the CamelJdbcParameters header, or else from the headers" }, + "producerOut": { "carriers": [ "list", "unchanged" ], "dependsOn": [ "outputClass" ], "byOption": [ { "option": "outputType", "value": "SelectOne", "carriers": [ "map", "text", "value", "bytes", "pojo", "null", "unchanged" ] }, { "option": "outputType", "value": "StreamList", "carriers": [ "iterator", "unchanged" ] } ], "description": "The rows of a select: a List of Maps of the column names and their values (beans of outputClass when set). SelectOne gives the Map of the one row, the [...] + }, "properties": { "dataSourceName": { "index": 0, "kind": "path", "displayName": "Data Source Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Name of DataSource to lookup in the Registry. If the name is dataSource or default, then Camel will attempt to lookup a default DataSource from the registry, meaning if there is a only one instance of DataS [...] "allowNamedParameters": { "index": 1, "kind": "parameter", "displayName": "Allow Named Parameters", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to allow using named parameters in the queries." }, diff --git a/components/camel-jdbc/src/main/docs/jdbc-component.adoc b/components/camel-jdbc/src/main/docs/jdbc-component.adoc index 04943660e73f..059bdd5b9f6a 100644 --- a/components/camel-jdbc/src/main/docs/jdbc-component.adoc +++ b/components/camel-jdbc/src/main/docs/jdbc-component.adoc @@ -54,11 +54,15 @@ include::partial$component-endpoint-headers.adoc[] === Result -By default, the result is returned in the OUT body as an -`ArrayList<HashMap<String, Object>>`. The `List` object contains the +By default, the result of a select is returned in the OUT body as an +`ArrayList<LinkedHashMap<String, Object>>`. The `List` object contains the list of rows and the `Map` objects contain each row with the `String` key as the column name. You can use the option `outputType` to control -the result. +the result: `SelectOne` gives the `Map` of the one row, the value of its +column when it has one column, or `null` when there is no row, and +`StreamList` gives an `Iterator` of the rows, which can be read once. +A statement that is not a select leaves the body as it is, with the count +in the `CamelJdbcUpdateCount` header. *Note:* This component fetches `ResultSetMetaData` to be able to return the column name as the key in the `Map`. diff --git a/components/camel-jdbc/src/main/java/org/apache/camel/component/jdbc/JdbcEndpoint.java b/components/camel-jdbc/src/main/java/org/apache/camel/component/jdbc/JdbcEndpoint.java index 927733d122b8..305ae2e8f861 100644 --- a/components/camel-jdbc/src/main/java/org/apache/camel/component/jdbc/JdbcEndpoint.java +++ b/components/camel-jdbc/src/main/java/org/apache/camel/component/jdbc/JdbcEndpoint.java @@ -25,6 +25,9 @@ import org.apache.camel.Component; import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; @@ -36,6 +39,25 @@ import org.apache.camel.support.DefaultEndpoint; */ @UriEndpoint(firstVersion = "1.2.0", scheme = "jdbc", title = "JDBC", syntax = "jdbc:dataSourceName", producerOnly = true, category = { Category.DATABASE }, headersClass = JdbcConstants.class) +@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + description = "The SQL statement as text, or bytes, a stream or a file of it; a Map or a List" + + " is not a statement: set the SQL as the body. With useHeadersAsParameters," + + " the values of its placeholders come from the CamelJdbcParameters header, or" + + " else from the headers"), + producerOut = @BodyType(value = { Carrier.LIST, Carrier.UNCHANGED }, dependsOn = "outputClass", + byOption = { + @BodyType.When(option = "outputType", value = "SelectOne", + carriers = { + Carrier.MAP, Carrier.TEXT, Carrier.VALUE, Carrier.BYTES, + Carrier.POJO, Carrier.NULL, Carrier.UNCHANGED }), + @BodyType.When(option = "outputType", value = "StreamList", + carriers = { Carrier.ITERATOR, Carrier.UNCHANGED }) }, + description = "The rows of a select: a List of Maps of the column names and their values" + + " (beans of outputClass when set). SelectOne gives the Map of the one row," + + " the value of its column as the driver reads it when it has one, or null" + + " for no row; StreamList an Iterator of the rows, read once. A statement" + + " that is not a select leaves the body unchanged, with the count in the" + + " CamelJdbcUpdateCount header")) public class JdbcEndpoint extends DefaultEndpoint { private DataSource dataSource; diff --git a/components/camel-jsch/src/generated/resources/META-INF/org/apache/camel/component/scp/scp.json b/components/camel-jsch/src/generated/resources/META-INF/org/apache/camel/component/scp/scp.json index c725d39cb7a8..a5fafc55d1fa 100644 --- a/components/camel-jsch/src/generated/resources/META-INF/org/apache/camel/component/scp/scp.json +++ b/components/camel-jsch/src/generated/resources/META-INF/org/apache/camel/component/scp/scp.json @@ -30,6 +30,10 @@ "healthCheckConsumerEnabled": { "index": 3, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, "healthCheckProducerEnabled": { "index": 4, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on producer [...] }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "byOption": [ { "option": "allowNullBody", "value": "true", "carriers": [ "null", "text", "bytes", "stream", "file" ] } ], "description": "The content of the file: text, bytes, a stream or a file, which is read into memory first to send its size. A Map or a List fails: marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the name of the remote file in the CamelFileNameProduced header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.scp.ScpConfiguration", "configurationField": "configuration", "description": "Hostname of the FTP server" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.scp.ScpConfiguration", "configurationField": "configuration", "description": "Port of the FTP server" }, diff --git a/components/camel-jsch/src/main/java/org/apache/camel/component/scp/ScpEndpoint.java b/components/camel-jsch/src/main/java/org/apache/camel/component/scp/ScpEndpoint.java index 5f97aff0c484..4f888a5a7ae8 100644 --- a/components/camel-jsch/src/main/java/org/apache/camel/component/scp/ScpEndpoint.java +++ b/components/camel-jsch/src/main/java/org/apache/camel/component/scp/ScpEndpoint.java @@ -24,6 +24,9 @@ import org.apache.camel.component.file.GenericFileProducer; import org.apache.camel.component.file.remote.RemoteFileConsumer; import org.apache.camel.component.file.remote.RemoteFileEndpoint; import org.apache.camel.component.file.remote.RemoteFileOperations; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; @@ -39,6 +42,16 @@ import org.apache.camel.spi.UriParam; + ",transferLoggingIntervalSeconds,transferLoggingLevel,transferLoggingVerbose,resumeDownload" + ",handleDirectoryParserAbsoluteResult,activePortRange,ftpClient,ftpClientConfig" + ",ftpClientConfigParameters,ftpClientParameters,account,synchronous") +@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + byOption = @BodyType.When(option = "allowNullBody", value = "true", + carriers = { + Carrier.NULL, Carrier.TEXT, Carrier.BYTES, + Carrier.STREAM, Carrier.FILE }), + description = "The content of the file: text, bytes, a stream or a file, which is read into" + + " memory first to send its size. A Map or a List fails: marshal it first"), + producerOut = @BodyType(value = Carrier.UNCHANGED, + description = "Unchanged, with the name of the remote file in the CamelFileNameProduced" + + " header")) public class ScpEndpoint extends RemoteFileEndpoint<ScpFile> { @UriParam diff --git a/components/camel-micrometer/src/generated/resources/META-INF/org/apache/camel/component/micrometer/micrometer.json b/components/camel-micrometer/src/generated/resources/META-INF/org/apache/camel/component/micrometer/micrometer.json index f7e9210de897..8896fc905db2 100644 --- a/components/camel-micrometer/src/generated/resources/META-INF/org/apache/camel/component/micrometer/micrometer.json +++ b/components/camel-micrometer/src/generated/resources/META-INF/org/apache/camel/component/micrometer/micrometer.json @@ -37,6 +37,10 @@ "CamelMetricsDescription": { "index": 5, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Override description value in URI", "constantName": "org.apache.camel.component.micrometer.MicrometerConstants#HEADER_METRIC_DESCRIPTION" }, "CamelMetricsTags": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "java.lang.Iterable<Tag>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "To augment meter tags defined as URI parameters", "constantName": "org.apache.camel.component.micrometer.MicrometerConstants#HEADER_METRIC_TAGS" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "any" ], "description": "Not used, unless an option such as increment, decrement or value is a simple expression that reads it, which must then give a number. The CamelMetrics headers override the options" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged; the CamelMetrics headers are removed" } + }, "properties": { "metricsType": { "index": 0, "kind": "path", "displayName": "Metrics Type", "group": "producer", "label": "", "required": true, "type": "enum", "javaType": "io.micrometer.core.instrument.Meter.Type", "enum": [ "counter", "summary", "timer" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Type of metrics" }, "metricsName": { "index": 1, "kind": "path", "displayName": "Metrics Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportSimpleExpression": true, "description": "Name of metrics" }, diff --git a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerEndpoint.java b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerEndpoint.java index 90fb0911a1f9..5c5917433e51 100644 --- a/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerEndpoint.java +++ b/components/camel-micrometer/src/main/java/org/apache/camel/component/micrometer/MicrometerEndpoint.java @@ -28,6 +28,9 @@ import org.apache.camel.Component; import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; @@ -41,6 +44,11 @@ import org.apache.camel.support.DefaultEndpoint; remote = false, syntax = "micrometer:metricsType:metricsName", producerOnly = true, category = { Category.MONITORING }, headersClass = MicrometerConstants.class) +@BodyTypes(producerIn = @BodyType(value = Carrier.ANY, + description = "Not used, unless an option such as increment, decrement or value is a simple" + + " expression that reads it, which must then give a number. The CamelMetrics" + + " headers override the options"), + producerOut = @BodyType(value = Carrier.UNCHANGED, description = "Unchanged; the CamelMetrics headers are removed")) public class MicrometerEndpoint extends DefaultEndpoint { protected MeterRegistry registry; diff --git a/components/camel-pdf/src/generated/resources/META-INF/org/apache/camel/component/pdf/pdf.json b/components/camel-pdf/src/generated/resources/META-INF/org/apache/camel/component/pdf/pdf.json index f2edff0482dd..5a579be3f433 100644 --- a/components/camel-pdf/src/generated/resources/META-INF/org/apache/camel/component/pdf/pdf.json +++ b/components/camel-pdf/src/generated/resources/META-INF/org/apache/camel/component/pdf/pdf.json @@ -33,6 +33,10 @@ "CamelPdfDecryptionMaterial": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "org.apache.pdfbox.pdmodel.encryption.DecryptionMaterial", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Expected type is https:\/\/pdfbox.apache.org\/docs\/2.0.13\/javadocs\/org\/apache\/pdfbox\/pdmodel\/encryption\/DecryptionMaterial.htmlDecryptionMaterial. Mandatory header if PDF documen [...] "CamelPdfFilesToMerge": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "java.util.List<java.io.File>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Mandatory header for merge operation and ignored in all other operations. The array of pdf files that will be merged.", "constantName": "org.apache.camel.component.pdf.PdfHeaderConstants#FILES_TO_MERGE_HEADER_NAME" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "byOption": [ { "option": "operation", "value": "extractText", "carriers": [ "bytes", "stream", "file", "pojo" ] }, { "option": "operation", "value": "merge", "carriers": [ "any" ] } ], "description": "The text to write for create and append, which takes the document from the CamelPdfDocument header; a Map or a POJO is written as its toString: marshal it first. extractText reads a PDF from bytes, a stream, a file or a [...] + "producerOut": { "carriers": [ "pojo" ], "javaType": "java.io.ByteArrayOutputStream", "byOption": [ { "option": "operation", "value": "extractText", "carriers": [ "text" ], "javaType": "java.lang.String" } ], "description": "The PDF of create, append and merge in a ByteArrayOutputStream, which converts to bytes (convertBodyTo byte[] before extractText). The text of the document for extractText" } + }, "properties": { "operation": { "index": 0, "kind": "path", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "enum", "javaType": "org.apache.camel.component.pdf.PdfOperation", "enum": [ "create", "append", "extractText", "merge" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.pdf.PdfConfiguration", "configurationField": "pdfConfiguration", "description": "Operation type" }, "font": { "index": 1, "kind": "parameter", "displayName": "Font", "group": "producer", "label": "", "required": false, "type": "enum", "javaType": "java.lang.String", "enum": [ "COURIER", "COURIER_BOLD", "COURIER_OBLIQUE", "COURIER_BOLD_OBLIQUE", "HELVETICA", "HELVETICA_BOLD", "HELVETICA_OBLIQUE", "HELVETICA_BOLD_OBLIQUE", "TIMES_ROMAN", "TIMES_BOLD", "TIMES_ITALIC", "TIMES_BOLD_ITALIC", "SYMBOL", "ZAPF_DINGBATS" ], "deprecated": false, "autowired": false, "secret": false, "defaultVa [...] diff --git a/components/camel-pdf/src/main/docs/pdf-component.adoc b/components/camel-pdf/src/main/docs/pdf-component.adoc index e2e9dcebcb9a..fd890c034ca6 100644 --- a/components/camel-pdf/src/main/docs/pdf-component.adoc +++ b/components/camel-pdf/src/main/docs/pdf-component.adoc @@ -95,5 +95,8 @@ YAML:: It is now possible to get the body as a PD Document by using `PDDocument doc = exchange.getIn().getBody(PDDocument.class);`, which saves the trouble of converting the byte-array to a document. +The body after `create`, `append` and `merge` is a `ByteArrayOutputStream` with the PDF, which does not convert to a +`PDDocument`: convert it to `byte[]` before `extractText`. + NOTE: this only works for unprotected PDF files. For password-protected, the files still need to be converted manually. diff --git a/components/camel-pdf/src/main/java/org/apache/camel/component/pdf/PdfEndpoint.java b/components/camel-pdf/src/main/java/org/apache/camel/component/pdf/PdfEndpoint.java index 5310e999665b..cdbee30e74be 100644 --- a/components/camel-pdf/src/main/java/org/apache/camel/component/pdf/PdfEndpoint.java +++ b/components/camel-pdf/src/main/java/org/apache/camel/component/pdf/PdfEndpoint.java @@ -21,6 +21,9 @@ import org.apache.camel.Component; import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; import org.apache.camel.support.DefaultEndpoint; @@ -31,6 +34,24 @@ import org.apache.camel.support.DefaultEndpoint; @UriEndpoint(firstVersion = "2.16.0", scheme = "pdf", title = "PDF", syntax = "pdf:operation", producerOnly = true, remote = false, category = { Category.DOCUMENT, Category.TRANSFORMATION }, headersClass = PdfHeaderConstants.class) +@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + byOption = { + @BodyType.When(option = "operation", value = "extractText", + carriers = { + Carrier.BYTES, Carrier.STREAM, Carrier.FILE, + Carrier.POJO }), + @BodyType.When(option = "operation", value = "merge", carriers = Carrier.ANY) }, + description = "The text to write for create and append, which takes the document from the" + + " CamelPdfDocument header; a Map or a POJO is written as its toString:" + + " marshal it first. extractText reads a PDF from bytes, a stream, a file or a" + + " PDDocument, not from text. merge takes the files from the" + + " CamelPdfFilesToMerge header"), + producerOut = @BodyType(value = Carrier.POJO, javaType = "java.io.ByteArrayOutputStream", + byOption = @BodyType.When(option = "operation", value = "extractText", + carriers = Carrier.TEXT, javaType = "java.lang.String"), + description = "The PDF of create, append and merge in a ByteArrayOutputStream, which" + + " converts to bytes (convertBodyTo byte[] before extractText). The text of" + + " the document for extractText")) public class PdfEndpoint extends DefaultEndpoint { @UriParam diff --git a/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json b/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json index d96eead22f1f..b1ab2749020f 100644 --- a/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json +++ b/components/camel-smooks/src/generated/resources/META-INF/org/apache/camel/component/smooks/smooks.json @@ -31,6 +31,10 @@ "headers": { "CamelSmooksExecutionContext": { "index": 0, "kind": "header", "displayName": "", "group": "advanced", "label": "advanced", "required": false, "javaType": "org.smooks.api.ExecutionContext", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The Smooks execution context.", "constantName": "org.apache.camel.component.smooks.SmooksConstants#SMOOKS_EXECUTION_CONTEXT" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "The data the reader of the smooks config reads: XML by default, or EDI, CSV or JSON with a reader. A Map, a List or a POJO fails" }, + "producerOut": { "carriers": [ "unknown" ], "description": "What the exports of the smooks config give: the bean a JavaSink export extracts (a Map of the beans when it extracts none), or the text of a StringSink. Without exports, the input as a stream" } + }, "properties": { "smooksConfig": { "index": 0, "kind": "path", "displayName": "Smooks Config", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "description": "Path to the Smooks configuration file" }, "reportPath": { "index": 1, "kind": "parameter", "displayName": "Report Path", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "File path to place the generated HTML execution report. The report is a useful tool in the developers arsenal for diagnosing issues or comprehending a transformation. Do not set in production since this is a major performance drain" }, diff --git a/components/camel-smooks/src/main/docs/smooks-component.adoc b/components/camel-smooks/src/main/docs/smooks-component.adoc index 677f8b82670f..a3568ee63eee 100644 --- a/components/camel-smooks/src/main/docs/smooks-component.adoc +++ b/components/camel-smooks/src/main/docs/smooks-component.adoc @@ -14,6 +14,8 @@ The Camel Smooks component uses https://www.smooks.org/[Smooks] to break up the structured data (EDI, CSV, POJO, etc...) of a Camel message body into fragments. These fragments can be processed independently of one another from within Smooks. +The body is read by the reader of the Smooks configuration (XML by default) as text, bytes, a stream or a file. A POJO is read when the body is a `org.smooks.io.source.JavaSource` that holds it: a POJO, a `Map` or a `List` as the body itself fails. + Common applications of Smooks include: * transformation: EDI to CSV, POJO to EDI, POJO to XML, and so on. diff --git a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java index a86a20829bbb..1ffd96330e7a 100644 --- a/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java +++ b/components/camel-smooks/src/main/java/org/apache/camel/component/smooks/SmooksEndpoint.java @@ -21,6 +21,9 @@ import org.apache.camel.Component; import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; @@ -34,6 +37,13 @@ import org.apache.camel.support.service.ServiceHelper; @UriEndpoint(firstVersion = "4.7.0", scheme = "smooks", title = "Smooks", syntax = "smooks:smooksConfig", producerOnly = true, category = { Category.TRANSFORMATION }, headersClass = SmooksConstants.class) +@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + description = "The data the reader of the smooks config reads: XML by default, or EDI, CSV" + + " or JSON with a reader. A Map, a List or a POJO fails"), + producerOut = @BodyType(value = Carrier.UNKNOWN, + description = "What the exports of the smooks config give: the bean a JavaSink export" + + " extracts (a Map of the beans when it extracts none), or the text of a" + + " StringSink. Without exports, the input as a stream")) public class SmooksEndpoint extends DefaultEndpoint { @UriPath(description = "Path to the Smooks configuration file") diff --git a/components/camel-snmp/src/generated/resources/META-INF/org/apache/camel/component/snmp/snmp.json b/components/camel-snmp/src/generated/resources/META-INF/org/apache/camel/component/snmp/snmp.json index 4dc8c5a836cd..5033597bc5c6 100644 --- a/components/camel-snmp/src/generated/resources/META-INF/org/apache/camel/component/snmp/snmp.json +++ b/components/camel-snmp/src/generated/resources/META-INF/org/apache/camel/component/snmp/snmp.json @@ -30,6 +30,11 @@ "healthCheckConsumerEnabled": { "index": 3, "kind": "property", "displayName": "Health Check Consumer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all consumer based health checks from this component" }, "healthCheckProducerEnabled": { "index": 4, "kind": "property", "displayName": "Health Check Producer Enabled", "group": "health", "label": "health", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Used for enabling or disabling all producer based health checks from this component. Notice: Camel has by default disabled all producer based health-checks. You can turn on producer [...] }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", "format": "xml", "description": "The variable bindings of the response of a poll or of a trap as XML text: an snmp element with an entry of an oid and a value for each, and the community of a trap in the securityName header" }, + "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "type", "value": "TRAP", "carriers": [ "pojo" ], "javaType": "org.snmp4j.PDU" } ], "description": "Not used by a POLL or GET_NEXT, which requests the oids. A TRAP sends the body, which must be a PDU of SNMP4J for the snmpVersion: a PDUv1 for 0, the default, a PDU for 1 and a ScopedPDU for 3. Another body fails" }, + "producerOut": { "carriers": [ "pojo" ], "javaType": "org.apache.camel.component.snmp.SnmpMessage", "byOption": [ { "option": "type", "value": "GET_NEXT", "carriers": [ "list" ], "javaType": "java.util.List<org.apache.camel.component.snmp.SnmpMessage>" }, { "option": "type", "value": "TRAP", "carriers": [ "unchanged" ] } ], "description": "The response of a POLL as an SnmpMessage, a Camel message as the body, whose own body is the XML text of the consumer; it does not convert to text [...] + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Hostname of the SNMP enabled device" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": true, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Port number of the SNMP enabled device" }, diff --git a/components/camel-snmp/src/main/docs/snmp-component.adoc b/components/camel-snmp/src/main/docs/snmp-component.adoc index 2f0eda76b8e8..c0409fcea38c 100644 --- a/components/camel-snmp/src/main/docs/snmp-component.adoc +++ b/components/camel-snmp/src/main/docs/snmp-component.adoc @@ -41,7 +41,9 @@ and receiving traps. It can also be used to request information using GET method. -The response body type is `org.apache.camel.component.snmp.SnmpMessage`. +After a `POLL`, the body is an `org.apache.camel.component.snmp.SnmpMessage`: a Camel message whose own body is the +response as XML text. It does not convert to a `String` itself. A `GET_NEXT` gives a `List` of them, one per variable +of the walk. A `TRAP` producer sends the body, which must be an `org.snmp4j.PDU`, and leaves it as it is. // component options: START @@ -64,13 +66,10 @@ Given the situation, that I poll for the following OIDs: 1.3.6.1.2.1.43.5.1.1.11.1 ------------------------- -The result will be the following: - -*Result of toString conversion* +The body is the result as XML text, written on one line without an XML declaration (indented here): [source,xml] ----------------------------------------------------------- -<?xml version="1.0" encoding="UTF-8"?> <snmp> <entry> <oid>1.3.6.1.2.1.1.3.0</oid> @@ -127,7 +126,7 @@ snmp:127.0.0.1:162?protocol=udp&type=TRAP You can get the community of SNMP TRAP with message header `securityName`, peer address of the SNMP TRAP with message header `peerAddress`. -Routing example in Java: (converts the SNMP PDU to XML String) +Routing example in Java: (the body of the consumer is the SNMP PDU as XML text) [tabs] ==== diff --git a/components/camel-snmp/src/main/java/org/apache/camel/component/snmp/SnmpEndpoint.java b/components/camel-snmp/src/main/java/org/apache/camel/component/snmp/SnmpEndpoint.java index 81bf37263a51..7f37c20b7f6a 100644 --- a/components/camel-snmp/src/main/java/org/apache/camel/component/snmp/SnmpEndpoint.java +++ b/components/camel-snmp/src/main/java/org/apache/camel/component/snmp/SnmpEndpoint.java @@ -23,6 +23,9 @@ import org.apache.camel.Consumer; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.EndpointServiceLocation; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; @@ -40,6 +43,26 @@ import org.snmp4j.security.SecurityLevel; */ @UriEndpoint(firstVersion = "2.1.0", scheme = "snmp", title = "SNMP", syntax = "snmp:host:port", category = { Category.MONITORING }) +@BodyTypes(consumerOut = @BodyType(value = Carrier.TEXT, javaType = "java.lang.String", format = "xml", + description = "The variable bindings of the response of a poll or of a trap as XML text: an" + + " snmp element with an entry of an oid and a value for each, and the" + + " community of a trap in the securityName header"), + producerIn = @BodyType(value = Carrier.ANY, + byOption = @BodyType.When(option = "type", value = "TRAP", carriers = Carrier.POJO, + javaType = "org.snmp4j.PDU"), + description = "Not used by a POLL or GET_NEXT, which requests the oids. A TRAP sends the" + + " body, which must be a PDU of SNMP4J for the snmpVersion: a PDUv1 for 0, the" + + " default, a PDU for 1 and a ScopedPDU for 3. Another body fails"), + producerOut = @BodyType(value = Carrier.POJO, javaType = "org.apache.camel.component.snmp.SnmpMessage", + byOption = { + @BodyType.When(option = "type", value = "GET_NEXT", carriers = Carrier.LIST, + javaType = "java.util.List<" + + "org.apache.camel.component.snmp.SnmpMessage>"), + @BodyType.When(option = "type", value = "TRAP", carriers = Carrier.UNCHANGED) }, + description = "The response of a POLL as an SnmpMessage, a Camel message as the body, whose" + + " own body is the XML text of the consumer; it does not convert to text. A" + + " List of them, one per step of the walk, for GET_NEXT. A TRAP leaves the" + + " body unchanged")) public class SnmpEndpoint extends DefaultPollingEndpoint implements EndpointServiceLocation { public static final String DEFAULT_COMMUNITY = "public"; diff --git a/components/camel-spring-parent/camel-spring-jdbc/src/generated/resources/META-INF/org/apache/camel/component/spring/jdbc/spring-jdbc.json b/components/camel-spring-parent/camel-spring-jdbc/src/generated/resources/META-INF/org/apache/camel/component/spring/jdbc/spring-jdbc.json index 3e5e9fbd4669..9cfba1b8222e 100644 --- a/components/camel-spring-parent/camel-spring-jdbc/src/generated/resources/META-INF/org/apache/camel/component/spring/jdbc/spring-jdbc.json +++ b/components/camel-spring-parent/camel-spring-jdbc/src/generated/resources/META-INF/org/apache/camel/component/spring/jdbc/spring-jdbc.json @@ -39,6 +39,10 @@ "CamelGeneratedKeysRowCount": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "int", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of rows in the header that contains generated keys.", "constantName": "org.apache.camel.component.jdbc.JdbcConstants#JDBC_GENERATED_KEYS_ROW_COUNT" }, "CamelGeneratedKeysRows": { "index": 7, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "List<Map<String, Object>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Rows that contains the generated keys.", "constantName": "org.apache.camel.component.jdbc.JdbcConstants#JDBC_GENERATED_KEYS_DATA" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "The SQL statement as text, or bytes, a stream or a file of it; a Map or a List is not a statement: set the SQL as the body. With useHeadersAsParameters, the values of its placeholders come from the CamelJdbcParameters header, or else from the headers" }, + "producerOut": { "carriers": [ "list", "unchanged" ], "dependsOn": [ "outputClass" ], "byOption": [ { "option": "outputType", "value": "SelectOne", "carriers": [ "map", "text", "value", "bytes", "pojo", "null", "unchanged" ] }, { "option": "outputType", "value": "StreamList", "carriers": [ "iterator", "unchanged" ] } ], "description": "The rows of a select: a List of Maps of the column names and their values (beans of outputClass when set). SelectOne gives the Map of the one row, the [...] + }, "properties": { "dataSourceName": { "index": 0, "kind": "path", "displayName": "Data Source Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Name of DataSource to lookup in the Registry. If the name is dataSource or default, then Camel will attempt to lookup a default DataSource from the registry, meaning if there is a only one instance of DataS [...] "allowNamedParameters": { "index": 1, "kind": "parameter", "displayName": "Allow Named Parameters", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether to allow using named parameters in the queries." }, diff --git a/components/camel-spring-parent/camel-spring-jdbc/src/main/java/org/apache/camel/component/spring/jdbc/SpringJdbcEndpoint.java b/components/camel-spring-parent/camel-spring-jdbc/src/main/java/org/apache/camel/component/spring/jdbc/SpringJdbcEndpoint.java index 0f872849b4fa..0904041ad82f 100644 --- a/components/camel-spring-parent/camel-spring-jdbc/src/main/java/org/apache/camel/component/spring/jdbc/SpringJdbcEndpoint.java +++ b/components/camel-spring-parent/camel-spring-jdbc/src/main/java/org/apache/camel/component/spring/jdbc/SpringJdbcEndpoint.java @@ -21,6 +21,9 @@ import javax.sql.DataSource; import org.apache.camel.Category; import org.apache.camel.Component; import org.apache.camel.component.jdbc.JdbcEndpoint; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.UriEndpoint; /** @@ -29,6 +32,25 @@ import org.apache.camel.spi.UriEndpoint; @UriEndpoint(firstVersion = "3.10.0", scheme = "spring-jdbc", title = "Spring JDBC", syntax = "spring-jdbc:dataSourceName", producerOnly = true, category = { Category.DATABASE }) +@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + description = "The SQL statement as text, or bytes, a stream or a file of it; a Map or a List" + + " is not a statement: set the SQL as the body. With useHeadersAsParameters," + + " the values of its placeholders come from the CamelJdbcParameters header, or" + + " else from the headers"), + producerOut = @BodyType(value = { Carrier.LIST, Carrier.UNCHANGED }, dependsOn = "outputClass", + byOption = { + @BodyType.When(option = "outputType", value = "SelectOne", + carriers = { + Carrier.MAP, Carrier.TEXT, Carrier.VALUE, Carrier.BYTES, + Carrier.POJO, Carrier.NULL, Carrier.UNCHANGED }), + @BodyType.When(option = "outputType", value = "StreamList", + carriers = { Carrier.ITERATOR, Carrier.UNCHANGED }) }, + description = "The rows of a select: a List of Maps of the column names and their values" + + " (beans of outputClass when set). SelectOne gives the Map of the one row," + + " the value of its column as the driver reads it when it has one, or null" + + " for no row; StreamList an Iterator of the rows, read once. A statement" + + " that is not a select leaves the body unchanged, with the count in the" + + " CamelJdbcUpdateCount header")) public class SpringJdbcEndpoint extends JdbcEndpoint { public SpringJdbcEndpoint() { diff --git a/components/camel-tika/src/generated/resources/META-INF/org/apache/camel/component/tika/tika.json b/components/camel-tika/src/generated/resources/META-INF/org/apache/camel/component/tika/tika.json index ddc7c899b1b7..0f8029d743e1 100644 --- a/components/camel-tika/src/generated/resources/META-INF/org/apache/camel/component/tika/tika.json +++ b/components/camel-tika/src/generated/resources/META-INF/org/apache/camel/component/tika/tika.json @@ -27,6 +27,10 @@ "lazyStartProducer": { "index": 0, "kind": "property", "displayName": "Lazy Start Producer", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail [...] "autowiredEnabled": { "index": 1, "kind": "property", "displayName": "Autowired Enabled", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "description": "Whether autowiring is enabled. This is used for automatic autowiring options (the option must be marked as autowired) by looking up in the registry to find if there is a single instance of matching t [...] }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "The document: text, bytes, a stream or a file. A Map, a List, a POJO or no body fails, and parse fails on an empty document" }, + "producerOut": { "carriers": [ "pojo" ], "javaType": "java.io.ByteArrayOutputStream", "byOption": [ { "option": "operation", "value": "detect", "carriers": [ "text" ], "javaType": "java.lang.String" } ], "description": "parse gives a ByteArrayOutputStream with the content as XHTML, or as HTML or plain text with tikaParseOutputFormat, in tikaParseOutputEncoding, and the metadata of the document in headers; camel-tika parses HTML and text, other types need their Tika parser module. det [...] + }, "properties": { "operation": { "index": 0, "kind": "path", "displayName": "Operation", "group": "producer", "label": "", "required": true, "type": "enum", "javaType": "org.apache.camel.component.tika.TikaOperation", "enum": [ "parse", "detect" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.tika.TikaConfiguration", "configurationField": "tikaConfiguration", "description": "Operation type" }, "tikaParseOutputEncoding": { "index": 1, "kind": "parameter", "displayName": "Tika Parse Output Encoding", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.tika.TikaConfiguration", "configurationField": "tikaConfiguration", "description": "Tika Parse Output Encoding" }, diff --git a/components/camel-tika/src/main/docs/tika-component.adoc b/components/camel-tika/src/main/docs/tika-component.adoc index 52c7916bdd82..89071eaedbe4 100644 --- a/components/camel-tika/src/main/docs/tika-component.adoc +++ b/components/camel-tika/src/main/docs/tika-component.adoc @@ -43,7 +43,8 @@ include::partial$component-endpoint-headers.adoc[] === To Detect a file's MIME Type -The file should be placed in the Body. +The body is the document: text, bytes, a stream or a file. After `detect`, the body is the MIME type as text, such as +`text/html`. [tabs] ==== @@ -80,7 +81,10 @@ YAML:: === To Parse a File -The file should be placed in the Body. +The body is the document: text, bytes, a stream or a file. After `parse`, the body is a `ByteArrayOutputStream` with +the content as XHTML, or as HTML or plain text with `tikaParseOutputFormat`, which converts to a `String`, and the +metadata of the document are headers, such as `dc:title`. The component has the Tika parsers of HTML and text: other +types need their Tika parser module, such as `org.apache.tika:tika-parser-pdf-module` for PDF, or the content is empty. [tabs] ==== diff --git a/components/camel-tika/src/main/java/org/apache/camel/component/tika/TikaEndpoint.java b/components/camel-tika/src/main/java/org/apache/camel/component/tika/TikaEndpoint.java index f23be5aeb801..d4913f00bce1 100644 --- a/components/camel-tika/src/main/java/org/apache/camel/component/tika/TikaEndpoint.java +++ b/components/camel-tika/src/main/java/org/apache/camel/component/tika/TikaEndpoint.java @@ -21,6 +21,9 @@ import org.apache.camel.Component; import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; import org.apache.camel.support.DefaultEndpoint; @@ -30,6 +33,17 @@ import org.apache.camel.support.DefaultEndpoint; */ @UriEndpoint(firstVersion = "2.19.0", scheme = "tika", title = "Tika", syntax = "tika:operation", producerOnly = true, remote = false, category = { Category.DOCUMENT, Category.TRANSFORMATION }) +@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + description = "The document: text, bytes, a stream or a file. A Map, a List, a POJO or no" + + " body fails, and parse fails on an empty document"), + producerOut = @BodyType(value = Carrier.POJO, javaType = "java.io.ByteArrayOutputStream", + byOption = @BodyType.When(option = "operation", value = "detect", carriers = Carrier.TEXT, + javaType = "java.lang.String"), + description = "parse gives a ByteArrayOutputStream with the content as XHTML, or as HTML or" + + " plain text with tikaParseOutputFormat, in tikaParseOutputEncoding, and the" + + " metadata of the document in headers; camel-tika parses HTML and text," + + " other types need their Tika parser module. detect gives the media type as" + + " text, such as text/html")) public class TikaEndpoint extends DefaultEndpoint { @UriParam diff --git a/components/camel-vertx/camel-vertx-http/src/generated/resources/META-INF/org/apache/camel/component/vertx/http/vertx-http.json b/components/camel-vertx/camel-vertx-http/src/generated/resources/META-INF/org/apache/camel/component/vertx/http/vertx-http.json index 81042fb956a6..e3091d4173ea 100644 --- a/components/camel-vertx/camel-vertx-http/src/generated/resources/META-INF/org/apache/camel/component/vertx/http/vertx-http.json +++ b/components/camel-vertx/camel-vertx-http/src/generated/resources/META-INF/org/apache/camel/component/vertx/http/vertx-http.json @@ -55,6 +55,10 @@ "CamelHttpPath": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Request URI's path, the header will be used to build the request URI with the HTTP_URI.", "constantName": "org.apache.camel.component.vertx.http.VertxHttpConstants#HTTP_PATH" }, "Content-Encoding": { "index": 7, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The HTTP content encoding. Is set to provide a content encoding, such as gzip.", "constantName": "org.apache.camel.component.vertx.http.VertxHttpConstants#CONTENT_ENCODING" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "description": "The request body: text, bytes, a stream or a file (a file as a multipart form with multipartUpload), or a Vert.x Buffer, MultiMap (a form) or MultipartForm. A Map, a List or a POJO fails: marshal it first. Without httpMethod, a query string in the URI or no body sends a GET, and a body a POST" }, + "producerOut": { "carriers": [ "bytes", "null" ], "description": "The response body as a byte array, or null for a response without a body. A Vert.x Buffer with responsePayloadAsByteArray=false, which stream caching turns into a stream" } + }, "properties": { "httpUri": { "index": 0, "kind": "path", "displayName": "Http Uri", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.net.URI", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.vertx.http.VertxHttpConfiguration", "configurationField": "configuration", "description": "The HTTP URI to connect to" }, "bridgeEndpoint": { "index": 1, "kind": "parameter", "displayName": "Bridge Endpoint", "group": "producer", "label": "producer", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.vertx.http.VertxHttpConfiguration", "configurationField": "configuration", "description": "If the option is true, the Exchange.HTTP_URI header will be ignored and the [...] diff --git a/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpEndpoint.java b/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpEndpoint.java index 4da417868706..9c2895e746f8 100644 --- a/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpEndpoint.java +++ b/components/camel-vertx/camel-vertx-http/src/main/java/org/apache/camel/component/vertx/http/VertxHttpEndpoint.java @@ -28,6 +28,9 @@ import org.apache.camel.Processor; import org.apache.camel.Producer; import org.apache.camel.component.vertx.common.VertxHelper; import org.apache.camel.http.base.HttpHelper; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.EndpointServiceLocation; import org.apache.camel.spi.UriEndpoint; import org.apache.camel.spi.UriParam; @@ -39,6 +42,16 @@ import org.apache.camel.util.ObjectHelper; @UriEndpoint(firstVersion = "3.5.0", scheme = "vertx-http", title = "Vert.x HTTP Client", syntax = "vertx-http:httpUri", category = { Category.HTTP }, producerOnly = true, lenientProperties = true, headersClass = VertxHttpConstants.class) +@BodyTypes(producerIn = @BodyType(value = { Carrier.NULL, Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + description = "The request body: text, bytes, a stream or a file (a file as a multipart form" + + " with multipartUpload), or a Vert.x Buffer, MultiMap (a form) or" + + " MultipartForm. A Map, a List or a POJO fails: marshal it first. Without" + + " httpMethod, a query string in the URI or no body sends a GET, and a body a" + + " POST"), + producerOut = @BodyType(value = { Carrier.BYTES, Carrier.NULL }, + description = "The response body as a byte array, or null for a response without a body. A" + + " Vert.x Buffer with responsePayloadAsByteArray=false, which stream caching" + + " turns into a stream")) public class VertxHttpEndpoint extends DefaultEndpoint implements EndpointServiceLocation { @UriParam diff --git a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java index 51a1730eb677..7091f6cb8183 100644 --- a/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java +++ b/dsl/camel-jbang/camel-jbang-core/src/test/java/org/apache/camel/dsl/jbang/core/commands/ai/CatalogDocsTest.java @@ -161,9 +161,9 @@ class CatalogDocsTest { .startsWith("pojo (org.w3c.dom.NodeList). The nodes the expression selects. With resultQName=STRING: text")); // a component that does not declare them has none, rather than a guess - JsonObject jdbc = catalogDoc(Map.of("name", "jdbc", "kind", "component", "includeOptions", false)); - assertNull(jdbc.get("bodyTypes")); - assertNull(jdbc.get("bodyTypesHint")); + JsonObject ldif = catalogDoc(Map.of("name", "ldif", "kind", "component", "includeOptions", false)); + assertNull(ldif.get("bodyTypes")); + assertNull(ldif.get("bodyTypesHint")); } @Test diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java index c9b1180d50c3..88695c3f6004 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java @@ -1731,6 +1731,174 @@ public class TextBodyFlowTest { .anySatisfy(m -> assertThat(m).contains("route events: simple reads a field of the body (${body[id]})")); } + @Test + public void testTheBodyOfQueriesDocumentsAndFiles() { + // jdbc, scp, vertx-http, tika, pdf create and graphql without a query option need the body as text, bytes, a + // stream or a file, so parsed data must be marshalled first (graphql with a query does not send the body); + // graphql, tika detect, pdf extractText, as2 and the snmp consumer give text, and jdbc rows, micrometer (which + // keeps the body) and smooks (whatever its config exports) say nothing + String yaml = """ + - route: + id: query + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: jdbc:myDataSource + - route: + id: upload + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: scp:localhost:22/upload + - route: + id: post + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: vertx-http:http://localhost:8080/orders + - route: + id: parse + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: tika:parse + - route: + id: print + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: pdf:create + - route: + id: ask + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: graphql://http://localhost:8080/graphql + - route: + id: variables + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: graphql://http://localhost:8080/graphql?query={books{id}} + - route: + id: graph + from: + uri: timer:tick + steps: + - to: graphql://http://localhost:8080/graphql?query={books{id}} + - setHeader: + name: books + simple: ${body[data]} + - route: + id: detect + from: + uri: file:inbox + steps: + - to: tika:detect + - setHeader: + name: type + simple: ${body[type]} + - route: + id: extract + from: + uri: file:inbox + steps: + - to: pdf:extractText + - setHeader: + name: title + simple: ${body[title]} + - route: + id: partner + from: + uri: as2:server/listen?requestUriPattern=/orders + steps: + - setHeader: + name: id + simple: ${body[id]} + - route: + id: trap + from: + uri: snmp:0.0.0.0:162?type=TRAP + steps: + - setHeader: + name: oid + simple: ${body[oid]} + - route: + id: rows + from: + uri: timer:tick + steps: + - setBody: + constant: select * from orders + - to: jdbc:myDataSource + - setHeader: + name: id + simple: ${body[0][ID]} + - route: + id: count + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: micrometer:counter:orders + - setHeader: + name: id + simple: ${body[id]} + - route: + id: transform + from: + uri: file:inbox + steps: + - to: smooks:smooks-config.xml + - setHeader: + name: id + simple: ${body[id]} + """; + assertThat(lines(yaml)).hasSize(11) + .anySatisfy(m -> assertThat(m).contains("route query: to: jdbc needs the body as text")) + .anySatisfy(m -> assertThat(m).contains("route ask: to: graphql needs the body as text")) + .anySatisfy(m -> assertThat(m).contains("route upload: to: scp needs the body as text")) + .anySatisfy(m -> assertThat(m).contains("route post: to: vertx-http needs the body as text")) + .anySatisfy(m -> assertThat(m).contains("route parse: to: tika needs the body as text")) + .anySatisfy(m -> assertThat(m).contains("route print: to: pdf needs the body as text")) + .anySatisfy(m -> assertThat(m).contains("route graph: simple reads a field of the body (${body[data]})")) + .anySatisfy(m -> assertThat(m).contains("route detect: simple reads a field of the body (${body[type]})")) + .anySatisfy(m -> assertThat(m).contains("route extract: simple reads a field of the body (${body[title]})")) + .anySatisfy(m -> assertThat(m).contains("route partner: simple reads a field of the body (${body[id]})")) + .anySatisfy(m -> assertThat(m).contains("route trap: simple reads a field of the body (${body[oid]})")); + } + @Test public void testAnOptionValueInAnotherStyleOfTheEnum() { // the catalog and the enum type converter take convert-to-json and convertToJson as CONVERT_TO_JSON, so after
