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]

Reply via email to