This is an automated email from the ASF dual-hosted git repository. davsclaus pushed a commit to branch feature/CAMEL-24961-catalog-body-types-messaging-2 in repository https://gitbox.apache.org/repos/asf/camel.git
commit 7c24ffec7eeb333f146b66b823dab205be2b050f Author: Claus Ibsen <[email protected]> AuthorDate: Thu Oct 22 17:51:13 2026 +0200 CAMEL-24961: Catalog body types for mail, paho, spring-rabbitmq, pulsar, nats and smpp Declares the body types of the second messaging group: the mail component (imap, imaps, pop3, pop3s, smtp and smtps), paho, spring-rabbitmq, pulsar, nats and smpp (smpp and smpps). All were checked at runtime with camel run: GreenMail for mail, camel infra for mosquitto, rabbitmq, pulsar and nats, and the jSMPP simulator for smpp. Fixes the doc prose about the body: the nats consumer replies only with exchangePattern=InOut and the producer gets the reply as bytes, the mail producer reads the body as text and sends a MimeMessage as it is, the split of mail attachments always gives their content as the body, and the smpp page and the CamelSmppEncoding header say how a body becomes the short message. Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]> Signed-off-by: Claus Ibsen <[email protected]> --- .../org/apache/camel/catalog/components/imap.json | 5 ++ .../org/apache/camel/catalog/components/imaps.json | 5 ++ .../org/apache/camel/catalog/components/nats.json | 6 ++ .../org/apache/camel/catalog/components/paho.json | 5 ++ .../org/apache/camel/catalog/components/pop3.json | 5 ++ .../org/apache/camel/catalog/components/pop3s.json | 5 ++ .../apache/camel/catalog/components/pulsar.json | 5 ++ .../org/apache/camel/catalog/components/smpp.json | 7 +- .../org/apache/camel/catalog/components/smpps.json | 7 +- .../org/apache/camel/catalog/components/smtp.json | 5 ++ .../org/apache/camel/catalog/components/smtps.json | 5 ++ .../camel/catalog/components/spring-rabbitmq.json | 6 ++ .../apache/camel/catalog/docs/mail-component.adoc | 17 ++--- .../apache/camel/catalog/docs/nats-component.adoc | 7 +- .../apache/camel/catalog/docs/smpp-component.adoc | 15 +++- .../org/apache/camel/component/mail/imap.json | 5 ++ .../org/apache/camel/component/mail/imaps.json | 5 ++ .../org/apache/camel/component/mail/pop3.json | 5 ++ .../org/apache/camel/component/mail/pop3s.json | 5 ++ .../org/apache/camel/component/mail/smtp.json | 5 ++ .../org/apache/camel/component/mail/smtps.json | 5 ++ .../camel-mail/src/main/docs/mail-component.adoc | 17 ++--- .../apache/camel/component/mail/MailEndpoint.java | 20 +++++ .../org/apache/camel/component/nats/nats.json | 6 ++ .../camel-nats/src/main/docs/nats-component.adoc | 7 +- .../apache/camel/component/nats/NatsEndpoint.java | 28 +++++++ .../org/apache/camel/component/paho/paho.json | 5 ++ .../apache/camel/component/paho/PahoEndpoint.java | 8 ++ .../org/apache/camel/component/pulsar/pulsar.json | 5 ++ .../camel/component/pulsar/PulsarEndpoint.java | 15 ++++ .../org/apache/camel/component/smpp/smpp.json | 7 +- .../org/apache/camel/component/smpp/smpps.json | 7 +- .../camel-smpp/src/main/docs/smpp-component.adoc | 15 +++- .../apache/camel/component/smpp/SmppConstants.java | 12 +-- .../apache/camel/component/smpp/SmppEndpoint.java | 22 ++++++ .../component/springrabbit/spring-rabbitmq.json | 6 ++ .../springrabbit/SpringRabbitMQEndpoint.java | 33 +++++++++ .../camel/dsl/yaml/validator/TextBodyFlowTest.java | 85 ++++++++++++++++++++++ 38 files changed, 387 insertions(+), 46 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imap.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imap.json index 8399bb76ec5a..47a584bfbb93 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imap.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imap.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imaps.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imaps.json index 183ccb7e3722..35c217ab9acd 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imaps.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/imaps.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/nats.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/nats.json index eca34ceb7d3c..50696e134278 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/nats.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/nats.json @@ -80,6 +80,12 @@ "CamelNatsDeliveryCounter": { "index": 7, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "important": true, "description": "Number of times this message has been delivered (1 = first, 1 then message has been redelivered)", "constantName": "org.apache.camel.component.nats.NatsConstants#NATS_DELIVERY_COUNTER" }, "CamelNatsManualAck": { "index": 8, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "org.apache.camel.component.nats.NatsManualAck", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The manual acknowledgment handle for JetStream messages (only set when manualAck=true).", "constantName": "org.apache.camel.component.nats.NatsConstants#NATS_MANUAL_ACK" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", "description": "The payload of the NATS message as a byte array, empty for a message without one: convert or unmarshal it" }, + "consumerReply": { "carriers": [ "any" ], "byOption": [ { "option": "exchangePattern", "value": "InOut", "carriers": [ "text", "bytes", "stream", "file" ] } ], "description": "Only with exchangePattern=InOut is a message with a reply subject answered, with the body the route ends with: text, bytes, a stream or a file. A Map, a POJO or no body sends no reply, and the requester times out" }, + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "What converts to a byte array: text, bytes, a stream or a file. A Map or a POJO is sent as its toString(), and a List or no body fails: marshal it first" }, + "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": "exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { "option": "exchangePattern", "value": "InOut", "carriers": [ "bytes" ], "javaType": "byte[]" } ], "description": "Unchanged for a message that expects no reply (InOnly). A message that expects one (InOut) waits for the reply, up to requestTimeout, and gets its payload as a byte array" } + }, "properties": { "topic": { "index": 0, "kind": "path", "displayName": "Topic", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.nats.NatsConfiguration", "configurationField": "configuration", "description": "The name of topic we want to use" }, "connectionTimeout": { "index": 1, "kind": "parameter", "displayName": "Connection Timeout", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 2000, "configurationClass": "org.apache.camel.component.nats.NatsConfiguration", "configurationField": "configuration", "description": "Timeout for connection attempts. (in milliseconds)" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/paho.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/paho.json index 1ee428f6b2eb..de99e56c6983 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/paho.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/paho.json @@ -64,6 +64,11 @@ "CamelPahoRetained": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Retain option.", "constantName": "org.apache.camel.component.paho.PahoConstants#CAMEL_PAHO_MSG_RETAINED" }, "CamelPahoOverrideTopic": { "index": 4, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of topic to override and send to instead of topic specified on endpoint.", "constantName": "org.apache.camel.component.paho.PahoConstants#CAMEL_PAHO_OVERRIDE_TOPIC" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", "description": "The payload of the MQTT message" }, + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "What converts to a byte array: text, bytes, a stream or a file, sent as the payload. A Map, a POJO or no body fails: marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ] } + }, "properties": { "topic": { "index": 0, "kind": "path", "displayName": "Topic", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Name of the topic" }, "automaticReconnect": { "index": 1, "kind": "parameter", "displayName": "Automatic Reconnect", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.paho.PahoConfiguration", "configurationField": "configuration", "description": "Sets whether the client will automatically attempt to reconnect to the server if the conne [...] diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3.json index d46e065460c7..3c4eb46d823b 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3s.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3s.json index 652f0c2be748..0dbc734fa296 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3s.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pop3s.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pulsar.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pulsar.json index edd57b05efb8..a4cce15a1aaf 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pulsar.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/pulsar.json @@ -94,6 +94,11 @@ "CamelPulsarProducerMessageDeliverAfter": { "index": 15, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deliver the message after a given delayed time (millis).", "constantName": "org.apache.camel.component.pulsar.utils.message.PulsarMessageHeaders#DELIVER_AFTER" }, "CamelPulsarProducerMessageId": { "index": 16, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "org.apache.pulsar.client.api.MessageId", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message id the broker assigned to the published message.", "constantName": "org.apache.camel.component.pulsar.utils.message.PulsarMessageHeaders#PRODUCER_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "bytes", "null" ], "javaType": "byte[]", "description": "The payload of the Pulsar message as a byte array, null for a message with a null value (a tombstone), with the key and the properties in headers: convert or unmarshal it" }, + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "What converts to a byte array: text, bytes, a stream or a file, sent as the payload. Any other body is sent with Java serialization, a Map, a List, a number and no body too, and an object that is not Serializable fails: marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, also when the exchange expects a reply, with the id of the published message in a header" } + }, "properties": { "persistence": { "index": 0, "kind": "path", "displayName": "Persistence", "group": "common", "label": "", "required": true, "type": "enum", "javaType": "java.lang.String", "enum": [ "persistent", "non-persistent" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Whether the topic is persistent or non-persistent" }, "tenant": { "index": 1, "kind": "path", "displayName": "Tenant", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The tenant" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json index dc937fb26f6a..51702b25e413 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpp.json @@ -82,7 +82,7 @@ "CamelSmppDestAddrNpi": { "index": 8, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Byte", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and DataSm Defines the numeric plan indicator (NPI) to be used in the SME destination address parameters. Use the URI option sourceAddrNpi values defined above. Consumer: only for DataSm Defines [...] "CamelSmppDestAddrTon": { "index": 9, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Byte", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and DataSm Defines the type of number (TON) to be used in the SME destination address parameters. Use the sourceAddrTon URI option values defined above. Consumer: only for DataSm Defines the typ [...] "CamelSmppDoneDate": { "index": 10, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "Date", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for smsc DeliveryReceipt The time and date at which the short message reached it's final state. The format is as follows: YYMMDDhhmm.", "constantName": "org.apache.camel.component.smpp.SmppConstants#DONE_DATE" }, - "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. Specifies the encoding (character set name) of the bytes in the message body. If the message body is a string then this is not relevant because Java Strings are always Unicode. If the body is [...] + "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and ReplaceSm. Specifies the encoding (character set name) the text of the message body is encoded in, as the short message. A byte array body is first read as text, in the charset of the exchange, unless [...] "CamelSmppError": { "index": 12, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String or Map<String, List<Map<String, Object>>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitMultiSm The errors which occurred by sending the short message(s) the form Map (messageID : (destAddr : address, error : errorCode)). Consumer: only for smsc DeliveryReceipt Where a [...] "CamelSmppClass": { "index": 13, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "org.jsmpp.bean.ESMClass", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "the ASM class", "constantName": "org.apache.camel.component.smpp.SmppConstants#ESM_CLASS" }, "CamelSmppEsmeAddr": { "index": 14, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for AlertNotification Defines the destination ESME address. For mobile terminated messages, this is the directory number of the recipient MS.", "constantName": "org.apache.camel.component.smpp.SmppConstants#ESME_ADDR" }, @@ -114,6 +114,11 @@ "CamelSmppOptionalParameter": { "index": 40, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Map<Short, Object>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti and DataSm The optional parameter which are send to the SMSC. The value is converted in the following way: String - org.jsmpp.bean.OptionalParameter.COctetString, byte - org.jsmpp.bea [...] "CamelSmppSplittingPolicy": { "index": 41, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. Specifies the policy for message splitting for this exchange. Possible values are described in the endpoint configuration parameter _splittingPolicy_", "constantName": "org.apache.camel [...] }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "bytes", "null" ], "description": "A short message as text decoded by its data coding, or as bytes for an 8-bit data coding; the text of a delivery receipt, with its fields in headers. A data_sm or an alert notification has no body" }, + "producerIn": { "carriers": [ "text", "bytes", "file" ], "description": "The text of the short message: bytes or a file are read as text, unless an 8-bit CamelSmppDataCoding or CamelSmppAlphabet header sends bytes as they are. A stream is sent empty and no body fails: convert it to text first; a Map or a POJO is sent as its toString(). DataSm, QuerySm and CancelSm do not read the body" }, + "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": "exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { "option": "exchangePattern", "value": "InOut", "carriers": [ "null" ] } ], "description": "Unchanged, with the message ids in the CamelSmppId header. When the exchange expects a reply (InOut), a new message with no body and only the result headers" } + }, "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", "configurationClass": "org.apache.camel.component.smpp.SmppConfiguration", "configurationField": "configuration", "description": "Hostname for the SMSC server to use." }, "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": 2775, "configurationClass": "org.apache.camel.component.smpp.SmppConfiguration", "configurationField": "configuration", "description": "Port number for the SMSC server to use." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json index 1adce03c7ebb..39a2de9049af 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smpps.json @@ -82,7 +82,7 @@ "CamelSmppDestAddrNpi": { "index": 8, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Byte", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and DataSm Defines the numeric plan indicator (NPI) to be used in the SME destination address parameters. Use the URI option sourceAddrNpi values defined above. Consumer: only for DataSm Defines [...] "CamelSmppDestAddrTon": { "index": 9, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Byte", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and DataSm Defines the type of number (TON) to be used in the SME destination address parameters. Use the sourceAddrTon URI option values defined above. Consumer: only for DataSm Defines the typ [...] "CamelSmppDoneDate": { "index": 10, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "Date", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for smsc DeliveryReceipt The time and date at which the short message reached it's final state. The format is as follows: YYMMDDhhmm.", "constantName": "org.apache.camel.component.smpp.SmppConstants#DONE_DATE" }, - "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. Specifies the encoding (character set name) of the bytes in the message body. If the message body is a string then this is not relevant because Java Strings are always Unicode. If the body is [...] + "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and ReplaceSm. Specifies the encoding (character set name) the text of the message body is encoded in, as the short message. A byte array body is first read as text, in the charset of the exchange, unless [...] "CamelSmppError": { "index": 12, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String or Map<String, List<Map<String, Object>>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitMultiSm The errors which occurred by sending the short message(s) the form Map (messageID : (destAddr : address, error : errorCode)). Consumer: only for smsc DeliveryReceipt Where a [...] "CamelSmppClass": { "index": 13, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "org.jsmpp.bean.ESMClass", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "the ASM class", "constantName": "org.apache.camel.component.smpp.SmppConstants#ESM_CLASS" }, "CamelSmppEsmeAddr": { "index": 14, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for AlertNotification Defines the destination ESME address. For mobile terminated messages, this is the directory number of the recipient MS.", "constantName": "org.apache.camel.component.smpp.SmppConstants#ESME_ADDR" }, @@ -114,6 +114,11 @@ "CamelSmppOptionalParameter": { "index": 40, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Map<Short, Object>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti and DataSm The optional parameter which are send to the SMSC. The value is converted in the following way: String - org.jsmpp.bean.OptionalParameter.COctetString, byte - org.jsmpp.bea [...] "CamelSmppSplittingPolicy": { "index": 41, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. Specifies the policy for message splitting for this exchange. Possible values are described in the endpoint configuration parameter _splittingPolicy_", "constantName": "org.apache.camel [...] }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "bytes", "null" ], "description": "A short message as text decoded by its data coding, or as bytes for an 8-bit data coding; the text of a delivery receipt, with its fields in headers. A data_sm or an alert notification has no body" }, + "producerIn": { "carriers": [ "text", "bytes", "file" ], "description": "The text of the short message: bytes or a file are read as text, unless an 8-bit CamelSmppDataCoding or CamelSmppAlphabet header sends bytes as they are. A stream is sent empty and no body fails: convert it to text first; a Map or a POJO is sent as its toString(). DataSm, QuerySm and CancelSm do not read the body" }, + "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": "exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { "option": "exchangePattern", "value": "InOut", "carriers": [ "null" ] } ], "description": "Unchanged, with the message ids in the CamelSmppId header. When the exchange expects a reply (InOut), a new message with no body and only the result headers" } + }, "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", "configurationClass": "org.apache.camel.component.smpp.SmppConfiguration", "configurationField": "configuration", "description": "Hostname for the SMSC server to use." }, "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": 2775, "configurationClass": "org.apache.camel.component.smpp.SmppConfiguration", "configurationField": "configuration", "description": "Port number for the SMSC server to use." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtp.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtp.json index c2e3c9652c51..e6517c971979 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtp.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtp.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtps.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtps.json index 4682f6a3524c..9bd4bd00f5a1 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtps.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/smtps.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-rabbitmq.json b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-rabbitmq.json index a2afee539d79..e2ae70cd9c83 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-rabbitmq.json +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/components/spring-rabbitmq.json @@ -78,6 +78,12 @@ "CamelSpringRabbitmqPriority": { "index": 18, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message priority.", "constantName": "org.apache.camel.component.springrabbit.SpringRabbitMQConstants#PRIORITY" }, "CamelSpringRabbitmqClusterId": { "index": 19, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The cluster id.", "constantName": "org.apache.camel.component.springrabbit.SpringRabbitMQConstants#CLUSTER_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "bytes" ], "dependsOn": [ "messageConverter" ], "description": "A String when the content type starts with text, as for text this component sends; a byte array otherwise, JSON and Java serialized objects too, which are not deserialized" }, + "consumerReply": { "carriers": [ "text", "bytes", "stream", "file" ], "dependsOn": [ "messageConverter" ], "byOption": [ { "option": "allowNullBody", "value": "true", "carriers": [ "null", "text", "bytes", "stream", "file" ] } ], "description": "The reply to a message with a reply-to, converted as the producer converts a body: a Map or a POJO fails" }, + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "dependsOn": [ "messageConverter" ], "byOption": [ { "option": "allowNullBody", "value": "true", "carriers": [ "null", "text", "bytes", "stream", "file" ] } ], "description": "Text, bytes, a stream or a file, sent as a byte array, text as text\/plain unless the CamelSpringRabbitmqContentType header says another type. A Map or a POJO fails, as it is not serialized: marshal it first" }, + "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": "exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { "option": "disableReplyTo", "value": "true", "carriers": [ "unchanged" ] } ], "description": "Unchanged for a message that expects no reply (InOnly). A message that expects one (InOut) gets the body of the reply as the consumer gives it: a String for a text content type, a byte array otherwise" } + }, "properties": { "exchangeName": { "index": 0, "kind": "path", "displayName": "Exchange Name", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The exchange name determines the exchange to which the produced messages will be sent to. In the case of consumers, the exchange name determines the exchange the queue will be bound to. Note: to use default exchan [...] "connectionFactory": { "index": 1, "kind": "parameter", "displayName": "Connection Factory", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "org.springframework.amqp.rabbit.connection.ConnectionFactory", "deprecated": false, "autowired": false, "secret": false, "description": "The connection factory to be use. A connection factory must be configured either on the component or endpoint." }, diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mail-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mail-component.adoc index c5f952ce7317..48d3f181e17b 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mail-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/mail-component.adoc @@ -189,7 +189,9 @@ trust/key store files (see `SSLNOTES.txt` in JavaMail for details). Camel uses the message exchange's IN body as the http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeMessage.html[MimeMessage] -text content. The body is converted to `String.class`. +text content. The body is converted to `String.class`: bytes, a stream or a file are read as text, so send binary +content as an attachment, and a Map or a POJO is sent as its `toString()`. A body that is a `jakarta.mail.internet.MimeMessage` +is sent as it is, with its own recipients and subject. Camel copies all of the exchange's IN headers to the http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeMessage.html[MimeMessage] @@ -691,17 +693,8 @@ the Splitter as shown below </split> ---- -You can also split the attachments as byte[] to -be stored as the message body. This is done by creating the expression -with boolean true - -._Java-only: programmatic `SplitAttachmentsExpression` configuration_ -[source,java] ----- -SplitAttachmentsExpression split = SplitAttachmentsExpression(true); ----- - -And then use the expression with the splitter EIP. +Each split message has the content of one attachment as its body: a byte array, or a String for a text +attachment, with the name of the attachment in the `CamelSplitAttachmentId` header. === Using custom SearchTerm diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/nats-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/nats-component.adoc index 8d11c415f087..63d1ad3aaf22 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/nats-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/nats-component.adoc @@ -116,9 +116,12 @@ camel.component.nats.servers=scott:tiger@someserver:4222,superman:123@someothers ---- === Request/Reply support -The producer supports request/reply where it can wait for an expected reply message. +The producer supports request/reply: when the exchange pattern is InOut, it waits for the reply message, up to +`requestTimeout`, and the payload of the reply becomes the message body, as a byte array. -The consumer will, when routing the message is complete, send back the message as reply-message if required. +The consumer sends back the message body as the reply message, when routing the message is complete, if the message has a +reply subject and the consumer has `exchangePattern=InOut`. The body must convert to a byte array: text, bytes, a stream or a +file. A body that does not, such as a Map, sends no reply. == Examples diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc index 02358413bb5a..8c5525d86d6e 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/smpp-component.adoc @@ -114,6 +114,9 @@ corresponding alphabet. When deciding which alphabet to use in the byte array, the Camel SMPP component does not consider the data coding value (header or configuration), it only considers the specified alphabet (from either the header or endpoint parameter). +The exception is an 8-bit data coding or alphabet in a header: the body is +then sent as the bytes it converts to, as they are. The same values in the +endpoint parameters do not do this, so a byte array body is read as text first. If some characters in the String cannot be represented in the chosen alphabet, they may be replaced by the question mark (`?`) symbol. @@ -121,8 +124,10 @@ Users of the API may want to consider checking if their message body can be converted to ISO-8859-1 before passing it to the component and if not, setting the alphabet header to request UCS-2 encoding. If the alphabet -and data coding options are not specified at all, then the component may -try to detect the required encoding and set the data coding for you. +and data coding options are not specified at all, the component does not +detect the required encoding or set the data coding for you: the text is +encoded for the SMSC default alphabet (`0`), in the `encoding` of the endpoint, +ISO-8859-1 by default. The list of alphabet codes is specified in the SMPP specification v3.4, section 5.2.19. One notable limitation of the SMPP specification is @@ -145,8 +150,10 @@ is completed automatically. If the GSM 3.38 alphabet is used, the component will pack up to 160 characters into the 140-byte message body. -If an 8-bit character set is used (e.g., ISO-8859-1 for Western Europe), then 140 characters will be -allowed within the 140-byte message body. +If the 8-bit alphabet (`4`) is used, then 140 bytes will be +allowed within the 140-byte message body. Text in an 8-bit character set +(e.g., ISO-8859-1 for Western Europe) is split by 140 bytes only with that +alphabet; with the default alphabet, it is split by 160 characters. If 16 bit UCS-2 encoding is used, then just 70 characters fit into each 140-byte message. diff --git a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imap.json b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imap.json index 8399bb76ec5a..47a584bfbb93 100644 --- a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imap.json +++ b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imap.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imaps.json b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imaps.json index 183ccb7e3722..35c217ab9acd 100644 --- a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imaps.json +++ b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/imaps.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3.json b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3.json index d46e065460c7..3c4eb46d823b 100644 --- a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3.json +++ b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3s.json b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3s.json index 652f0c2be748..0dbc734fa296 100644 --- a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3s.json +++ b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/pop3s.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtp.json b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtp.json index c2e3c9652c51..e6517c971979 100644 --- a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtp.json +++ b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtp.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtps.json b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtps.json index 4682f6a3524c..9bd4bd00f5a1 100644 --- a/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtps.json +++ b/components/camel-mail/src/generated/resources/META-INF/org/apache/camel/component/mail/smtps.json @@ -95,6 +95,11 @@ "CamelMailDelete": { "index": 9, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deletes the messages after they have been processed.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_DELETE" }, "CamelMailMessageId": { "index": 10, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message ID.", "constantName": "org.apache.camel.component.mail.MailConstants#MAIL_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "stream", "pojo" ], "dependsOn": [ "binding" ], "byOption": [ { "option": "mapMailMessage", "value": "false", "carriers": [ "pojo" ], "javaType": "jakarta.mail.Message" } ], "description": "The content of the mail an imap or pop3 consumer reads: a String for text\/plain, text\/html and text\/xml, a stream for another content type, and a jakarta.mail Multipart for a multipart mail, which converts to the text of its first text part, with the files [...] + "producerIn": { "carriers": [ "null", "text", "bytes", "stream", "file" ], "dependsOn": [ "binding" ], "description": "The text of the mail smtp sends, in the contentType: bytes, a stream or a file are read as text, so send binary content as an attachment, and no body sends an empty text. A jakarta.mail MimeMessage is sent as it is, and a Map or a POJO as its toString(): marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, with the Message-ID of the mail in the CamelMailMessageId header" } + }, "properties": { "host": { "index": 0, "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The mail server host name" }, "port": { "index": 1, "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.mail.MailConfiguration", "configurationField": "configuration", "description": "The port number of the mail server" }, diff --git a/components/camel-mail/src/main/docs/mail-component.adoc b/components/camel-mail/src/main/docs/mail-component.adoc index c5f952ce7317..48d3f181e17b 100644 --- a/components/camel-mail/src/main/docs/mail-component.adoc +++ b/components/camel-mail/src/main/docs/mail-component.adoc @@ -189,7 +189,9 @@ trust/key store files (see `SSLNOTES.txt` in JavaMail for details). Camel uses the message exchange's IN body as the http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeMessage.html[MimeMessage] -text content. The body is converted to `String.class`. +text content. The body is converted to `String.class`: bytes, a stream or a file are read as text, so send binary +content as an attachment, and a Map or a POJO is sent as its `toString()`. A body that is a `jakarta.mail.internet.MimeMessage` +is sent as it is, with its own recipients and subject. Camel copies all of the exchange's IN headers to the http://java.sun.com/javaee/5/docs/api/javax/mail/internet/MimeMessage.html[MimeMessage] @@ -691,17 +693,8 @@ the Splitter as shown below </split> ---- -You can also split the attachments as byte[] to -be stored as the message body. This is done by creating the expression -with boolean true - -._Java-only: programmatic `SplitAttachmentsExpression` configuration_ -[source,java] ----- -SplitAttachmentsExpression split = SplitAttachmentsExpression(true); ----- - -And then use the expression with the splitter EIP. +Each split message has the content of one attachment as its body: a byte array, or a String for a text +attachment, with the name of the attachment in the `CamelSplitAttachmentId` header. === Using custom SearchTerm diff --git a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java index 1c52a0a92ae5..45b3fb1dcb48 100644 --- a/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java +++ b/components/camel-mail/src/main/java/org/apache/camel/component/mail/MailEndpoint.java @@ -26,6 +26,9 @@ import org.apache.camel.Consumer; import org.apache.camel.Exchange; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.EndpointServiceLocation; import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.spi.HeaderFilterStrategyAware; @@ -47,6 +50,23 @@ import static org.apache.camel.component.mail.MailConstants.MAIL_HANDLE_DUPLICAT @UriEndpoint(firstVersion = "1.0.0", scheme = "imap,imaps,pop3,pop3s,smtp,smtps", title = "IMAP,IMAPS,POP3,POP3S,SMTP,SMTPS", syntax = "imap:host:port", alternativeSyntax = "imap:username:password@host:port", category = { Category.MAIL }, headersClass = MailConstants.class) +@BodyTypes(consumerOut = @BodyType(value = { Carrier.TEXT, Carrier.STREAM, Carrier.POJO }, dependsOn = "binding", + byOption = @BodyType.When(option = "mapMailMessage", value = "false", + carriers = Carrier.POJO, javaType = "jakarta.mail.Message"), + description = "The content of the mail an imap or pop3 consumer reads: a String for" + + " text/plain, text/html and text/xml, a stream for another content type," + + " and a jakarta.mail Multipart for a multipart mail, which converts to the" + + " text of its first text part, with the files in the attachments. The" + + " jakarta.mail.Message itself with mapMailMessage=false"), + producerIn = @BodyType(value = { Carrier.NULL, Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + dependsOn = "binding", + description = "The text of the mail smtp sends, in the contentType: bytes, a stream or a" + + " file are read as text, so send binary content as an attachment, and no" + + " body sends an empty text. A jakarta.mail MimeMessage is sent as it is," + + " and a Map or a POJO as its toString(): marshal it first"), + producerOut = @BodyType(value = Carrier.UNCHANGED, + description = "Unchanged, with the Message-ID of the mail in the CamelMailMessageId" + + " header")) public class MailEndpoint extends ScheduledPollEndpoint implements HeaderFilterStrategyAware, EndpointServiceLocation { @UriParam(defaultValue = "" + MailConsumer.DEFAULT_CONSUMER_DELAY, javaType = "java.time.Duration", diff --git a/components/camel-nats/src/generated/resources/META-INF/org/apache/camel/component/nats/nats.json b/components/camel-nats/src/generated/resources/META-INF/org/apache/camel/component/nats/nats.json index eca34ceb7d3c..50696e134278 100644 --- a/components/camel-nats/src/generated/resources/META-INF/org/apache/camel/component/nats/nats.json +++ b/components/camel-nats/src/generated/resources/META-INF/org/apache/camel/component/nats/nats.json @@ -80,6 +80,12 @@ "CamelNatsDeliveryCounter": { "index": 7, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "important": true, "description": "Number of times this message has been delivered (1 = first, 1 then message has been redelivered)", "constantName": "org.apache.camel.component.nats.NatsConstants#NATS_DELIVERY_COUNTER" }, "CamelNatsManualAck": { "index": 8, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "org.apache.camel.component.nats.NatsManualAck", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The manual acknowledgment handle for JetStream messages (only set when manualAck=true).", "constantName": "org.apache.camel.component.nats.NatsConstants#NATS_MANUAL_ACK" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", "description": "The payload of the NATS message as a byte array, empty for a message without one: convert or unmarshal it" }, + "consumerReply": { "carriers": [ "any" ], "byOption": [ { "option": "exchangePattern", "value": "InOut", "carriers": [ "text", "bytes", "stream", "file" ] } ], "description": "Only with exchangePattern=InOut is a message with a reply subject answered, with the body the route ends with: text, bytes, a stream or a file. A Map, a POJO or no body sends no reply, and the requester times out" }, + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "What converts to a byte array: text, bytes, a stream or a file. A Map or a POJO is sent as its toString(), and a List or no body fails: marshal it first" }, + "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": "exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { "option": "exchangePattern", "value": "InOut", "carriers": [ "bytes" ], "javaType": "byte[]" } ], "description": "Unchanged for a message that expects no reply (InOnly). A message that expects one (InOut) waits for the reply, up to requestTimeout, and gets its payload as a byte array" } + }, "properties": { "topic": { "index": 0, "kind": "path", "displayName": "Topic", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.nats.NatsConfiguration", "configurationField": "configuration", "description": "The name of topic we want to use" }, "connectionTimeout": { "index": 1, "kind": "parameter", "displayName": "Connection Timeout", "group": "common", "label": "common", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 2000, "configurationClass": "org.apache.camel.component.nats.NatsConfiguration", "configurationField": "configuration", "description": "Timeout for connection attempts. (in milliseconds)" }, diff --git a/components/camel-nats/src/main/docs/nats-component.adoc b/components/camel-nats/src/main/docs/nats-component.adoc index 8d11c415f087..63d1ad3aaf22 100644 --- a/components/camel-nats/src/main/docs/nats-component.adoc +++ b/components/camel-nats/src/main/docs/nats-component.adoc @@ -116,9 +116,12 @@ camel.component.nats.servers=scott:tiger@someserver:4222,superman:123@someothers ---- === Request/Reply support -The producer supports request/reply where it can wait for an expected reply message. +The producer supports request/reply: when the exchange pattern is InOut, it waits for the reply message, up to +`requestTimeout`, and the payload of the reply becomes the message body, as a byte array. -The consumer will, when routing the message is complete, send back the message as reply-message if required. +The consumer sends back the message body as the reply message, when routing the message is complete, if the message has a +reply subject and the consumer has `exchangePattern=InOut`. The body must convert to a byte array: text, bytes, a stream or a +file. A body that does not, such as a Map, sends no reply. == Examples diff --git a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsEndpoint.java b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsEndpoint.java index ed1aaa74511e..2d95d008a104 100644 --- a/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsEndpoint.java +++ b/components/camel-nats/src/main/java/org/apache/camel/component/nats/NatsEndpoint.java @@ -31,6 +31,9 @@ import org.apache.camel.Consumer; import org.apache.camel.MultipleConsumersSupport; import org.apache.camel.Processor; import org.apache.camel.Producer; +import org.apache.camel.spi.BodyType; +import org.apache.camel.spi.BodyType.Carrier; +import org.apache.camel.spi.BodyTypes; import org.apache.camel.spi.EndpointServiceLocation; import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.spi.HeaderFilterStrategyAware; @@ -45,6 +48,31 @@ import org.apache.camel.util.ObjectHelper; */ @UriEndpoint(firstVersion = "2.17.0", scheme = "nats", title = "Nats", syntax = "nats:topic", category = { Category.MESSAGING }, headersClass = NatsConstants.class) +@BodyTypes(consumerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]", + description = "The payload of the NATS message as a byte array, empty for a message" + + " without one: convert or unmarshal it"), + consumerReply = @BodyType(value = Carrier.ANY, + byOption = @BodyType.When(option = "exchangePattern", value = "InOut", + carriers = { + Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, + Carrier.FILE }), + description = "Only with exchangePattern=InOut is a message with a reply subject" + + " answered, with the body the route ends with: text, bytes, a stream or a" + + " file. A Map, a POJO or no body sends no reply, and the requester" + + " times out"), + producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + description = "What converts to a byte array: text, bytes, a stream or a file. A Map or a" + + " POJO is sent as its toString(), and a List or no body fails: marshal it" + + " first"), + producerOut = @BodyType(value = Carrier.UNKNOWN, + byOption = { + @BodyType.When(option = "exchangePattern", value = "InOnly", + carriers = Carrier.UNCHANGED), + @BodyType.When(option = "exchangePattern", value = "InOut", + carriers = Carrier.BYTES, javaType = "byte[]") }, + description = "Unchanged for a message that expects no reply (InOnly). A message that" + + " expects one (InOut) waits for the reply, up to requestTimeout, and gets" + + " its payload as a byte array")) public class NatsEndpoint extends DefaultEndpoint implements MultipleConsumersSupport, HeaderFilterStrategyAware, EndpointServiceLocation { diff --git a/components/camel-paho/src/generated/resources/META-INF/org/apache/camel/component/paho/paho.json b/components/camel-paho/src/generated/resources/META-INF/org/apache/camel/component/paho/paho.json index 1ee428f6b2eb..de99e56c6983 100644 --- a/components/camel-paho/src/generated/resources/META-INF/org/apache/camel/component/paho/paho.json +++ b/components/camel-paho/src/generated/resources/META-INF/org/apache/camel/component/paho/paho.json @@ -64,6 +64,11 @@ "CamelPahoRetained": { "index": 3, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Retain option.", "constantName": "org.apache.camel.component.paho.PahoConstants#CAMEL_PAHO_MSG_RETAINED" }, "CamelPahoOverrideTopic": { "index": 4, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The name of topic to override and send to instead of topic specified on endpoint.", "constantName": "org.apache.camel.component.paho.PahoConstants#CAMEL_PAHO_OVERRIDE_TOPIC" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "bytes" ], "javaType": "byte[]", "description": "The payload of the MQTT message" }, + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "What converts to a byte array: text, bytes, a stream or a file, sent as the payload. A Map, a POJO or no body fails: marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ] } + }, "properties": { "topic": { "index": 0, "kind": "path", "displayName": "Topic", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Name of the topic" }, "automaticReconnect": { "index": 1, "kind": "parameter", "displayName": "Automatic Reconnect", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.paho.PahoConfiguration", "configurationField": "configuration", "description": "Sets whether the client will automatically attempt to reconnect to the server if the conne [...] diff --git a/components/camel-paho/src/main/java/org/apache/camel/component/paho/PahoEndpoint.java b/components/camel-paho/src/main/java/org/apache/camel/component/paho/PahoEndpoint.java index 48773c9848a2..619689ce1fcc 100644 --- a/components/camel-paho/src/main/java/org/apache/camel/component/paho/PahoEndpoint.java +++ b/components/camel-paho/src/main/java/org/apache/camel/component/paho/PahoEndpoint.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,11 @@ import org.eclipse.paho.client.mqttv3.persist.MqttDefaultFilePersistence; @UriEndpoint(firstVersion = "2.16.0", scheme = "paho", title = "Paho", category = { Category.MESSAGING, Category.IOT }, syntax = "paho:topic", headersClass = PahoConstants.class) @Deprecated(since = "4.21") +@BodyTypes(consumerOut = @BodyType(value = Carrier.BYTES, javaType = "byte[]", description = "The payload of the MQTT message"), + producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + description = "What converts to a byte array: text, bytes, a stream or a file, sent as" + + " the payload. A Map, a POJO or no body fails: marshal it first"), + producerOut = @BodyType(Carrier.UNCHANGED)) public class PahoEndpoint extends DefaultEndpoint implements EndpointServiceLocation { // Configuration members diff --git a/components/camel-pulsar/src/generated/resources/META-INF/org/apache/camel/component/pulsar/pulsar.json b/components/camel-pulsar/src/generated/resources/META-INF/org/apache/camel/component/pulsar/pulsar.json index edd57b05efb8..a4cce15a1aaf 100644 --- a/components/camel-pulsar/src/generated/resources/META-INF/org/apache/camel/component/pulsar/pulsar.json +++ b/components/camel-pulsar/src/generated/resources/META-INF/org/apache/camel/component/pulsar/pulsar.json @@ -94,6 +94,11 @@ "CamelPulsarProducerMessageDeliverAfter": { "index": 15, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "Long", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Deliver the message after a given delayed time (millis).", "constantName": "org.apache.camel.component.pulsar.utils.message.PulsarMessageHeaders#DELIVER_AFTER" }, "CamelPulsarProducerMessageId": { "index": 16, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "org.apache.pulsar.client.api.MessageId", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message id the broker assigned to the published message.", "constantName": "org.apache.camel.component.pulsar.utils.message.PulsarMessageHeaders#PRODUCER_MESSAGE_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "bytes", "null" ], "javaType": "byte[]", "description": "The payload of the Pulsar message as a byte array, null for a message with a null value (a tombstone), with the key and the properties in headers: convert or unmarshal it" }, + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "description": "What converts to a byte array: text, bytes, a stream or a file, sent as the payload. Any other body is sent with Java serialization, a Map, a List, a number and no body too, and an object that is not Serializable fails: marshal it first" }, + "producerOut": { "carriers": [ "unchanged" ], "description": "Unchanged, also when the exchange expects a reply, with the id of the published message in a header" } + }, "properties": { "persistence": { "index": 0, "kind": "path", "displayName": "Persistence", "group": "common", "label": "", "required": true, "type": "enum", "javaType": "java.lang.String", "enum": [ "persistent", "non-persistent" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Whether the topic is persistent or non-persistent" }, "tenant": { "index": 1, "kind": "path", "displayName": "Tenant", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The tenant" }, diff --git a/components/camel-pulsar/src/main/java/org/apache/camel/component/pulsar/PulsarEndpoint.java b/components/camel-pulsar/src/main/java/org/apache/camel/component/pulsar/PulsarEndpoint.java index fd6de025b5ba..fd5fdb1ee8c0 100644 --- a/components/camel-pulsar/src/main/java/org/apache/camel/component/pulsar/PulsarEndpoint.java +++ b/components/camel-pulsar/src/main/java/org/apache/camel/component/pulsar/PulsarEndpoint.java @@ -21,6 +21,9 @@ import org.apache.camel.Consumer; import org.apache.camel.Processor; import org.apache.camel.Producer; import org.apache.camel.component.pulsar.utils.message.PulsarMessageHeaders; +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; @@ -37,6 +40,18 @@ import org.apache.pulsar.client.api.PulsarClient; @UriEndpoint(scheme = "pulsar", firstVersion = "2.24.0", title = "Pulsar", syntax = "pulsar:persistence://tenant/namespace/topic", category = { Category.MESSAGING }, headersClass = PulsarMessageHeaders.class) +@BodyTypes(consumerOut = @BodyType(value = { Carrier.BYTES, Carrier.NULL }, javaType = "byte[]", + description = "The payload of the Pulsar message as a byte array, null for a message with" + + " a null value (a tombstone), with the key and the properties in headers:" + + " convert or unmarshal it"), + producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + description = "What converts to a byte array: text, bytes, a stream or a file, sent as the" + + " payload. Any other body is sent with Java serialization, a Map, a List, a" + + " number and no body too, and an object that is not Serializable fails:" + + " marshal it first"), + producerOut = @BodyType(value = Carrier.UNCHANGED, + description = "Unchanged, also when the exchange expects a reply, with the id of the" + + " published message in a header")) public class PulsarEndpoint extends DefaultEndpoint implements EndpointServiceLocation { private PulsarClient pulsarClient; diff --git a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json index dc937fb26f6a..51702b25e413 100644 --- a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json +++ b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpp.json @@ -82,7 +82,7 @@ "CamelSmppDestAddrNpi": { "index": 8, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Byte", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and DataSm Defines the numeric plan indicator (NPI) to be used in the SME destination address parameters. Use the URI option sourceAddrNpi values defined above. Consumer: only for DataSm Defines [...] "CamelSmppDestAddrTon": { "index": 9, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Byte", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and DataSm Defines the type of number (TON) to be used in the SME destination address parameters. Use the sourceAddrTon URI option values defined above. Consumer: only for DataSm Defines the typ [...] "CamelSmppDoneDate": { "index": 10, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "Date", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for smsc DeliveryReceipt The time and date at which the short message reached it's final state. The format is as follows: YYMMDDhhmm.", "constantName": "org.apache.camel.component.smpp.SmppConstants#DONE_DATE" }, - "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. Specifies the encoding (character set name) of the bytes in the message body. If the message body is a string then this is not relevant because Java Strings are always Unicode. If the body is [...] + "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and ReplaceSm. Specifies the encoding (character set name) the text of the message body is encoded in, as the short message. A byte array body is first read as text, in the charset of the exchange, unless [...] "CamelSmppError": { "index": 12, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String or Map<String, List<Map<String, Object>>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitMultiSm The errors which occurred by sending the short message(s) the form Map (messageID : (destAddr : address, error : errorCode)). Consumer: only for smsc DeliveryReceipt Where a [...] "CamelSmppClass": { "index": 13, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "org.jsmpp.bean.ESMClass", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "the ASM class", "constantName": "org.apache.camel.component.smpp.SmppConstants#ESM_CLASS" }, "CamelSmppEsmeAddr": { "index": 14, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for AlertNotification Defines the destination ESME address. For mobile terminated messages, this is the directory number of the recipient MS.", "constantName": "org.apache.camel.component.smpp.SmppConstants#ESME_ADDR" }, @@ -114,6 +114,11 @@ "CamelSmppOptionalParameter": { "index": 40, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Map<Short, Object>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti and DataSm The optional parameter which are send to the SMSC. The value is converted in the following way: String - org.jsmpp.bean.OptionalParameter.COctetString, byte - org.jsmpp.bea [...] "CamelSmppSplittingPolicy": { "index": 41, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. Specifies the policy for message splitting for this exchange. Possible values are described in the endpoint configuration parameter _splittingPolicy_", "constantName": "org.apache.camel [...] }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "bytes", "null" ], "description": "A short message as text decoded by its data coding, or as bytes for an 8-bit data coding; the text of a delivery receipt, with its fields in headers. A data_sm or an alert notification has no body" }, + "producerIn": { "carriers": [ "text", "bytes", "file" ], "description": "The text of the short message: bytes or a file are read as text, unless an 8-bit CamelSmppDataCoding or CamelSmppAlphabet header sends bytes as they are. A stream is sent empty and no body fails: convert it to text first; a Map or a POJO is sent as its toString(). DataSm, QuerySm and CancelSm do not read the body" }, + "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": "exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { "option": "exchangePattern", "value": "InOut", "carriers": [ "null" ] } ], "description": "Unchanged, with the message ids in the CamelSmppId header. When the exchange expects a reply (InOut), a new message with no body and only the result headers" } + }, "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", "configurationClass": "org.apache.camel.component.smpp.SmppConfiguration", "configurationField": "configuration", "description": "Hostname for the SMSC server to use." }, "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": 2775, "configurationClass": "org.apache.camel.component.smpp.SmppConfiguration", "configurationField": "configuration", "description": "Port number for the SMSC server to use." }, diff --git a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json index 1adce03c7ebb..39a2de9049af 100644 --- a/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json +++ b/components/camel-smpp/src/generated/resources/META-INF/org/apache/camel/component/smpp/smpps.json @@ -82,7 +82,7 @@ "CamelSmppDestAddrNpi": { "index": 8, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Byte", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and DataSm Defines the numeric plan indicator (NPI) to be used in the SME destination address parameters. Use the URI option sourceAddrNpi values defined above. Consumer: only for DataSm Defines [...] "CamelSmppDestAddrTon": { "index": 9, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Byte", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti, CancelSm and DataSm Defines the type of number (TON) to be used in the SME destination address parameters. Use the sourceAddrTon URI option values defined above. Consumer: only for DataSm Defines the typ [...] "CamelSmppDoneDate": { "index": 10, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "Date", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for smsc DeliveryReceipt The time and date at which the short message reached it's final state. The format is as follows: YYMMDDhhmm.", "constantName": "org.apache.camel.component.smpp.SmppConstants#DONE_DATE" }, - "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. Specifies the encoding (character set name) of the bytes in the message body. If the message body is a string then this is not relevant because Java Strings are always Unicode. If the body is [...] + "CamelSmppEncoding": { "index": 11, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and ReplaceSm. Specifies the encoding (character set name) the text of the message body is encoded in, as the short message. A byte array body is first read as text, in the charset of the exchange, unless [...] "CamelSmppError": { "index": 12, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String or Map<String, List<Map<String, Object>>>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitMultiSm The errors which occurred by sending the short message(s) the form Map (messageID : (destAddr : address, error : errorCode)). Consumer: only for smsc DeliveryReceipt Where a [...] "CamelSmppClass": { "index": 13, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "org.jsmpp.bean.ESMClass", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "the ASM class", "constantName": "org.apache.camel.component.smpp.SmppConstants#ESM_CLASS" }, "CamelSmppEsmeAddr": { "index": 14, "kind": "header", "displayName": "", "group": "consumer", "label": "consumer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for AlertNotification Defines the destination ESME address. For mobile terminated messages, this is the directory number of the recipient MS.", "constantName": "org.apache.camel.component.smpp.SmppConstants#ESME_ADDR" }, @@ -114,6 +114,11 @@ "CamelSmppOptionalParameter": { "index": 40, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Map<Short, Object>", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Producer: only for SubmitSm, SubmitMulti and DataSm The optional parameter which are send to the SMSC. The value is converted in the following way: String - org.jsmpp.bean.OptionalParameter.COctetString, byte - org.jsmpp.bea [...] "CamelSmppSplittingPolicy": { "index": 41, "kind": "header", "displayName": "", "group": "producer", "label": "producer", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "only for SubmitSm, SubmitMulti and DataSm. Specifies the policy for message splitting for this exchange. Possible values are described in the endpoint configuration parameter _splittingPolicy_", "constantName": "org.apache.camel [...] }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "bytes", "null" ], "description": "A short message as text decoded by its data coding, or as bytes for an 8-bit data coding; the text of a delivery receipt, with its fields in headers. A data_sm or an alert notification has no body" }, + "producerIn": { "carriers": [ "text", "bytes", "file" ], "description": "The text of the short message: bytes or a file are read as text, unless an 8-bit CamelSmppDataCoding or CamelSmppAlphabet header sends bytes as they are. A stream is sent empty and no body fails: convert it to text first; a Map or a POJO is sent as its toString(). DataSm, QuerySm and CancelSm do not read the body" }, + "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": "exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { "option": "exchangePattern", "value": "InOut", "carriers": [ "null" ] } ], "description": "Unchanged, with the message ids in the CamelSmppId header. When the exchange expects a reply (InOut), a new message with no body and only the result headers" } + }, "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", "configurationClass": "org.apache.camel.component.smpp.SmppConfiguration", "configurationField": "configuration", "description": "Hostname for the SMSC server to use." }, "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": 2775, "configurationClass": "org.apache.camel.component.smpp.SmppConfiguration", "configurationField": "configuration", "description": "Port number for the SMSC server to use." }, diff --git a/components/camel-smpp/src/main/docs/smpp-component.adoc b/components/camel-smpp/src/main/docs/smpp-component.adoc index 02358413bb5a..8c5525d86d6e 100644 --- a/components/camel-smpp/src/main/docs/smpp-component.adoc +++ b/components/camel-smpp/src/main/docs/smpp-component.adoc @@ -114,6 +114,9 @@ corresponding alphabet. When deciding which alphabet to use in the byte array, the Camel SMPP component does not consider the data coding value (header or configuration), it only considers the specified alphabet (from either the header or endpoint parameter). +The exception is an 8-bit data coding or alphabet in a header: the body is +then sent as the bytes it converts to, as they are. The same values in the +endpoint parameters do not do this, so a byte array body is read as text first. If some characters in the String cannot be represented in the chosen alphabet, they may be replaced by the question mark (`?`) symbol. @@ -121,8 +124,10 @@ Users of the API may want to consider checking if their message body can be converted to ISO-8859-1 before passing it to the component and if not, setting the alphabet header to request UCS-2 encoding. If the alphabet -and data coding options are not specified at all, then the component may -try to detect the required encoding and set the data coding for you. +and data coding options are not specified at all, the component does not +detect the required encoding or set the data coding for you: the text is +encoded for the SMSC default alphabet (`0`), in the `encoding` of the endpoint, +ISO-8859-1 by default. The list of alphabet codes is specified in the SMPP specification v3.4, section 5.2.19. One notable limitation of the SMPP specification is @@ -145,8 +150,10 @@ is completed automatically. If the GSM 3.38 alphabet is used, the component will pack up to 160 characters into the 140-byte message body. -If an 8-bit character set is used (e.g., ISO-8859-1 for Western Europe), then 140 characters will be -allowed within the 140-byte message body. +If the 8-bit alphabet (`4`) is used, then 140 bytes will be +allowed within the 140-byte message body. Text in an 8-bit character set +(e.g., ISO-8859-1 for Western Europe) is split by 140 bytes only with that +alphabet; with the default alphabet, it is split by 160 characters. If 16 bit UCS-2 encoding is used, then just 70 characters fit into each 140-byte message. diff --git a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConstants.java b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConstants.java index 56736b1bb880..ddb349a4a0d5 100644 --- a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConstants.java +++ b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppConstants.java @@ -80,12 +80,12 @@ public interface SmppConstants { javaType = "Date") String DONE_DATE = "CamelSmppDoneDate"; @Metadata(label = "producer", description = "*only for SubmitSm,\n" + - "SubmitMulti and DataSm*. Specifies the encoding (character set name) of\n" + - "the bytes in the message body. If the message body is a string then\n" + - "this is not relevant because Java Strings are always Unicode. If the\n" + - "body is a byte array then this header can be used to indicate that it is\n" + - "ISO-8859-1 or some other value. Default value is specified by the\n" + - "endpoint configuration parameter _encoding_", + "SubmitMulti and ReplaceSm*. Specifies the encoding (character set name)\n" + + "the text of the message body is encoded in, as the short message. A\n" + + "byte array body is first read as text, in the charset of the exchange,\n" + + "unless an 8-bit data coding or alphabet header sends it as it is.\n" + + "Default value is specified by the endpoint configuration parameter\n" + + "_encoding_", javaType = "String") String ENCODING = "CamelSmppEncoding"; @Metadata(description = "*Producer:* *only for SubmitMultiSm* The errors which\n" + diff --git a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppEndpoint.java b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppEndpoint.java index 84771fb69c4a..584ea1f40275 100644 --- a/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppEndpoint.java +++ b/components/camel-smpp/src/main/java/org/apache/camel/component/smpp/SmppEndpoint.java @@ -23,6 +23,9 @@ import org.apache.camel.Exchange; import org.apache.camel.ExchangePattern; 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.UriEndpoint; import org.apache.camel.spi.UriParam; @@ -35,6 +38,25 @@ import org.jsmpp.bean.DeliverSm; */ @UriEndpoint(firstVersion = "2.2.0", scheme = "smpp,smpps", title = "SMPP", syntax = "smpp:host:port", category = { Category.MOBILE }, lenientProperties = true, headersClass = SmppConstants.class) +@BodyTypes(consumerOut = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.NULL }, + description = "A short message as text decoded by its data coding, or as bytes for an" + + " 8-bit data coding; the text of a delivery receipt, with its fields in" + + " headers. A data_sm or an alert notification has no body"), + producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.FILE }, + description = "The text of the short message: bytes or a file are read as text, unless an" + + " 8-bit CamelSmppDataCoding or CamelSmppAlphabet header sends bytes as they" + + " are. A stream is sent empty and no body fails: convert it to text first;" + + " a Map or a POJO is sent as its toString(). DataSm, QuerySm and CancelSm do" + + " not read the body"), + producerOut = @BodyType(value = Carrier.UNKNOWN, + byOption = { + @BodyType.When(option = "exchangePattern", value = "InOnly", + carriers = Carrier.UNCHANGED), + @BodyType.When(option = "exchangePattern", value = "InOut", + carriers = Carrier.NULL) }, + description = "Unchanged, with the message ids in the CamelSmppId header. When the" + + " exchange expects a reply (InOut), a new message with no body and only the" + + " result headers")) public class SmppEndpoint extends DefaultEndpoint implements EndpointServiceLocation { private SmppBinding binding; diff --git a/components/camel-spring-parent/camel-spring-rabbitmq/src/generated/resources/META-INF/org/apache/camel/component/springrabbit/spring-rabbitmq.json b/components/camel-spring-parent/camel-spring-rabbitmq/src/generated/resources/META-INF/org/apache/camel/component/springrabbit/spring-rabbitmq.json index a2afee539d79..e2ae70cd9c83 100644 --- a/components/camel-spring-parent/camel-spring-rabbitmq/src/generated/resources/META-INF/org/apache/camel/component/springrabbit/spring-rabbitmq.json +++ b/components/camel-spring-parent/camel-spring-rabbitmq/src/generated/resources/META-INF/org/apache/camel/component/springrabbit/spring-rabbitmq.json @@ -78,6 +78,12 @@ "CamelSpringRabbitmqPriority": { "index": 18, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The message priority.", "constantName": "org.apache.camel.component.springrabbit.SpringRabbitMQConstants#PRIORITY" }, "CamelSpringRabbitmqClusterId": { "index": 19, "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The cluster id.", "constantName": "org.apache.camel.component.springrabbit.SpringRabbitMQConstants#CLUSTER_ID" } }, + "bodyTypes": { + "consumerOut": { "carriers": [ "text", "bytes" ], "dependsOn": [ "messageConverter" ], "description": "A String when the content type starts with text, as for text this component sends; a byte array otherwise, JSON and Java serialized objects too, which are not deserialized" }, + "consumerReply": { "carriers": [ "text", "bytes", "stream", "file" ], "dependsOn": [ "messageConverter" ], "byOption": [ { "option": "allowNullBody", "value": "true", "carriers": [ "null", "text", "bytes", "stream", "file" ] } ], "description": "The reply to a message with a reply-to, converted as the producer converts a body: a Map or a POJO fails" }, + "producerIn": { "carriers": [ "text", "bytes", "stream", "file" ], "dependsOn": [ "messageConverter" ], "byOption": [ { "option": "allowNullBody", "value": "true", "carriers": [ "null", "text", "bytes", "stream", "file" ] } ], "description": "Text, bytes, a stream or a file, sent as a byte array, text as text\/plain unless the CamelSpringRabbitmqContentType header says another type. A Map or a POJO fails, as it is not serialized: marshal it first" }, + "producerOut": { "carriers": [ "unknown" ], "byOption": [ { "option": "exchangePattern", "value": "InOnly", "carriers": [ "unchanged" ] }, { "option": "disableReplyTo", "value": "true", "carriers": [ "unchanged" ] } ], "description": "Unchanged for a message that expects no reply (InOnly). A message that expects one (InOut) gets the body of the reply as the consumer gives it: a String for a text content type, a byte array otherwise" } + }, "properties": { "exchangeName": { "index": 0, "kind": "path", "displayName": "Exchange Name", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The exchange name determines the exchange to which the produced messages will be sent to. In the case of consumers, the exchange name determines the exchange the queue will be bound to. Note: to use default exchan [...] "connectionFactory": { "index": 1, "kind": "parameter", "displayName": "Connection Factory", "group": "common", "label": "common", "required": false, "type": "object", "javaType": "org.springframework.amqp.rabbit.connection.ConnectionFactory", "deprecated": false, "autowired": false, "secret": false, "description": "The connection factory to be use. A connection factory must be configured either on the component or endpoint." }, diff --git a/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQEndpoint.java b/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQEndpoint.java index 25343414cffe..ba560b46b8c7 100644 --- a/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQEndpoint.java +++ b/components/camel-spring-parent/camel-spring-rabbitmq/src/main/java/org/apache/camel/component/springrabbit/SpringRabbitMQEndpoint.java @@ -26,6 +26,9 @@ import org.apache.camel.Exchange; 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.EndpointServiceLocation; import org.apache.camel.spi.Metadata; import org.apache.camel.spi.UriEndpoint; @@ -57,6 +60,36 @@ import static org.apache.camel.component.springrabbit.SpringRabbitMQConstants.DI @UriEndpoint(firstVersion = "3.8.0", scheme = "spring-rabbitmq", title = "Spring RabbitMQ", syntax = "spring-rabbitmq:exchangeName", category = { Category.MESSAGING }, headersClass = SpringRabbitMQConstants.class) +@BodyTypes(consumerOut = @BodyType(value = { Carrier.TEXT, Carrier.BYTES }, dependsOn = "messageConverter", + description = "A String when the content type starts with text, as for text this" + + " component sends; a byte array otherwise, JSON and Java serialized objects" + + " too, which are not deserialized"), + consumerReply = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + dependsOn = "messageConverter", + byOption = @BodyType.When(option = "allowNullBody", value = "true", + carriers = { + Carrier.NULL, Carrier.TEXT, Carrier.BYTES, + Carrier.STREAM, Carrier.FILE }), + description = "The reply to a message with a reply-to, converted as the producer" + + " converts a body: a Map or a POJO fails"), + producerIn = @BodyType(value = { Carrier.TEXT, Carrier.BYTES, Carrier.STREAM, Carrier.FILE }, + dependsOn = "messageConverter", + byOption = @BodyType.When(option = "allowNullBody", value = "true", + carriers = { + Carrier.NULL, Carrier.TEXT, Carrier.BYTES, + Carrier.STREAM, Carrier.FILE }), + description = "Text, bytes, a stream or a file, sent as a byte array, text as text/plain" + + " unless the CamelSpringRabbitmqContentType header says another type. A Map" + + " or a POJO fails, as it is not serialized: marshal it first"), + producerOut = @BodyType(value = Carrier.UNKNOWN, + byOption = { + @BodyType.When(option = "exchangePattern", value = "InOnly", + carriers = Carrier.UNCHANGED), + @BodyType.When(option = "disableReplyTo", value = "true", + carriers = Carrier.UNCHANGED) }, + description = "Unchanged for a message that expects no reply (InOnly). A message that" + + " expects one (InOut) gets the body of the reply as the consumer gives it:" + + " a String for a text content type, a byte array otherwise")) public class SpringRabbitMQEndpoint extends DefaultEndpoint implements AsyncEndpoint, EndpointServiceLocation { public static final String ARG_PREFIX = "arg."; diff --git a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java index 620acf8bab55..24da4237401c 100644 --- a/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java +++ b/dsl/camel-yaml-dsl/camel-yaml-dsl-validator/src/test/java/org/apache/camel/dsl/yaml/validator/TextBodyFlowTest.java @@ -1406,6 +1406,91 @@ public class TextBodyFlowTest { .anySatisfy(m -> assertThat(m).contains("to: google-pubsub needs the body as text or bytes")); } + @Test + public void testTheBodyOfMessaging() { + // the paho consumer gives bytes, so a field read needs an unmarshal; pulsar and smtp send what converts to + // bytes or text, so parsed data must be marshalled first, and so must the reply of a nats consumer that answers + // (InOut); the converter of spring-rabbitmq may be set on the component, and an imap mail may be text, a stream + // or a multipart, which say nothing + String yaml = """ + - route: + id: mqtt + from: + uri: paho:orders + steps: + - setHeader: + name: id + simple: ${body[id]} + - route: + id: publish + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: pulsar:persistent://public/default/orders + - route: + id: service + from: + uri: nats:orders + parameters: + exchangePattern: InOut + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - route: + id: listener + from: + uri: nats:events + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - route: + id: rabbit + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: spring-rabbitmq:orders + - route: + id: mail + from: + uri: timer:tick + steps: + - setBody: + constant: '{"id": 1}' + - unmarshal: + json: {} + - to: smtp://[email protected] + - route: + id: inbox + from: + uri: imap://localhost + steps: + - setHeader: + name: id + simple: ${body[id]} + """; + assertThat(lines(yaml)).hasSize(4).anySatisfy(m -> assertThat(m) + .contains("route mqtt: simple reads a field of the body (${body[id]})") + .contains("the paho consumer gives it as bytes")) + .anySatisfy(m -> assertThat(m).contains("to: pulsar needs the body as text, bytes, a stream or a file")) + .anySatisfy(m -> assertThat(m) + .contains("route service:") + .contains("the body at the end of the route is the reply to the nats request")) + .anySatisfy(m -> assertThat(m) + .contains("route mail: to: smtp needs the body as text, bytes, a stream or a file")); + } + @Test public void testTheBodyOfCoreComponents() { // the stream consumer gives each line as text, so a field read needs an unmarshal, and stream:out writes text,
