davsclaus opened a new pull request, #28395:
URL: https://github.com/apache/camel/pull/28395
_Claude Code on behalf of davsclaus_
This group adds the catalog body types (CAMEL-24961) for twelve HTTP,
WebSocket and web service components: netty, netty-http, jetty, servlet,
undertow, vertx-websocket, atmosphere-websocket, webhook, cxf, cxfrs, spring-ws
and rest-postman. Each change is an `@BodyTypes` annotation on the Endpoint,
plus the JSON it generates and the catalog copy. Five doc pages had their body
text corrected.
**What the catalog says now**
| Component | Consumer | Reply of the consumer | Producer input | Producer
output |
|---|---|---|---|---|
| netty | a `String` (the default codec has no TCP framing: textline=true
gives one line each); `byte[]` with udpByteArrayCodec; a `ByteBuf` with
allowDefaultCodec=false | a String or a ByteBuf; any body with textline; no
body closes the connection | a String, or a ByteBuf over TCP; any body with
textline | the reply as a String (sync, the default); unchanged with sync=false
|
| netty-http | the request as a stream cache that can be read again; a
ByteBuf with disableStreamCache | text, bytes, a stream, a file or a value; no
body gives 204 | text, bytes, a stream or a file | the response as `byte[]` |
| jetty, servlet | the request as a stream cache (the raw stream with
disableStreamCache); empty for a GET; null for Content-Length 0 | text, bytes,
a stream or a file | | |
| undertow | HTTP: `byte[]` for POST, PUT and PATCH, null for the other
methods, a Map for a form; WebSocket: a String or `byte[]` | HTTP: text, bytes,
a stream or a file | HTTP: text, bytes, a stream or a file; WebSocket: to the
peers of the endpoint | HTTP: the response as `byte[]`; WebSocket: unchanged |
| vertx-websocket | a String for a text frame, `byte[]` for a binary one;
the `ServerWebSocket` for the OPEN event | | a String as text, `byte[]` as
binary, other bodies as their toString | unchanged |
| atmosphere-websocket | a String or `byte[]`; InOnly, no reply | | text or
a Reader as text, bytes or an InputStream as binary | unchanged |
| webhook | `unknown`: what the webhook handler of the delegate makes of the
request | `any`: the delegates set the response themselves | | |
| cxf | by dataFormat: POJO a `MessageContentsList` of the parameters;
PAYLOAD a `CxfPayload`; RAW the stream of the envelope; CXF_MESSAGE a
`SOAPMessage` | by dataFormat: the return value; the XML of the body; the
envelope; a SOAPMessage or a Source | by dataFormat, as the reply | by
dataFormat, as the consumer |
| cxfrs | Default binding: a `MessageContentsList`; SimpleConsumer: the
entity as the method declares it | a `Response`, text, bytes, a stream, a file,
or a bean that a JAX-RS provider writes | the entity; the parameters of the
method with httpClientAPI=false | a `jakarta.ws.rs.core.Response`; the return
value of the method with httpClientAPI=false |
| spring-ws | the payload as a `Source` (format xml) | XML as text, bytes, a
stream, a Source or a DOM | the same | the response as a `Source`, or null |
| rest-postman | the request body, as platform-http gives it to
`direct:<requestId>` | text, bytes or a stream | one request: text, bytes, a
stream or a file; a folder or the whole collection ignores the body | one
request: the response stream; a folder or a collection: a List of
`PostmanRunResult` |
Where an HTTP server answers with a Map, a List or a POJO, the description
says to marshal it first, as it does for platform-http.
**Checked at runtime.** The throwaway tests below are not part of the PR.
- netty: real TCP and UDP sockets.
- jetty, servlet (in the Undertow servlet container), undertow,
atmosphere-websocket and netty-http: a `java.net.http` client and WebSocket.
- vertx-websocket: as server and as client.
- cxf: all four data formats, as consumer, reply and producer.
- cxfrs: the Default and SimpleConsumer bindings, and the HTTP and proxy
APIs.
- spring-ws: an in-memory message sender.
- rest-postman: WireMock behind the producer, and platform-http-vertx for
the consumer.
The tests sent text, bytes, a stream, a file, a Map, a List, a POJO, a
number and no body, and logged the class of the body after each step.
Not run:
- the transferException deserialization and custom bindings or codecs;
- chunked netty-http messages and protocol=proxy;
- performInvocation and the Custom binding of cxfrs;
- one-way SOAP operations;
- atmosphere events;
- a real webhook delegate (read from the Telegram, ClickUp and WhatsApp
handlers).
**Choices**
- undertow has HTTP and WebSocket under one scheme, picked by the URI. So
each side describes both, and the producer output mixes `bytes` and
`unchanged`, as sql and jdbc do.
- cxf repeats the RAW entries for MESSAGE, which is an alias of RAW.
- The consumer of webhook is `unknown`, as the delegate component decides
its body.
**Doc fixes**
- jetty, servlet, netty-http: the "Stream" note said that the body can be
read only once. By default the consumer gives a stream cache, which can be read
again; only disableStreamCache gives the raw stream. The netty-http producer
gives a `byte[]`.
- cxf: the class is `org.apache.camel.component.cxf.common.CxfPayload`.
- cxfrs: `jakarta.ws.rs.core.Response`, not `javax`.
Open PRs that change these modules (#21800, #22358, #28337, #28352, #28357,
#28366, #28369, #28377) do not touch the Endpoint classes or the generated
files of this PR.
**Bugs found, not fixed here.** The JIRAs, one per component, will follow.
- **netty:**
- With the default codec, a failed exchange gets no reply (the exception
cannot be encoded), and the client times out. With textline the client gets the
error.
- A reply that is not a String (bytes, a stream, a file, a Map or a POJO)
is dropped with a WARN, and the client waits, without end when there is no
requestTimeout.
- useByteBuf=true skips a File, a Map or a POJO with no error ("No payload
to send").
- A producer with sync=false still sets the reply of the server on the
exchange after the producer has completed.
- **netty-http:**
- A List reply sends no response and keeps the connection open.
- With disableStreamCache=true, a route that ends with the request ByteBuf
fails with `IllegalReferenceCountException`, and the client gets no response.
- sync=false still puts the response on the exchange.
- **jetty, servlet** (DefaultHttpBinding of camel-http-common):
- With chunked=true, the default, a reply of a Map, a List, a POJO or a
number gives 200 with an empty body and no error.
- mapHttpMessageBody=false still maps the body.
- With disableStreamCache=true, the body of a form POST has already been
read by the mapping of the form fields: servlet answers 500 "Stream is closed",
jetty gives an empty body.
- **servlet:** attachmentMultipartBinding=true fails every request that is
not multipart, with 500 "Cannot populate attachments".
- **undertow:**
- A reply of a Map, a List or a POJO gives an empty 200, with only a WARN.
- An Integer reply or producer body is sent as 4 binary bytes, not as "42".
- The producer sends a Map, a List or a POJO as an empty POST, with no
error.
- The consumer drops the body of a DELETE and of the other methods that
are not POST, PUT or PATCH.
- The producer gives an empty `byte[]`, not null, for a 204.
- **atmosphere-websocket:**
- `WebsocketConsumer.getQueryMap` uses `nameval[1]`, so a query parameter
without `=` fails with an ArrayIndexOutOfBoundsException. This was read from
the code.
- useStreaming is documented for sending, but only the consumer uses it.
- **cxf:**
- A POJO reply (and a CXF_MESSAGE reply) of a `byte[]` gives the SOAP
fault "class [B cannot be cast to class [Ljava.lang.Object;".
`DefaultCxfBinding.populateOutBody` checks `isArray()` and then casts to
`Object[]`.
- The POJO producer splits a body that is not a List: "Hello,World"
becomes 2 parameters, and a `byte[]` one per byte.
- A CXF_MESSAGE producer sends an empty envelope for a String, `byte[]`,
stream or DOM Document body, with no error; a reply of text, a stream or a
Document does the same.
- A Map or null reply gives an empty soap:Body in PAYLOAD, and an empty
response in RAW, instead of a fault.
- **cxfrs:**
- With the Default binding, a route that leaves the request body gives 500
"No message body writer has been found for class MessageContentsList".
- The producer of the HTTP API sends only the first element of a List body.
- **spring-ws:**
- A route that ends with a null body sends the request payload back as the
response.
- A reply that does not convert to a Source (a Map, a raw stream) gives an
empty SOAP body without a fault.
- The producer rejects a `File`, and a raw `InputStream` without stream
caching.
**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]