davsclaus opened a new pull request, #28394:
URL: https://github.com/apache/camel/pull/28394
_Claude Code on behalf of davsclaus_
This group adds the catalog body types (CAMEL-24961) for twelve messaging
components: sjms, sjms2, rocketmq, hivemq, iggy, kafka-share, xmpp, pubnub,
disruptor, disruptor-vm, vertx and reactive-streams. Each change is only an
`@BodyTypes` annotation on the Endpoint, plus the JSON it generates and the
catalog copy. Three doc pages had their body text corrected.
**What the catalog says now**
| Component | Consumer | Producer input | Producer output |
|---|---|---|---|
| sjms, sjms2 | a `String` for a TextMessage, a `byte[]` for a BytesMessage,
a Map for a MapMessage, the `StreamMessage` itself, null for a plain Message;
the `jakarta.jms.Message` with mapJmsMessage=false; an InOut reply is sent as
the producer sends | text as a TextMessage; bytes, a stream or a file as a
BytesMessage; a Map as a MapMessage; null as an empty Message; a number or a
List only with objectMessageEnabled | unchanged for InOnly; the reply for InOut
|
| rocketmq | `byte[]`, no reply | text, bytes, a stream or a file |
unchanged; the reply as `byte[]` with InOut and replyToTopic |
| hivemq | `byte[]` | text, bytes, a stream or a file; no body is an empty
payload | unchanged |
| iggy | a `String`, decoded with the default charset of the JVM | `any`,
converted to text; a List of String or of Iggy `Message` sends one message each
| unchanged |
| kafka-share | a `String` (null for a tombstone); `byte[]` with
ByteArrayDeserializer | | |
| xmpp | the chat text; the Smack `Message` with doc, or when the message
has no body text | `any`, converted to text; a Smack Stanza with doc, a
`PubSub` packet with pubsub | unchanged |
| pubnub | `PNMessageResult` (`PNPresenceEventResult` too with withPresence)
| text, a value, a Map, a List or a POJO, serialized to JSON; a Map or a POJO
for SETSTATE; not read by the other operations | unchanged for PUBLISH and
FIRE; a List for GETHISTORY; the result object of the client for GETSTATE,
HERENOW and SETSTATE |
| disruptor, disruptor-vm | the body the producer sent | `any` | unchanged
for InOnly or waitForTaskToComplete=Never; the body the route ends with for
InOut (as seda) |
| vertx | what the sender sent on the event bus: a String, bytes, a number,
a JsonObject or JsonArray, or a Serializable object; the reply needs a codec
too | the same, sent as is with its codec; a stream, a POJO that is not
Serializable, or no body fails | unchanged for InOnly; the reply for InOut |
| reactive-streams | what the publisher emits; a caller of toStream gets the
body the route ends with | `any` | unchanged |
**Checked at runtime.** Each component ran in throwaway tests that sent
text, bytes, a stream, a file, a Map, a POJO, a number and no body. The tests
logged the class of the body after each step and are not part of the PR. Where
to was checked:
- **Docker:** Kafka 4.3.1 (kafka-share), HiveMQ CE 2026.5 (MQTT 5 and
3.1.1), Iggy 0.9.0, RocketMQ 5.3.3.
- **Embedded:** Artemis for sjms and sjms2, with InOnly and InOut; Vert.x
5.2.1; the reactor engine for reactive-streams.
- **Fakes:** the `FakeXmppServer` of the xmpp tests, and WireMock for
pubnub. pubnub's history, state, here-now and presence results come from its
existing tests.
Not run: sjms with objectMessageEnabled=true, an xmpp message without body
text, and the xmpp group chat producer.
**Choices**
- sjms differs from camel-jms in one place: a StreamMessage is not read into
a stream, so the body is the `StreamMessage` itself.
- sjms2 repeats the annotation of sjms, because a subclass does not inherit
the body types of its parent.
- disruptor and disruptor-vm share one Endpoint class. Both copy the body
types of seda.
- The consumer of vertx is `unknown`: the sender can be any Vert.x code,
with its own codecs.
- The consumer of reactive-streams is `unknown`: it is whatever the
publisher emits.
- pubnub leaves bytes out of the producer: they are sent as a JSON array of
numbers.
- hivemq lists no body as an input, because an empty payload is intended,
and its tests check for it.
**Doc fixes**
- sjms, sjms2: the "Message Content" section described the rule for the
values of headers as if it were the rule for the body. It now says it is about
headers, and has a table of how a body maps to a JMS message and back.
- vertx: the page said that the event bus "sends and receives JSON events".
It now lists the types the codecs take, and says that the body is sent without
type conversion.
PR #27173 (sjms batch) also changes `SjmsEndpoint` and the sjms page. This
PR only adds the annotation and touches the "Message Content" section, so a
rebase of either one should only need the generated files regenerated.
**Bugs found, not fixed here.** The JIRAs, one per component, will follow.
- **sjms** (sjms2 inherits the code):
- `jmsMessageType=Stream` fails with a NullPointerException on send,
because `JmsBinding.createJmsMessageForType` has no Stream case.
- An InOut reply that cannot be sent is dropped without a log, and the
caller times out. Examples are a number, a List, or a Serializable object
without objectMessageEnabled. `EndpointMessageListener.onMessage` only rethrows
a `RuntimeCamelException`.
- A body that is not Serializable and does not convert is sent as an empty
Message, with only a WARN.
- **hivemq:** the producer uses a conversion that is not mandatory, so a
Map, a POJO or a number is published as an empty payload, with no error.
camel-paho fails instead.
- **iggy:**
- The producer converts a `byte[]` to a String, which corrupts a binary
payload (`ff fe 00 41` was stored as `ef bf bd ef bf bd 00 41`).
- The consumer decodes with the platform charset.
- No body fails with a NullPointerException, and an empty List with
"Cannot encode an empty message batch".
- camel-test-infra-iggy cannot start the 0.9.0 image: it needs
`IGGY_NODE_ADVERTISED_ADDRESS` and `IGGY_SHARDING_CPU_ALLOCATION`.
- **rocketmq:**
- With the default waitForSendResult=false, `processInOnly` returns `true`
and then calls `callback.done(true)` later, from the send callback. This was
read from the code, not run.
- The test-infra broker advertises the IP of its container, which a Docker
Desktop host cannot reach.
- The tests are skipped on aarch64, but the image runs there.
- **pubnub:**
- `doFire` and `doSetState` set the exception of an empty body but do not
return, so the operation still runs and the callback can be called twice.
- `PNMessageResult` has no type converter, so `${body}` gives
`PNMessageResult@hash`.
- **vertx:**
- When the body the route ends with has no codec (a stream, a POJO that is
not Serializable), the reply fails without a log, and the requester times out.
A Buffer request that the route does not change is the common case, as stream
caching makes it a stream.
- pubSub=true is ignored for InOut.
- A null body fails with the misleading "No body available of type:
java.lang.String".
- **reactive-streams:** the producer leaves the
`CamelReactiveStreamsCallback` header, a lambda, on the message.
**Local checks**
- The changed modules build, with no change to the generated files after the
build.
- The catalog copies equal their modules.
- camel-catalog, camel-yaml-dsl-validator and camel-jbang-core tests pass.
- The Endpoint and Component DSLs regenerate with no change.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]