davsclaus opened a new pull request, #28914:
URL: https://github.com/apache/camel/pull/28914

   Fixes [CAMEL-26136](https://issues.apache.org/jira/browse/CAMEL-26136).
   
   ### 1. A failed exchange gets no reply with the default codec
   ### 2. A reply that is not a String is dropped and the client waits
   
   **What was wrong:** with the default codec (no `textline`, no custom 
`encoders`/`decoders`) the only encoder is netty's `StringEncoder`. A reply 
that was not a `String` (the muted `Exception` of a failed exchange, bytes, a 
stream, a file, a `Map`, a POJO) passed through it unencoded, the write failed, 
`ServerResponseFutureListener` only logged it, and the client waited (forever 
without `requestTimeout`).
   
   **What changed:**
   - `NettyConfiguration` records when it installed the default String codec 
(`isDefaultStringCodec()`, no new option).
   - `ServerChannelHandler` converts such a reply to a `String` with the type 
converter before writing it, the same as the textline path. A `ByteBuf` reply 
is passed on as before. The conversion is skipped with `transferExchange=true` 
and when a custom `serverInitializerFactory` builds the pipeline 
(camel-netty-http sets one, so it is not affected).
   - When the reply body cannot be built or converted, the consumer now closes 
the TCP channel (not the UDP server channel), so the client does not wait for a 
reply that never comes. The exception still goes to the consumer's exception 
handler.
   
   **Security:** the failed-exchange reply is the `muteException` stand-in, so 
the client receives `java.lang.Exception: Exchange processing failed`, exactly 
what textline clients already get. Only `toString()` is used (class and 
message), never the stack trace. The route's exception is only sent with 
`muteException=false`, which is an opt-in.
   
   ### 3. With useByteBuf=true a File, Map or POJO body is skipped silently
   
   **What was wrong:** `NettyPayloadHelper.getIn` used 
`getBody(ByteBuf.class)`, which returns null for a body that cannot be 
converted. The producer then logged "No payload to send" and completed the 
exchange without error. Also, `getOut` (used for a consumer reply set as the 
out message, the common case) ignored `useByteBuf` altogether.
   
   **What changed:** `getIn` and `getOut` share one helper that uses 
`getMandatoryBody(ByteBuf.class)` when the body is not null. The exchange now 
fails with `InvalidPayloadException`. A null body still means "no payload", as 
before. Both methods now declare `InvalidPayloadException`. The only callers 
are in camel-netty.
   
   ### 4. With sync=false the producer still sets the server's reply on the 
exchange
   
   **What was wrong:** with `sync=false`, `NettyProducer` calls the callback 
once the request is written, but `ClientChannelHandler.channelRead0` still set 
a reply that came later on that exchange. It then also called 
`state.callbackDoneOnce`, which ran the producer callback a second time. Before 
the fix, the test log shows `Error returning channel to pool ... Object has 
already been returned to this pool`.
   
   **What changed:** `ClientChannelHandler.channelRead0` ignores received 
messages (logged at DEBUG) when the producer is not `sync`.
   
   ### Tests
   - `NettyDefaultCodecReplyTest`: failed exchange (muted and 
`muteException=false`), `Map` reply and `byte[]` reply over the default codec. 
All 4 failed before the fix with `ReadTimeoutException`.
   - `NettyUseByteBufTest`: a POJO body fails the producer exchange (before the 
fix: nothing thrown). A consumer reply that cannot be converted closes the 
channel, so the client gets "No response received" at once (before the fix: 
`ReadTimeoutException` after 5s). A String body is still sent.
   - `NettyProducerSyncFalseReplyTest`: the body after a `sync=false` producer 
stays the request (before the fix: `Bye World`, the server's reply).
   - Full camel-netty suite: 146 tests, 0 failures (9 skipped, as on main). The 
camel-netty-http suite (359 tests) also passes against this change. No 
camel-netty-http file is changed.
   
   ### Docs
   - `netty-component.adoc` (and its catalog copy): default-codec reply 
conversion, `useByteBuf` failure, `sync=false` ignoring replies.
   - Upgrade guide 4.24: new section "camel-netty - replies with the default 
codec, useByteBuf and sync=false", next to the existing camel-netty section.
   - No option, header or generated configurer changed.
   
   ### Not changed
   - `ServerResponseFutureListener` still only logs a failed write and does not 
close the channel. camel-netty-http shares it, and with the conversion above 
the default codec no longer fails the write.
   - The producer side with the default codec and a non-String request already 
fails the exchange on the failed write. It is not silent, so it is left as is.
   
   _Claude Code on behalf of Claus Ibsen (davsclaus)_
   
   🤖 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