This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch main in repository https://gitbox.apache.org/repos/asf/camel.git
commit ab959a5b0cb6e63b9b8534f4808c7583309a5e94 Author: Claus Ibsen <[email protected]> AuthorDate: Sat Oct 24 19:57:01 2026 +0200 CAMEL-24961: Catalog body types for jpa, sql-stored, mybatis, jooq, pgevent, duckdb, clickhouse and four more database components (#28393) Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../camel/catalog/components/clickhouse.json | 4 +++ .../org/apache/camel/catalog/components/drill.json | 4 +++ .../apache/camel/catalog/components/duckdb.json | 4 +++ .../org/apache/camel/catalog/components/jooq.json | 5 +++ .../org/apache/camel/catalog/components/jpa.json | 5 +++ .../org/apache/camel/catalog/components/kudu.json | 4 +++ .../camel/catalog/components/mybatis-bean.json | 4 +++ .../apache/camel/catalog/components/mybatis.json | 5 +++ .../catalog/components/pg-replication-slot.json | 3 ++ .../apache/camel/catalog/components/pgevent.json | 5 +++ .../camel/catalog/components/sql-stored.json | 4 +++ .../apache/camel/catalog/docs/jooq-component.adoc | 6 ++-- .../camel/catalog/docs/mybatis-bean-component.adoc | 12 ++++--- .../camel/catalog/docs/mybatis-component.adoc | 5 +-- .../camel/component/clickhouse/clickhouse.json | 4 +++ .../component/clickhouse/ClickHouseEndpoint.java | 25 +++++++++++++ .../org/apache/camel/component/drill/drill.json | 4 +++ .../camel/component/drill/DrillEndpoint.java | 12 +++++++ .../org/apache/camel/component/duckdb/duckdb.json | 4 +++ .../camel/component/duckdb/DuckDbEndpoint.java | 27 ++++++++++++++ .../org/apache/camel/component/jooq/jooq.json | 5 +++ .../camel-jooq/src/main/docs/jooq-component.adoc | 6 ++-- .../apache/camel/component/jooq/JooqEndpoint.java | 17 +++++++++ .../org/apache/camel/component/jpa/jpa.json | 5 +++ .../apache/camel/component/jpa/JpaEndpoint.java | 30 ++++++++++++++++ .../org/apache/camel/component/kudu/kudu.json | 4 +++ .../apache/camel/component/kudu/KuduEndpoint.java | 21 +++++++++++ .../camel/component/mybatis/mybatis-bean.json | 4 +++ .../apache/camel/component/mybatis/mybatis.json | 5 +++ .../src/main/docs/mybatis-bean-component.adoc | 12 ++++--- .../src/main/docs/mybatis-component.adoc | 5 +-- .../component/mybatis/MyBatisBeanEndpoint.java | 13 +++++++ .../camel/component/mybatis/MyBatisEndpoint.java | 41 ++++++++++++++++++++++ .../pg/replication/slot/pg-replication-slot.json | 3 ++ .../slot/PgReplicationSlotEndpoint.java | 8 +++++ .../apache/camel/component/pgevent/pgevent.json | 5 +++ .../camel/component/pgevent/PgEventEndpoint.java | 12 +++++++ .../camel/component/sql/stored/sql-stored.json | 4 +++ .../component/sql/stored/SqlStoredEndpoint.java | 25 +++++++++++++ 39 files changed, 351 insertions(+), 20 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/clickhouse.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/clickhouse.json index 6e4f34d47ff7..db94b15eabb7 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/clickhouse.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/clickhouse.json @@ -42,6 +42,10 @@ "CamelClickHouseReadRows": { "index": 5, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of rows read by a query operation.", "constantName": "org.apache.camel.component.clickhouse.ClickHouseConstants#READ_ROWS" }, "CamelClickHousePingOk": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The boolean result of a ping operation.", "constantName": "org.apache.camel.component.clickhouse.ClickHouseConstants#PING_OK" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "list" ], "byOption": [ { "option": "operation", "value": "QUERY", "carriers": [ "text", "bytes", "stream", "file" ] }, { "option": "operation", "value": "PING", "carriers": [ "any" ] } ], "description": "The rows to insert, in the format option (JSONEachRow: one JSON object per line), as text, bytes, a stream or a file; or a List of objects whose class is registered on the Client. A Map or a List of Maps fails: marshal [...] + "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": "operation", "value": "QUERY", "carriers": [ "text" ], "javaType": "java.lang.String" }, { "option": "operation", "value": "PING", "carriers": [ "value" ], "javaType": "java.lang.Boolean" } ], "description": "Insert leaves the body unchanged, with the count in the CamelClickHouseWrittenRows header. Query gives the result as a String in the format option (JSONEachRow: one JSON object per line); binary formats such [...] + }, "properties": { "database": { "index": 0, "kind": "path", "displayName": "Database", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The ClickHouse database. A table may also be provided using the database.table syntax." }, "asyncInsert": { "index": 1, "kind": "parameter", "displayName": "Async Insert", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to use ClickHouse server-side asynchronous inserts (async_insert=1)." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/drill.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/drill.json index e3543bc15f93..c01654c60035 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/drill.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/drill.json @@ -30,6 +30,10 @@ "headers": { "CamelDrillQuery": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The drill query", "constantName": "org.apache.camel.component.drill.DrillConstants#DRILL_QUERY" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "any" ], "description": "The body is not read: the query comes from the CamelDrillQuery header, and a query in the body without that header fails" }, + "producerOut": { "carriers": [ "list" ], "javaType": "java.util.List<java.util.Map<String, Object>>", "description": "The rows of the query: a List of Maps of the column names (case insensitive) and their values, an empty List for no rows. A statement such as CREATE TABLE AS, DROP or ALTER SESSION gives the one row Drill answers with, such as ok and summary" } + }, "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, "description": "Host name or IP address" }, "clusterId": { "index": 1, "kind": "parameter", "displayName": "Cluster Id", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Cluster ID https:\/\/drill.apache.org\/docs\/using-the-jdbc-driver\/#determining-the-cluster-id" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/duckdb.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/duckdb.json index ae7b10fe972c..b018b667caae 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/duckdb.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/duckdb.json @@ -39,6 +39,10 @@ "CamelDuckDbRowsRead": { "index": 5, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of rows returned by a query.", "constantName": "org.apache.camel.component.duckdb.DuckDbConstants#ROWS_READ" }, "CamelDuckDbPingOk": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The boolean result of a ping operation.", "constantName": "org.apache.camel.component.duckdb.DuckDbConstants#PING_OK" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "dependsOn": [ "query" ], "byOption": [ { "option": "operation", "value": "INSERT", "carriers": [ "list" ] }, { "option": "operation", "value": "COPY", "carriers": [ "file", "text" ] }, { "option": "operation", "value": "PING", "carriers": [ "any" ] } ], "description": "The SQL statement as text, or bytes, a stream or a file of it; the query option or the CamelDuckDbQuery header takes its place. Insert takes a List of [...] + "producerOut": { "carriers": [ "value" ], "javaType": "java.lang.Long", "byOption": [ { "option": "operation", "value": "QUERY", "carriers": [ "list" ], "javaType": "java.util.List<java.util.Map<String, Object>>" }, { "option": "operation", "value": "PING", "carriers": [ "value" ], "javaType": "java.lang.Boolean" }, { "option": "resultFormat", "value": "JSON", "carriers": [ "text", "value" ] } ], "description": "The count of rows written or affected as a Long, also in the CamelDuckDb [...] + }, "properties": { "databasePath": { "index": 0, "kind": "path", "displayName": "Database Path", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Database path, either :memory: or a relative or absolute file path." }, "batchSize": { "index": 1, "kind": "parameter", "displayName": "Batch Size", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "description": "Batch size for insert when the body is a List. 0 inserts all rows in one JDBC batch." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jooq.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jooq.json index b7084e5f2d02..bce0ae172257 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jooq.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jooq.json @@ -35,6 +35,11 @@ "healthCheckConsumerEnabled": { "index": 8, "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": 9, "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": [ "pojo" ], "description": "One row of the table of the entityType per message, as the jOOQ UpdatableRecord of that class" }, + "producerIn": { "carriers": [ "pojo" ], "dependsOn": [ "query" ], "description": "A jOOQ object, by the operation: a record of the entityType to store for NONE, an org.jooq.Query for EXECUTE, an org.jooq.ResultQuery (a select) for FETCH. Text, a Map or a List fails: there is no conversion to them. With the query option the SQL is that query and the body is not read" }, + "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": "operation", "value": "FETCH", "carriers": [ "list" ], "javaType": "org.jooq.Result" } ], "description": "NONE stores the record and EXECUTE runs the query, both leave the body unchanged. FETCH gives the org.jooq.Result of the query, a List of its records, which is empty for no row" } + }, "properties": { "entityType": { "index": 0, "kind": "path", "displayName": "Entity Type", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jooq.JooqConfiguration", "configurationField": "configuration", "description": "JOOQ entity class" }, "databaseConfiguration": { "index": 1, "kind": "parameter", "displayName": "Database Configuration", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "org.jooq.Configuration", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jooq.JooqConfiguration", "configurationField": "configuration", "description": "To use a specific database configuration" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jpa.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jpa.json index 544a910e1097..54e42766013c 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jpa.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/jpa.json @@ -41,6 +41,11 @@ "CamelJpaMaximumResults": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Defines the maximum number of results to retrieve on the query; takes precedence over the value set on the endpoint, if any.", "constantName": "org.apache.camel.component.jpa.JpaConstants#JPA_MAXIMUM_RESULTS" }, "CamelJpaFirstResult": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Defines the position of the first result to retrieve; takes precedence over the value set on the endpoint, if any.", "constantName": "org.apache.camel.component.jpa.JpaConstants#JPA_FIRST_RESULT" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "pojo" ], "dependsOn": [ "query", "namedQuery", "nativeQuery" ], "description": "One entity of the entityType class per message. A query that selects columns gives one row per message: an Object array, or the value of a single column; a nativeQuery gives an Object array unless resultClass is set" }, + "producerIn": { "carriers": [ "pojo", "list" ], "dependsOn": [ "query", "namedQuery", "nativeQuery" ], "byOption": [ { "option": "findEntity", "value": "true", "carriers": [ "value", "text" ] } ], "description": "The entity to persist, merge or remove, converted to the entityType class; a List or an array of entities needs entityType java.util.List (or java.lang.Object). Text, bytes or a Map fail. With findEntity, the primary key. With a query the body is not read: the parameters com [...] + "producerOut": { "carriers": [ "pojo", "list" ], "dependsOn": [ "query", "namedQuery", "nativeQuery", "outputTarget" ], "byOption": [ { "option": "usePersist", "value": "true", "carriers": [ "unchanged" ] }, { "option": "findEntity", "value": "true", "carriers": [ "pojo", "null" ] } ], "description": "The managed entity that merge returns, or a List or array of them; usePersist leaves the body as sent. findEntity gives the entity, or null when there is none. A query gives the List of [...] + }, "properties": { "entityType": { "index": 0, "kind": "path", "displayName": "Entity Type", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Entity class name" }, "entityManagerFactory": { "index": 1, "kind": "parameter", "displayName": "Entity Manager Factory", "group": "common", "label": "", "required": false, "type": "object", "javaType": "jakarta.persistence.EntityManagerFactory", "deprecated": false, "autowired": false, "secret": false, "description": "The EntityManagerFactory to use." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/kudu.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/kudu.json index f1e66c4048a5..fafb30d43184 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/kudu.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/kudu.json @@ -35,6 +35,10 @@ "CamelKuduScanPredicate": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "org.apache.kudu.client.KuduPredicate", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The predicate for scan operation", "constantName": "org.apache.camel.component.kudu.KuduConstants#CAMEL_KUDU_SCAN_PREDICATE" }, "CamelKuduScanLimit": { "index": 4, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The limit on the number of rows for scan operation", "constantName": "org.apache.camel.component.kudu.KuduConstants#CAMEL_KUDU_SCAN_LIMIT" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "map" ], "byOption": [ { "option": "operation", "value": "SCAN", "carriers": [ "any" ] }, { "option": "operation", "value": "CREATE_TABLE", "carriers": [ "any" ] } ], "description": "For insert, update, upsert and delete: a Map of the column names and their values, one row, each value of the Java type of its column (a String for an INT32 column fails); delete uses only the key columns. Text such as JSON, a List or a POJO fails: unmarshal it into a Map fi [...] + "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": "operation", "value": "SCAN", "carriers": [ "list" ], "javaType": "java.util.List<java.util.Map<String, Object>>" } ], "description": "Scan gives a List of the rows, each a Map of the column names and their values, an empty List for no rows. The other operations leave the body unchanged" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Host of the server to connect to" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Port of the server to connect to" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis-bean.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis-bean.json index 9d9f7265a9fb..4efcf074c49f 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis-bean.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis-bean.json @@ -34,6 +34,10 @@ "headers": { "CamelMyBatisResult": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Object", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response returned from MyBatis in any of the operations. Such as INSERT could return the auto-generated key, or number of rows etc.", "constantName": "org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_RESULT" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "any" ], "description": "The argument of the method of the mapper, converted to its parameter type by the bean binding, so the text 123 fits an int parameter. With inputHeader the argument is that header and the body is not read" }, + "producerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" ], "description": "What the method of the mapper returns, as it declares it: a bean, a List of rows, a Map, a value such as the count of an update, or null for no row; also in the CamelMyBatisResult header. A void method leaves the body unchanged. With outputHeader the result goes in that header and the body is unchanged" } + }, "properties": { "beanName": { "index": 0, "kind": "path", "displayName": "Bean Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Name of the bean with the MyBatis annotations. This can either by a type alias or a FQN class name." }, "methodName": { "index": 1, "kind": "path", "displayName": "Method Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Name of the method on the bean that has the SQL query to be executed." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis.json index e71af6ae3dfe..b204cc83149e 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/mybatis.json @@ -36,6 +36,11 @@ "CamelMyBatisResult": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Object", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response returned from MyBatis in any of the operations. Such as INSERT could return the auto-generated key, or number of rows etc.", "constantName": "org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_RESULT" }, "CamelMyBatisStatementName": { "index": 1, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The statementName used (for example: insertAccount).", "constantName": "org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_STATEMENT_NAME" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" ], "byOption": [ { "option": "useIterator", "value": "false", "carriers": [ "list" ] } ], "description": "One row of the select per message, as the resultType or resultMap of the statement maps it: a bean, a Map or a single value, and null for a row of only nulls. With useIterator=false a List of all the rows in one message; with outputHeader the row goes in that header and the body is null" }, + "producerIn": { "carriers": [ "any" ], "description": "The parameter of the statement, given to MyBatis as it is, without type conversion: it must fit the parameterType, so the text 123 fails an int parameter. A bean or a Map for several parameters; no body runs the statement without one. Insert, Update and Delete run once per element of a List, an array or an Iterator, the List variants once with the whole List. With inputHeader the parameter is that header and the body is not read" }, + "producerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" ], "byOption": [ { "option": "statementType", "value": "SelectOne", "carriers": [ "unknown" ] }, { "option": "statementType", "value": "SelectList", "carriers": [ "list" ] }, { "option": "statementType", "value": "Insert", "carriers": [ "unchanged" ] }, { "option": "statementType", "value": "InsertList", "carriers": [ "unchanged" ] }, { "option": "statementType", "value": "Update", "carriers": [ "unchanged" ] } [...] + }, "properties": { "statement": { "index": 0, "kind": "path", "displayName": "Statement", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The statement name in the MyBatis XML mapping file which maps to the query, insert, update or delete operation you wish to evaluate." }, "maxMessagesPerPoll": { "index": 1, "kind": "parameter", "displayName": "Max Messages Per Poll", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "description": "This option is intended to split results returned by the database pool into the batches and deliver them in multiple exchanges. This integer defines the maximum messages to deliver in single exchange [...] diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pg-replication-slot.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pg-replication-slot.json index 334949141e7c..db98358463cb 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pg-replication-slot.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pg-replication-slot.json @@ -29,6 +29,9 @@ "healthCheckConsumerEnabled": { "index": 2, "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": 3, "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": [ "bytes" ], "javaType": "byte[]", "description": "One message of the output plugin of the slot, as bytes: text for test_decoding, JSON for wal2json, the binary protocol for pgoutput; convert it to a String for the text plugins. The exchange id is the LSN of the message" } + }, "properties": { "slot": { "index": 0, "kind": "path", "displayName": "Slot", "group": "common", "label": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Replication Slot name" }, "host": { "index": 1, "kind": "path", "displayName": "Host", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "localhost", "description": "Postgres host" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pgevent.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pgevent.json index bfd65985c32f..6da6f6368b47 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pgevent.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pgevent.json @@ -31,6 +31,11 @@ "headers": { "channel": { "index": 0, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of the channel.", "constantName": "org.apache.camel.component.pgevent.PgEventConstants#HEADER_CHANNEL" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", "description": "The payload of the notification as a String, empty when it was sent without one; the channel is in the channel header" }, + "producerIn": { "carriers": [ "any" ], "description": "The payload of the notification, converted to a String: text, or bytes, a stream or a file of it; a Map or a POJO is sent as its toString(), so marshal it first. PostgreSQL takes a payload of less than 8000 bytes, and no body sends an empty payload" }, + "producerOut": { "carriers": [ "unchanged" ] } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "localhost", "description": "To connect using hostname and port to the database." }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 5432, "description": "To connect using hostname and port to the database." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json index 6af8b9790c35..16606cd4dc34 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/sql-stored.json @@ -35,6 +35,10 @@ "CamelSqlStoredParameters": { "index": 1, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Iterator", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The parameters", "constantName": "org.apache.camel.component.sql.stored.SqlStoredConstants#SQL_STORED_PARAMETERS" }, "CamelSqlStoredUpdateCount": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "important": true, "description": "The update count", "constantName": "org.apache.camel.component.sql.stored.SqlStoredConstants#SQL_STORED_UPDATE_COUNT" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "batch", "value": "true", "carriers": [ "list", "iterator" ] }, { "option": "useMessageBodyForTemplate", "value": "true", "carriers": [ "text" ] } ], "description": "What the expressions of the IN parameters read: a :#name parameter takes its value from a Map body, or else from the header. With batch, a List or an Iterator of such bodies, one batch item each (a single Map is not a batch); with useMessageBodyForTemplate, [...] + "producerOut": { "carriers": [ "map" ], "javaType": "java.util.Map<String, Object>", "dependsOn": [ "outputHeader" ], "byOption": [ { "option": "noop", "value": "true", "carriers": [ "unchanged" ] }, { "option": "batch", "value": "true", "carriers": [ "unchanged" ] } ], "description": "A Map of the names of the OUT and INOUT parameters and their values, with a result set the procedure returns under #result-set-1 (a List of Maps) and the update count under #update-count-1, which is al [...] + }, "properties": { "template": { "index": 0, "kind": "path", "displayName": "Template", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "largeInput": true, "inputLanguage": "sql", "description": "Sets the stored procedure template to perform. You can externalize the template by using file: or classpath: as prefix and specify the location of [...] "batch": { "index": 1, "kind": "parameter", "displayName": "Batch", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enables or disables batch mode" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jooq-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jooq-component.adoc index a6d33c8bad3d..cf61ef759ff8 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jooq-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/jooq-component.adoc @@ -104,9 +104,9 @@ When using jooq as a producer you can use any of the following `JooqOperation` o [width="100%",cols="1,2",options="header"] |=== | Operation | Description -| none | Execute a query (default) -| execute | Execute a query with no expected results -| fetch | Execute a query and the result of the query is stored as the new message body +| none | Store the entity (the record of the entity type) in the message body (default) +| execute | Execute a query (an `org.jooq.Query` in the message body, or the `query` option) with no expected results +| fetch | Execute a query (an `org.jooq.ResultQuery` in the message body, or the `query` option) and the `org.jooq.Result` of the query is stored as the new message body |=== == Example diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-bean-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-bean-component.adoc index 80eeacaad41f..c11b5f69ffd4 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-bean-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-bean-component.adoc @@ -49,11 +49,13 @@ include::partial$component-endpoint-headers.adoc[] === Message Body -The response from MyBatis will only be set as the body if it's a -`SELECT` statement. That means, for example, for `INSERT` statements -Camel will not replace the body. This allows you to continue routing and -keep the original body. The response from MyBatis is always stored in -the header with the key `CamelMyBatisResult`. +The value the mapper method returns is set as the body, and is also stored in +the header with the key `CamelMyBatisResult`. That is the bean, the `List` or +the `Map` of a select (or null when there is no row), and the count of rows of an +`INSERT`, `UPDATE` or `DELETE` method that returns an `int`. A `void` method +leaves the body as it was, which allows you to continue routing with the +original body. With the `outputHeader` option the result is stored in that +header instead, and the body is not changed. == Examples diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-component.adoc index 34c9939ba20b..d84d40a70f92 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mybatis-component.adoc @@ -60,8 +60,9 @@ include::partial$component-endpoint-headers.adoc[] The response from MyBatis will only be set as the body if it's a `SELECT` statement. That means, for example, for `INSERT` statements Camel will not replace the body. This allows you to continue routing and -keep the original body. The response from MyBatis is always stored in -the header with the key `CamelMyBatisResult`. +keep the original body. The response from MyBatis is stored in +the header with the key `CamelMyBatisResult`, or in the header that the +`outputHeader` option names, which leaves the body unchanged for a `SELECT` as well. == Examples diff --git a/components/camel-clickhouse/src/generated/resources/META-INF/org/apache/camel/component/clickhouse/clickhouse.json b/components/camel-clickhouse/src/generated/resources/META-INF/org/apache/camel/component/clickhouse/clickhouse.json index 6e4f34d47ff7..db94b15eabb7 100644 --- a/components/camel-clickhouse/src/generated/resources/META-INF/org/apache/camel/component/clickhouse/clickhouse.json +++ b/components/camel-clickhouse/src/generated/resources/META-INF/org/apache/camel/component/clickhouse/clickhouse.json @@ -42,6 +42,10 @@ "CamelClickHouseReadRows": { "index": 5, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of rows read by a query operation.", "constantName": "org.apache.camel.component.clickhouse.ClickHouseConstants#READ_ROWS" }, "CamelClickHousePingOk": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The boolean result of a ping operation.", "constantName": "org.apache.camel.component.clickhouse.ClickHouseConstants#PING_OK" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file", "list" ], "byOption": [ { "option": "operation", "value": "QUERY", "carriers": [ "text", "bytes", "stream", "file" ] }, { "option": "operation", "value": "PING", "carriers": [ "any" ] } ], "description": "The rows to insert, in the format option (JSONEachRow: one JSON object per line), as text, bytes, a stream or a file; or a List of objects whose class is registered on the Client. A Map or a List of Maps fails: marshal [...] + "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": "operation", "value": "QUERY", "carriers": [ "text" ], "javaType": "java.lang.String" }, { "option": "operation", "value": "PING", "carriers": [ "value" ], "javaType": "java.lang.Boolean" } ], "description": "Insert leaves the body unchanged, with the count in the CamelClickHouseWrittenRows header. Query gives the result as a String in the format option (JSONEachRow: one JSON object per line); binary formats such [...] + }, "properties": { "database": { "index": 0, "kind": "path", "displayName": "Database", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The ClickHouse database. A table may also be provided using the database.table syntax." }, "asyncInsert": { "index": 1, "kind": "parameter", "displayName": "Async Insert", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to use ClickHouse server-side asynchronous inserts (async_insert=1)." }, diff --git a/components/camel-clickhouse/src/main/java/org/apache/camel/component/clickhouse/ClickHouseEndpoint.java b/components/camel-clickhouse/src/main/java/org/apache/camel/component/clickhouse/ClickHouseEndpoint.java index e9dcbac2b810..f788c6bfa659 100644 --- a/components/camel-clickhouse/src/main/java/org/apache/camel/component/clickhouse/ClickHouseEndpoint.java +++ b/components/camel-clickhouse/src/main/java/org/apache/camel/component/clickhouse/ClickHouseEndpoint.java @@ -21,6 +21,9 @@ import org.apache.camel.Category; 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; @@ -35,6 +38,28 @@ import org.apache.camel.util.ObjectHelper; @UriEndpoint(firstVersion = "4.22.0", scheme = "clickhouse", title = "ClickHouse", syntax = "clickhouse:database", category = { Category.DATABASE, Category.BIGDATA }, producerOnly = true, headersClass = ClickHouseConstants.class) +@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE, Carrier.LIST }, + byOption = { + @BodyType.When(option = "operation", value = "QUERY", + carriers = { + Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, + Carrier.FILE }), + @BodyType.When(option = "operation", value = "PING", carriers = Carrier.ANY) }, + description = "The rows to insert, in the format option (JSONEachRow: one JSON object per" + + " line), as text, bytes, a stream or a file; or a List of objects whose" + + " class is registered on the Client. A Map or a List of Maps fails: marshal" + + " it first. Query takes the SQL statement"), + producerOut = @BodyType(value = Carrier.UNCHANGED, + byOption = { + @BodyType.When(option = "operation", value = "QUERY", carriers = Carrier.TEXT, + javaType = "java.lang.String"), + @BodyType.When(option = "operation", value = "PING", carriers = Carrier.VALUE, + javaType = "java.lang.Boolean") }, + description = "Insert leaves the body unchanged, with the count in the" + + " CamelClickHouseWrittenRows header. Query gives the result as a String" + + " in the format option (JSONEachRow: one JSON object per line); binary" + + " formats such as RowBinary do not survive the String. Ping gives a" + + " Boolean. The CamelClickHouseOperation header overrides the operation")) public class ClickHouseEndpoint extends DefaultEndpoint { private Client client; diff --git a/components/camel-drill/src/generated/resources/META-INF/org/apache/camel/component/drill/drill.json b/components/camel-drill/src/generated/resources/META-INF/org/apache/camel/component/drill/drill.json index e3543bc15f93..c01654c60035 100644 --- a/components/camel-drill/src/generated/resources/META-INF/org/apache/camel/component/drill/drill.json +++ b/components/camel-drill/src/generated/resources/META-INF/org/apache/camel/component/drill/drill.json @@ -30,6 +30,10 @@ "headers": { "CamelDrillQuery": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The drill query", "constantName": "org.apache.camel.component.drill.DrillConstants#DRILL_QUERY" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "any" ], "description": "The body is not read: the query comes from the CamelDrillQuery header, and a query in the body without that header fails" }, + "producerOut": { "carriers": [ "list" ], "javaType": "java.util.List<java.util.Map<String, Object>>", "description": "The rows of the query: a List of Maps of the column names (case insensitive) and their values, an empty List for no rows. A statement such as CREATE TABLE AS, DROP or ALTER SESSION gives the one row Drill answers with, such as ok and summary" } + }, "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, "description": "Host name or IP address" }, "clusterId": { "index": 1, "kind": "parameter", "displayName": "Cluster Id", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Cluster ID https:\/\/drill.apache.org\/docs\/using-the-jdbc-driver\/#determining-the-cluster-id" }, diff --git a/components/camel-drill/src/main/java/org/apache/camel/component/drill/DrillEndpoint.java b/components/camel-drill/src/main/java/org/apache/camel/component/drill/DrillEndpoint.java index 1c71dd656e31..a3d785986800 100644 --- a/components/camel-drill/src/main/java/org/apache/camel/component/drill/DrillEndpoint.java +++ b/components/camel-drill/src/main/java/org/apache/camel/component/drill/DrillEndpoint.java @@ -26,6 +26,9 @@ import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; import org.apache.camel.component.drill.util.StringUtils; +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,15 @@ import org.springframework.jdbc.core.RowMapperResultSetExtractor; */ @UriEndpoint(firstVersion = "2.19.0", scheme = "drill", title = "Drill", syntax = "drill:host", producerOnly = true, category = { Category.DATABASE, Category.BIGDATA }, headersClass = DrillConstants.class) +@BodyTypes(producerIn = @BodyType(value = Carrier.ANY, + description = "The body is not read: the query comes from the CamelDrillQuery header," + + " and a query in the body without that header fails"), + producerOut = @BodyType(value = Carrier.LIST, + javaType = "java.util.List<java.util.Map<String, Object>>", + description = "The rows of the query: a List of Maps of the column names (case" + + " insensitive) and their values, an empty List for no rows. A statement" + + " such as CREATE TABLE AS, DROP or ALTER SESSION gives the one row Drill" + + " answers with, such as ok and summary")) public class DrillEndpoint extends DefaultPollingEndpoint implements EndpointServiceLocation { @UriPath(description = "Host name or IP address") diff --git a/components/camel-duckdb/src/generated/resources/META-INF/org/apache/camel/component/duckdb/duckdb.json b/components/camel-duckdb/src/generated/resources/META-INF/org/apache/camel/component/duckdb/duckdb.json index ae7b10fe972c..b018b667caae 100644 --- a/components/camel-duckdb/src/generated/resources/META-INF/org/apache/camel/component/duckdb/duckdb.json +++ b/components/camel-duckdb/src/generated/resources/META-INF/org/apache/camel/component/duckdb/duckdb.json @@ -39,6 +39,10 @@ "CamelDuckDbRowsRead": { "index": 5, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The number of rows returned by a query.", "constantName": "org.apache.camel.component.duckdb.DuckDbConstants#ROWS_READ" }, "CamelDuckDbPingOk": { "index": 6, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The boolean result of a ping operation.", "constantName": "org.apache.camel.component.duckdb.DuckDbConstants#PING_OK" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "dependsOn": [ "query" ], "byOption": [ { "option": "operation", "value": "INSERT", "carriers": [ "list" ] }, { "option": "operation", "value": "COPY", "carriers": [ "file", "text" ] }, { "option": "operation", "value": "PING", "carriers": [ "any" ] } ], "description": "The SQL statement as text, or bytes, a stream or a file of it; the query option or the CamelDuckDbQuery header takes its place. Insert takes a List of [...] + "producerOut": { "carriers": [ "value" ], "javaType": "java.lang.Long", "byOption": [ { "option": "operation", "value": "QUERY", "carriers": [ "list" ], "javaType": "java.util.List<java.util.Map<String, Object>>" }, { "option": "operation", "value": "PING", "carriers": [ "value" ], "javaType": "java.lang.Boolean" }, { "option": "resultFormat", "value": "JSON", "carriers": [ "text", "value" ] } ], "description": "The count of rows written or affected as a Long, also in the CamelDuckDb [...] + }, "properties": { "databasePath": { "index": 0, "kind": "path", "displayName": "Database Path", "group": "producer", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Database path, either :memory: or a relative or absolute file path." }, "batchSize": { "index": 1, "kind": "parameter", "displayName": "Batch Size", "group": "producer", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "description": "Batch size for insert when the body is a List. 0 inserts all rows in one JDBC batch." }, diff --git a/components/camel-duckdb/src/main/java/org/apache/camel/component/duckdb/DuckDbEndpoint.java b/components/camel-duckdb/src/main/java/org/apache/camel/component/duckdb/DuckDbEndpoint.java index 80895ed53157..b41e0173c322 100644 --- a/components/camel-duckdb/src/main/java/org/apache/camel/component/duckdb/DuckDbEndpoint.java +++ b/components/camel-duckdb/src/main/java/org/apache/camel/component/duckdb/DuckDbEndpoint.java @@ -26,6 +26,9 @@ import org.apache.camel.Category; 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.spi.UriPath; @@ -39,6 +42,30 @@ import org.apache.camel.util.ObjectHelper; @UriEndpoint(firstVersion = "4.22.0", scheme = "duckdb", title = "DuckDB", syntax = "duckdb:databasePath", category = { Category.DATABASE, Category.BIGDATA }, producerOnly = true, headersClass = DuckDbConstants.class) +@BodyTypes(producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + dependsOn = "query", + byOption = { + @BodyType.When(option = "operation", value = "INSERT", carriers = Carrier.LIST), + @BodyType.When(option = "operation", value = "COPY", + carriers = { Carrier.FILE, Carrier.TEXT }), + @BodyType.When(option = "operation", value = "PING", carriers = Carrier.ANY) }, + description = "The SQL statement as text, or bytes, a stream or a file of it; the query" + + " option or the CamelDuckDbQuery header takes its place. Insert takes a List" + + " of Maps of the column names and their values (a Map alone fails), copy a" + + " File or the path of the csv, parquet or json file to load"), + producerOut = @BodyType(value = Carrier.VALUE, javaType = "java.lang.Long", + byOption = { + @BodyType.When(option = "operation", value = "QUERY", carriers = Carrier.LIST, + javaType = "java.util.List<java.util.Map<String, Object>>"), + @BodyType.When(option = "operation", value = "PING", carriers = Carrier.VALUE, + javaType = "java.lang.Boolean"), + @BodyType.When(option = "resultFormat", value = "JSON", + carriers = { Carrier.TEXT, Carrier.VALUE }) }, + description = "The count of rows written or affected as a Long, also in the" + + " CamelDuckDbRowsWritten header. Query gives the rows as a List of Maps" + + " of the column names and their values (a JSON array String with" + + " resultFormat=JSON), ping a Boolean. The CamelDuckDbOperation header" + + " overrides the operation")) public class DuckDbEndpoint extends DefaultEndpoint { private final ReentrantLock connectionLock = new ReentrantLock(); diff --git a/components/camel-jooq/src/generated/resources/META-INF/org/apache/camel/component/jooq/jooq.json b/components/camel-jooq/src/generated/resources/META-INF/org/apache/camel/component/jooq/jooq.json index b7084e5f2d02..bce0ae172257 100644 --- a/components/camel-jooq/src/generated/resources/META-INF/org/apache/camel/component/jooq/jooq.json +++ b/components/camel-jooq/src/generated/resources/META-INF/org/apache/camel/component/jooq/jooq.json @@ -35,6 +35,11 @@ "healthCheckConsumerEnabled": { "index": 8, "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": 9, "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": [ "pojo" ], "description": "One row of the table of the entityType per message, as the jOOQ UpdatableRecord of that class" }, + "producerIn": { "carriers": [ "pojo" ], "dependsOn": [ "query" ], "description": "A jOOQ object, by the operation: a record of the entityType to store for NONE, an org.jooq.Query for EXECUTE, an org.jooq.ResultQuery (a select) for FETCH. Text, a Map or a List fails: there is no conversion to them. With the query option the SQL is that query and the body is not read" }, + "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": "operation", "value": "FETCH", "carriers": [ "list" ], "javaType": "org.jooq.Result" } ], "description": "NONE stores the record and EXECUTE runs the query, both leave the body unchanged. FETCH gives the org.jooq.Result of the query, a List of its records, which is empty for no row" } + }, "properties": { "entityType": { "index": 0, "kind": "path", "displayName": "Entity Type", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jooq.JooqConfiguration", "configurationField": "configuration", "description": "JOOQ entity class" }, "databaseConfiguration": { "index": 1, "kind": "parameter", "displayName": "Database Configuration", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "org.jooq.Configuration", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.jooq.JooqConfiguration", "configurationField": "configuration", "description": "To use a specific database configuration" }, diff --git a/components/camel-jooq/src/main/docs/jooq-component.adoc b/components/camel-jooq/src/main/docs/jooq-component.adoc index a6d33c8bad3d..cf61ef759ff8 100644 --- a/components/camel-jooq/src/main/docs/jooq-component.adoc +++ b/components/camel-jooq/src/main/docs/jooq-component.adoc @@ -104,9 +104,9 @@ When using jooq as a producer you can use any of the following `JooqOperation` o [width="100%",cols="1,2",options="header"] |=== | Operation | Description -| none | Execute a query (default) -| execute | Execute a query with no expected results -| fetch | Execute a query and the result of the query is stored as the new message body +| none | Store the entity (the record of the entity type) in the message body (default) +| execute | Execute a query (an `org.jooq.Query` in the message body, or the `query` option) with no expected results +| fetch | Execute a query (an `org.jooq.ResultQuery` in the message body, or the `query` option) and the `org.jooq.Result` of the query is stored as the new message body |=== == Example diff --git a/components/camel-jooq/src/main/java/org/apache/camel/component/jooq/JooqEndpoint.java b/components/camel-jooq/src/main/java/org/apache/camel/component/jooq/JooqEndpoint.java index 9e25470fcfb2..a8b50cb6c5a1 100644 --- a/components/camel-jooq/src/main/java/org/apache/camel/component/jooq/JooqEndpoint.java +++ b/components/camel-jooq/src/main/java/org/apache/camel/component/jooq/JooqEndpoint.java @@ -24,6 +24,9 @@ import org.apache.camel.NoTypeConversionAvailableException; import org.apache.camel.Processor; import org.apache.camel.Producer; import org.apache.camel.RuntimeCamelException; +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.ScheduledPollEndpoint; @@ -35,6 +38,20 @@ import org.jooq.ResultQuery; */ @UriEndpoint(firstVersion = "3.0.0", scheme = "jooq", syntax = "jooq:entityType", title = "JOOQ", category = { Category.DATABASE }) +@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO, + description = "One row of the table of the entityType per message, as the jOOQ" + + " UpdatableRecord of that class"), + producerIn = @BodyType(value = Carrier.POJO, dependsOn = "query", + description = "A jOOQ object, by the operation: a record of the entityType to store for" + + " NONE, an org.jooq.Query for EXECUTE, an org.jooq.ResultQuery (a select)" + + " for FETCH. Text, a Map or a List fails: there is no conversion to them." + + " With the query option the SQL is that query and the body is not read"), + producerOut = @BodyType(value = Carrier.UNCHANGED, + byOption = @BodyType.When(option = "operation", value = "FETCH", carriers = Carrier.LIST, + javaType = "org.jooq.Result"), + description = "NONE stores the record and EXECUTE runs the query, both leave the body" + + " unchanged. FETCH gives the org.jooq.Result of the query, a List of its" + + " records, which is empty for no row")) public class JooqEndpoint extends ScheduledPollEndpoint { private Expression producerExpression; diff --git a/components/camel-jpa/src/generated/resources/META-INF/org/apache/camel/component/jpa/jpa.json b/components/camel-jpa/src/generated/resources/META-INF/org/apache/camel/component/jpa/jpa.json index 544a910e1097..54e42766013c 100644 --- a/components/camel-jpa/src/generated/resources/META-INF/org/apache/camel/component/jpa/jpa.json +++ b/components/camel-jpa/src/generated/resources/META-INF/org/apache/camel/component/jpa/jpa.json @@ -41,6 +41,11 @@ "CamelJpaMaximumResults": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Defines the maximum number of results to retrieve on the query; takes precedence over the value set on the endpoint, if any.", "constantName": "org.apache.camel.component.jpa.JpaConstants#JPA_MAXIMUM_RESULTS" }, "CamelJpaFirstResult": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Defines the position of the first result to retrieve; takes precedence over the value set on the endpoint, if any.", "constantName": "org.apache.camel.component.jpa.JpaConstants#JPA_FIRST_RESULT" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "pojo" ], "dependsOn": [ "query", "namedQuery", "nativeQuery" ], "description": "One entity of the entityType class per message. A query that selects columns gives one row per message: an Object array, or the value of a single column; a nativeQuery gives an Object array unless resultClass is set" }, + "producerIn": { "carriers": [ "pojo", "list" ], "dependsOn": [ "query", "namedQuery", "nativeQuery" ], "byOption": [ { "option": "findEntity", "value": "true", "carriers": [ "value", "text" ] } ], "description": "The entity to persist, merge or remove, converted to the entityType class; a List or an array of entities needs entityType java.util.List (or java.lang.Object). Text, bytes or a Map fail. With findEntity, the primary key. With a query the body is not read: the parameters com [...] + "producerOut": { "carriers": [ "pojo", "list" ], "dependsOn": [ "query", "namedQuery", "nativeQuery", "outputTarget" ], "byOption": [ { "option": "usePersist", "value": "true", "carriers": [ "unchanged" ] }, { "option": "findEntity", "value": "true", "carriers": [ "pojo", "null" ] } ], "description": "The managed entity that merge returns, or a List or array of them; usePersist leaves the body as sent. findEntity gives the entity, or null when there is none. A query gives the List of [...] + }, "properties": { "entityType": { "index": 0, "kind": "path", "displayName": "Entity Type", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.Class<java.lang.Object>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Entity class name" }, "entityManagerFactory": { "index": 1, "kind": "parameter", "displayName": "Entity Manager Factory", "group": "common", "label": "", "required": false, "type": "object", "javaType": "jakarta.persistence.EntityManagerFactory", "deprecated": false, "autowired": false, "secret": false, "description": "The EntityManagerFactory to use." }, diff --git a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaEndpoint.java b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaEndpoint.java index 3d0eba7a8e2a..bbb5e347c372 100644 --- a/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaEndpoint.java +++ b/components/camel-jpa/src/main/java/org/apache/camel/component/jpa/JpaEndpoint.java @@ -31,6 +31,9 @@ import org.apache.camel.InvalidPayloadRuntimeException; import org.apache.camel.PollingConsumer; 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; @@ -48,6 +51,33 @@ import org.springframework.orm.jpa.SharedEntityManagerCreator; */ @UriEndpoint(firstVersion = "1.0.0", scheme = "jpa", title = "JPA", syntax = "jpa:entityType", category = { Category.DATABASE }, headersClass = JpaConstants.class) +@BodyTypes(consumerOut = @BodyType(value = Carrier.POJO, dependsOn = { "query", "namedQuery", "nativeQuery" }, + description = "One entity of the entityType class per message. A query that selects" + + " columns gives one row per message: an Object array, or the value of a" + + " single column; a nativeQuery gives an Object array unless resultClass" + + " is set"), + producerIn = @BodyType(value = { Carrier.POJO, Carrier.LIST }, + dependsOn = { "query", "namedQuery", "nativeQuery" }, + byOption = @BodyType.When(option = "findEntity", value = "true", + carriers = { Carrier.VALUE, Carrier.TEXT }), + description = "The entity to persist, merge or remove, converted to the entityType class;" + + " a List or an array of entities needs entityType java.util.List (or" + + " java.lang.Object). Text, bytes or a Map fail. With findEntity, the primary" + + " key. With a query the body is not read: the parameters come from the" + + " parameters option or the CamelJpaParameters header"), + producerOut = @BodyType(value = { Carrier.POJO, Carrier.LIST }, + dependsOn = { "query", "namedQuery", "nativeQuery", "outputTarget" }, + byOption = { + @BodyType.When(option = "usePersist", value = "true", + carriers = Carrier.UNCHANGED), + @BodyType.When(option = "findEntity", value = "true", + carriers = { Carrier.POJO, Carrier.NULL }) }, + description = "The managed entity that merge returns, or a List or array of them;" + + " usePersist leaves the body as sent. findEntity gives the entity, or" + + " null when there is none. A query gives the List of its results" + + " (entities, Object arrays or values), the one result with singleResult," + + " or the count of an update or delete as an Integer; with outputTarget the" + + " result goes to that header (or property:name) and the body is unchanged")) public class JpaEndpoint extends ScheduledPollEndpoint { @UriParam diff --git a/components/camel-kudu/src/generated/resources/META-INF/org/apache/camel/component/kudu/kudu.json b/components/camel-kudu/src/generated/resources/META-INF/org/apache/camel/component/kudu/kudu.json index f1e66c4048a5..fafb30d43184 100644 --- a/components/camel-kudu/src/generated/resources/META-INF/org/apache/camel/component/kudu/kudu.json +++ b/components/camel-kudu/src/generated/resources/META-INF/org/apache/camel/component/kudu/kudu.json @@ -35,6 +35,10 @@ "CamelKuduScanPredicate": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "org.apache.kudu.client.KuduPredicate", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The predicate for scan operation", "constantName": "org.apache.camel.component.kudu.KuduConstants#CAMEL_KUDU_SCAN_PREDICATE" }, "CamelKuduScanLimit": { "index": 4, "kind": "header", "displayName": "", "group": "producer", "label": "", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The limit on the number of rows for scan operation", "constantName": "org.apache.camel.component.kudu.KuduConstants#CAMEL_KUDU_SCAN_LIMIT" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "map" ], "byOption": [ { "option": "operation", "value": "SCAN", "carriers": [ "any" ] }, { "option": "operation", "value": "CREATE_TABLE", "carriers": [ "any" ] } ], "description": "For insert, update, upsert and delete: a Map of the column names and their values, one row, each value of the Java type of its column (a String for an INT32 column fails); delete uses only the key columns. Text such as JSON, a List or a POJO fails: unmarshal it into a Map fi [...] + "producerOut": { "carriers": [ "unchanged" ], "byOption": [ { "option": "operation", "value": "SCAN", "carriers": [ "list" ], "javaType": "java.util.List<java.util.Map<String, Object>>" } ], "description": "Scan gives a List of the rows, each a Map of the column names and their values, an empty List for no rows. The other operations leave the body unchanged" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Host of the server to connect to" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Port of the server to connect to" }, diff --git a/components/camel-kudu/src/main/java/org/apache/camel/component/kudu/KuduEndpoint.java b/components/camel-kudu/src/main/java/org/apache/camel/component/kudu/KuduEndpoint.java index 0e03d38719a1..ae73220f3bd2 100644 --- a/components/camel-kudu/src/main/java/org/apache/camel/component/kudu/KuduEndpoint.java +++ b/components/camel-kudu/src/main/java/org/apache/camel/component/kudu/KuduEndpoint.java @@ -23,6 +23,9 @@ import org.apache.camel.Category; 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.EndpointServiceLocation; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; @@ -42,6 +45,24 @@ import org.slf4j.LoggerFactory; title = "Kudu", syntax = "kudu:host:port/tableName", category = { Category.DATABASE, Category.IOT, Category.CLOUD }, producerOnly = true, headersClass = KuduConstants.class) +@BodyTypes(producerIn = @BodyType(value = Carrier.MAP, + byOption = { + @BodyType.When(option = "operation", value = "SCAN", carriers = Carrier.ANY), + @BodyType.When(option = "operation", value = "CREATE_TABLE", + carriers = Carrier.ANY) }, + description = "For insert, update, upsert and delete: a Map of the column names and" + + " their values, one row, each value of the Java type of its column (a" + + " String for an INT32 column fails); delete uses only the key columns." + + " Text such as JSON, a List or a POJO fails: unmarshal it into a Map" + + " first. Scan and create_table do not read the body: they take the" + + " CamelKuduScan* and the CamelKuduSchema and CamelKuduTableOptions" + + " headers. The operation must be set"), + producerOut = @BodyType(value = Carrier.UNCHANGED, + byOption = @BodyType.When(option = "operation", value = "SCAN", carriers = Carrier.LIST, + javaType = "java.util.List<java.util.Map<String, Object>>"), + description = "Scan gives a List of the rows, each a Map of the column names and their" + + " values, an empty List for no rows. The other operations leave the body" + + " unchanged")) public class KuduEndpoint extends DefaultEndpoint implements EndpointServiceLocation { private static final Logger LOG = LoggerFactory.getLogger(KuduEndpoint.class); diff --git a/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis-bean.json b/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis-bean.json index 9d9f7265a9fb..4efcf074c49f 100644 --- a/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis-bean.json +++ b/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis-bean.json @@ -34,6 +34,10 @@ "headers": { "CamelMyBatisResult": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Object", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response returned from MyBatis in any of the operations. Such as INSERT could return the auto-generated key, or number of rows etc.", "constantName": "org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_RESULT" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "any" ], "description": "The argument of the method of the mapper, converted to its parameter type by the bean binding, so the text 123 fits an int parameter. With inputHeader the argument is that header and the body is not read" }, + "producerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" ], "description": "What the method of the mapper returns, as it declares it: a bean, a List of rows, a Map, a value such as the count of an update, or null for no row; also in the CamelMyBatisResult header. A void method leaves the body unchanged. With outputHeader the result goes in that header and the body is unchanged" } + }, "properties": { "beanName": { "index": 0, "kind": "path", "displayName": "Bean Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Name of the bean with the MyBatis annotations. This can either by a type alias or a FQN class name." }, "methodName": { "index": 1, "kind": "path", "displayName": "Method Name", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Name of the method on the bean that has the SQL query to be executed." }, diff --git a/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis.json b/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis.json index e71af6ae3dfe..b204cc83149e 100644 --- a/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis.json +++ b/components/camel-mybatis/src/generated/resources/META-INF/org/apache/camel/component/mybatis/mybatis.json @@ -36,6 +36,11 @@ "CamelMyBatisResult": { "index": 0, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Object", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The response returned from MyBatis in any of the operations. Such as INSERT could return the auto-generated key, or number of rows etc.", "constantName": "org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_RESULT" }, "CamelMyBatisStatementName": { "index": 1, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The statementName used (for example: insertAccount).", "constantName": "org.apache.camel.component.mybatis.MyBatisConstants#MYBATIS_STATEMENT_NAME" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" ], "byOption": [ { "option": "useIterator", "value": "false", "carriers": [ "list" ] } ], "description": "One row of the select per message, as the resultType or resultMap of the statement maps it: a bean, a Map or a single value, and null for a row of only nulls. With useIterator=false a List of all the rows in one message; with outputHeader the row goes in that header and the body is null" }, + "producerIn": { "carriers": [ "any" ], "description": "The parameter of the statement, given to MyBatis as it is, without type conversion: it must fit the parameterType, so the text 123 fails an int parameter. A bean or a Map for several parameters; no body runs the statement without one. Insert, Update and Delete run once per element of a List, an array or an Iterator, the List variants once with the whole List. With inputHeader the parameter is that header and the body is not read" }, + "producerOut": { "carriers": [ "unknown" ], "dependsOn": [ "outputHeader" ], "byOption": [ { "option": "statementType", "value": "SelectOne", "carriers": [ "unknown" ] }, { "option": "statementType", "value": "SelectList", "carriers": [ "list" ] }, { "option": "statementType", "value": "Insert", "carriers": [ "unchanged" ] }, { "option": "statementType", "value": "InsertList", "carriers": [ "unchanged" ] }, { "option": "statementType", "value": "Update", "carriers": [ "unchanged" ] } [...] + }, "properties": { "statement": { "index": 0, "kind": "path", "displayName": "Statement", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The statement name in the MyBatis XML mapping file which maps to the query, insert, update or delete operation you wish to evaluate." }, "maxMessagesPerPoll": { "index": 1, "kind": "parameter", "displayName": "Max Messages Per Poll", "group": "consumer", "label": "consumer", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 0, "description": "This option is intended to split results returned by the database pool into the batches and deliver them in multiple exchanges. This integer defines the maximum messages to deliver in single exchange [...] diff --git a/components/camel-mybatis/src/main/docs/mybatis-bean-component.adoc b/components/camel-mybatis/src/main/docs/mybatis-bean-component.adoc index 80eeacaad41f..c11b5f69ffd4 100644 --- a/components/camel-mybatis/src/main/docs/mybatis-bean-component.adoc +++ b/components/camel-mybatis/src/main/docs/mybatis-bean-component.adoc @@ -49,11 +49,13 @@ include::partial$component-endpoint-headers.adoc[] === Message Body -The response from MyBatis will only be set as the body if it's a -`SELECT` statement. That means, for example, for `INSERT` statements -Camel will not replace the body. This allows you to continue routing and -keep the original body. The response from MyBatis is always stored in -the header with the key `CamelMyBatisResult`. +The value the mapper method returns is set as the body, and is also stored in +the header with the key `CamelMyBatisResult`. That is the bean, the `List` or +the `Map` of a select (or null when there is no row), and the count of rows of an +`INSERT`, `UPDATE` or `DELETE` method that returns an `int`. A `void` method +leaves the body as it was, which allows you to continue routing with the +original body. With the `outputHeader` option the result is stored in that +header instead, and the body is not changed. == Examples diff --git a/components/camel-mybatis/src/main/docs/mybatis-component.adoc b/components/camel-mybatis/src/main/docs/mybatis-component.adoc index 34c9939ba20b..d84d40a70f92 100644 --- a/components/camel-mybatis/src/main/docs/mybatis-component.adoc +++ b/components/camel-mybatis/src/main/docs/mybatis-component.adoc @@ -60,8 +60,9 @@ include::partial$component-endpoint-headers.adoc[] The response from MyBatis will only be set as the body if it's a `SELECT` statement. That means, for example, for `INSERT` statements Camel will not replace the body. This allows you to continue routing and -keep the original body. The response from MyBatis is always stored in -the header with the key `CamelMyBatisResult`. +keep the original body. The response from MyBatis is stored in +the header with the key `CamelMyBatisResult`, or in the header that the +`outputHeader` option names, which leaves the body unchanged for a `SELECT` as well. == Examples diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java index 9155e9d0f155..474b0760ea33 100644 --- a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.java +++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisBeanEndpoint.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.UriPath; @@ -33,6 +36,16 @@ import static org.apache.camel.component.mybatis.MyBatisConstants.SCHEME_MYBATIS @UriEndpoint(firstVersion = "2.22.0", scheme = SCHEME_MYBATIS_BEAN, title = "MyBatis Bean", syntax = "mybatis-bean:beanName:methodName", producerOnly = true, category = { Category.DATABASE }, headersClass = MyBatisConstants.class) +@BodyTypes(producerIn = @BodyType(value = Carrier.ANY, + description = "The argument of the method of the mapper, converted to its parameter type" + + " by the bean binding, so the text 123 fits an int parameter. With" + + " inputHeader the argument is that header and the body is not read"), + producerOut = @BodyType(value = Carrier.UNKNOWN, dependsOn = "outputHeader", + description = "What the method of the mapper returns, as it declares it: a bean, a List of" + + " rows, a Map, a value such as the count of an update, or null for no row;" + + " also in the CamelMyBatisResult header. A void method leaves the body" + + " unchanged. With outputHeader the result goes in that header and the body" + + " is unchanged")) public class MyBatisBeanEndpoint extends BaseMyBatisEndpoint { @UriPath diff --git a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java index 1f56faf017ec..eeef936bc9a3 100644 --- a/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.java +++ b/components/camel-mybatis/src/main/java/org/apache/camel/component/mybatis/MyBatisEndpoint.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,44 @@ import static org.apache.camel.component.mybatis.MyBatisConstants.SCHEME_MYBATIS */ @UriEndpoint(firstVersion = "2.7.0", scheme = SCHEME_MYBATIS, title = "MyBatis", syntax = "mybatis:statement", category = { Category.DATABASE }, headersClass = MyBatisConstants.class) +@BodyTypes(consumerOut = @BodyType(value = Carrier.UNKNOWN, dependsOn = "outputHeader", + byOption = @BodyType.When(option = "useIterator", value = "false", carriers = Carrier.LIST), + description = "One row of the select per message, as the resultType or resultMap of the" + + " statement maps it: a bean, a Map or a single value, and null for a row of" + + " only nulls. With useIterator=false a List of all the rows in one message;" + + " with outputHeader the row goes in that header and the body is null"), + producerIn = @BodyType(value = Carrier.ANY, + description = "The parameter of the statement, given to MyBatis as it is, without type" + + " conversion: it must fit the parameterType, so the text 123 fails an int" + + " parameter. A bean or a Map for several parameters; no body runs the" + + " statement without one. Insert, Update and Delete run once per element of" + + " a List, an array or an Iterator, the List variants once with the whole" + + " List. With inputHeader the parameter is that header and the body is not" + + " read"), + producerOut = @BodyType(value = Carrier.UNKNOWN, dependsOn = "outputHeader", + byOption = { + @BodyType.When(option = "statementType", value = "SelectOne", + carriers = Carrier.UNKNOWN), + @BodyType.When(option = "statementType", value = "SelectList", + carriers = Carrier.LIST), + @BodyType.When(option = "statementType", value = "Insert", + carriers = Carrier.UNCHANGED), + @BodyType.When(option = "statementType", value = "InsertList", + carriers = Carrier.UNCHANGED), + @BodyType.When(option = "statementType", value = "Update", + carriers = Carrier.UNCHANGED), + @BodyType.When(option = "statementType", value = "UpdateList", + carriers = Carrier.UNCHANGED), + @BodyType.When(option = "statementType", value = "Delete", + carriers = Carrier.UNCHANGED), + @BodyType.When(option = "statementType", value = "DeleteList", + carriers = Carrier.UNCHANGED) }, + description = "By the statementType, which the producer needs: SelectOne gives the one" + + " row as the statement maps it (a bean, a Map or a value), or null for no" + + " row; SelectList a List of the rows. Insert, Update and Delete leave the" + + " body unchanged, with the count of rows in the CamelMyBatisResult header." + + " With outputHeader the result goes in that header and the body is" + + " unchanged")) public class MyBatisEndpoint extends BaseMyBatisEndpoint { @UriPath diff --git a/components/camel-pg-replication-slot/src/generated/resources/META-INF/org/apache/camel/component/pg/replication/slot/pg-replication-slot.json b/components/camel-pg-replication-slot/src/generated/resources/META-INF/org/apache/camel/component/pg/replication/slot/pg-replication-slot.json index 334949141e7c..db98358463cb 100644 --- a/components/camel-pg-replication-slot/src/generated/resources/META-INF/org/apache/camel/component/pg/replication/slot/pg-replication-slot.json +++ b/components/camel-pg-replication-slot/src/generated/resources/META-INF/org/apache/camel/component/pg/replication/slot/pg-replication-slot.json @@ -29,6 +29,9 @@ "healthCheckConsumerEnabled": { "index": 2, "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": 3, "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": [ "bytes" ], "javaType": "byte[]", "description": "One message of the output plugin of the slot, as bytes: text for test_decoding, JSON for wal2json, the binary protocol for pgoutput; convert it to a String for the text plugins. The exchange id is the LSN of the message" } + }, "properties": { "slot": { "index": 0, "kind": "path", "displayName": "Slot", "group": "common", "label": "common", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Replication Slot name" }, "host": { "index": 1, "kind": "path", "displayName": "Host", "group": "common", "label": "common", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "localhost", "description": "Postgres host" }, diff --git a/components/camel-pg-replication-slot/src/main/java/org/apache/camel/component/pg/replication/slot/PgReplicationSlotEndpoint.java b/components/camel-pg-replication-slot/src/main/java/org/apache/camel/component/pg/replication/slot/PgReplicationSlotEndpoint.java index f70b08c0225f..76de2f10d477 100644 --- a/components/camel-pg-replication-slot/src/main/java/org/apache/camel/component/pg/replication/slot/PgReplicationSlotEndpoint.java +++ b/components/camel-pg-replication-slot/src/main/java/org/apache/camel/component/pg/replication/slot/PgReplicationSlotEndpoint.java @@ -30,6 +30,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; @@ -45,6 +48,11 @@ import org.slf4j.LoggerFactory; @UriEndpoint(firstVersion = "3.0.0", scheme = "pg-replication-slot", title = "PostgreSQL Replication Slot", syntax = "pg-replication-slot:host:port/database/slot:outputPlugin", category = { Category.DATABASE }, consumerOnly = true) +@BodyTypes(consumerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]", + description = "One message of the output plugin of the slot, as bytes: text for" + + " test_decoding, JSON for wal2json, the binary protocol for pgoutput;" + + " convert it to a String for the text plugins. The exchange id is the LSN" + + " of the message")) public class PgReplicationSlotEndpoint extends ScheduledPollEndpoint { private static final Logger LOG = LoggerFactory.getLogger(PgReplicationSlotEndpoint.class); diff --git a/components/camel-pgevent/src/generated/resources/META-INF/org/apache/camel/component/pgevent/pgevent.json b/components/camel-pgevent/src/generated/resources/META-INF/org/apache/camel/component/pgevent/pgevent.json index bfd65985c32f..6da6f6368b47 100644 --- a/components/camel-pgevent/src/generated/resources/META-INF/org/apache/camel/component/pgevent/pgevent.json +++ b/components/camel-pgevent/src/generated/resources/META-INF/org/apache/camel/component/pgevent/pgevent.json @@ -31,6 +31,11 @@ "headers": { "channel": { "index": 0, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of the channel.", "constantName": "org.apache.camel.component.pgevent.PgEventConstants#HEADER_CHANNEL" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text" ], "javaType": "java.lang.String", "description": "The payload of the notification as a String, empty when it was sent without one; the channel is in the channel header" }, + "producerIn": { "carriers": [ "any" ], "description": "The payload of the notification, converted to a String: text, or bytes, a stream or a file of it; a Map or a POJO is sent as its toString(), so marshal it first. PostgreSQL takes a payload of less than 8000 bytes, and no body sends an empty payload" }, + "producerOut": { "carriers": [ "unchanged" ] } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "defaultValue": "localhost", "description": "To connect using hostname and port to the database." }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "java.lang.Integer", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 5432, "description": "To connect using hostname and port to the database." }, diff --git a/components/camel-pgevent/src/main/java/org/apache/camel/component/pgevent/PgEventEndpoint.java b/components/camel-pgevent/src/main/java/org/apache/camel/component/pgevent/PgEventEndpoint.java index 1fe9dc6b7e0b..f515fe883fd1 100644 --- a/components/camel-pgevent/src/main/java/org/apache/camel/component/pgevent/PgEventEndpoint.java +++ b/components/camel-pgevent/src/main/java/org/apache/camel/component/pgevent/PgEventEndpoint.java @@ -28,6 +28,9 @@ import org.apache.camel.Category; 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.ClassResolver; import org.apache.camel.spi.EndpointServiceLocation; import org.apache.camel.spi.Metadata; @@ -46,6 +49,15 @@ import org.slf4j.LoggerFactory; @UriEndpoint(firstVersion = "2.15.0", scheme = "pgevent", title = "PostgreSQL Event", syntax = "pgevent:host:port/database/channel", category = { Category.DATABASE }, headersClass = PgEventConstants.class) +@BodyTypes(consumerOut = @BodyType(value = Carrier.TEXT, javaType = "java.lang.String", + description = "The payload of the notification as a String, empty when it was sent" + + " without one; the channel is in the channel header"), + producerIn = @BodyType(value = Carrier.ANY, + description = "The payload of the notification, converted to a String: text, or bytes," + + " a stream or a file of it; a Map or a POJO is sent as its toString(), so" + + " marshal it first. PostgreSQL takes a payload of less than 8000 bytes," + + " and no body sends an empty payload"), + producerOut = @BodyType(value = Carrier.UNCHANGED)) public class PgEventEndpoint extends DefaultEndpoint implements EndpointServiceLocation { private static final Logger LOG = LoggerFactory.getLogger(PgEventEndpoint.class); diff --git a/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json b/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json index 6af8b9790c35..16606cd4dc34 100644 --- a/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json +++ b/components/camel-sql/src/generated/resources/META-INF/org/apache/camel/component/sql/stored/sql-stored.json @@ -35,6 +35,10 @@ "CamelSqlStoredParameters": { "index": 1, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Iterator", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The parameters", "constantName": "org.apache.camel.component.sql.stored.SqlStoredConstants#SQL_STORED_PARAMETERS" }, "CamelSqlStoredUpdateCount": { "index": 2, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "important": true, "description": "The update count", "constantName": "org.apache.camel.component.sql.stored.SqlStoredConstants#SQL_STORED_UPDATE_COUNT" } }, + "bodyTypes": { + "producerIn": { "carriers": [ "any" ], "byOption": [ { "option": "batch", "value": "true", "carriers": [ "list", "iterator" ] }, { "option": "useMessageBodyForTemplate", "value": "true", "carriers": [ "text" ] } ], "description": "What the expressions of the IN parameters read: a :#name parameter takes its value from a Map body, or else from the header. With batch, a List or an Iterator of such bodies, one batch item each (a single Map is not a batch); with useMessageBodyForTemplate, [...] + "producerOut": { "carriers": [ "map" ], "javaType": "java.util.Map<String, Object>", "dependsOn": [ "outputHeader" ], "byOption": [ { "option": "noop", "value": "true", "carriers": [ "unchanged" ] }, { "option": "batch", "value": "true", "carriers": [ "unchanged" ] } ], "description": "A Map of the names of the OUT and INOUT parameters and their values, with a result set the procedure returns under #result-set-1 (a List of Maps) and the update count under #update-count-1, which is al [...] + }, "properties": { "template": { "index": 0, "kind": "path", "displayName": "Template", "group": "producer", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "supportFileReference": true, "largeInput": true, "inputLanguage": "sql", "description": "Sets the stored procedure template to perform. You can externalize the template by using file: or classpath: as prefix and specify the location of [...] "batch": { "index": 1, "kind": "parameter", "displayName": "Batch", "group": "producer", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enables or disables batch mode" }, diff --git a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java index 2ded97421b56..d1628d12f490 100644 --- a/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java +++ b/components/camel-sql/src/main/java/org/apache/camel/component/sql/stored/SqlStoredEndpoint.java @@ -28,6 +28,9 @@ import org.apache.camel.Producer; import org.apache.camel.component.sql.SqlServiceLocationHelper; import org.apache.camel.component.sql.stored.template.TemplateParser; import org.apache.camel.spi.BeanIntrospection; +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; @@ -44,6 +47,28 @@ import org.springframework.jdbc.core.JdbcTemplate; */ @UriEndpoint(firstVersion = "2.17.0", scheme = "sql-stored", title = "SQL Stored Procedure", syntax = "sql-stored:template", producerOnly = true, category = { Category.DATABASE }, headersClass = SqlStoredConstants.class) +@BodyTypes(producerIn = @BodyType(value = Carrier.ANY, + byOption = { + @BodyType.When(option = "batch", value = "true", + carriers = { Carrier.LIST, Carrier.ITERATOR }), + @BodyType.When(option = "useMessageBodyForTemplate", value = "true", + carriers = Carrier.TEXT) }, + description = "What the expressions of the IN parameters read: a :#name parameter takes" + + " its value from a Map body, or else from the header. With batch, a List or" + + " an Iterator of such bodies, one batch item each (a single Map is not a" + + " batch); with useMessageBodyForTemplate, the template as text, with the" + + " parameters in the CamelSqlStoredParameters header"), + producerOut = @BodyType(value = Carrier.MAP, javaType = "java.util.Map<String, Object>", + dependsOn = "outputHeader", + byOption = { + @BodyType.When(option = "noop", value = "true", carriers = Carrier.UNCHANGED), + @BodyType.When(option = "batch", value = "true", carriers = Carrier.UNCHANGED) }, + description = "A Map of the names of the OUT and INOUT parameters and their values, with" + + " a result set the procedure returns under #result-set-1 (a List of Maps)" + + " and the update count under #update-count-1, which is also in the" + + " CamelSqlStoredUpdateCount header. With outputHeader the Map is in that" + + " header and the body is unchanged; batch leaves the body unchanged, with" + + " the total update count in the header")) public class SqlStoredEndpoint extends DefaultEndpoint implements EndpointServiceLocation { private CallableStatementWrapperFactory wrapperFactory;
