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

   # Description
   
   [CAMEL-26046](https://issues.apache.org/jira/browse/CAMEL-26046)
   
   With `enableRetry=true`, `CommonCreationStrategyImpl.getBuilder` builds the 
`DeadLetterPolicy` with `maxRedeliverCount` and `retryLetterTopic`, but not 
with `deadLetterTopic`. Only the branch without retry mode copies it. The 
option says "Name of the topic where the messages which fail maxRedeliverCount 
times will be sent". In pulsar-client 4.2.4, 
`ConsumerBuilderImpl.subscribeAsync` in retry mode replaces a blank dead letter 
topic of the policy with its default, `<topic>-<subscription>-DLQ`, or 
`<subscription>-DLQ` when that older topic already exists. A non-blank one is 
kept. So with `enableRetry=true` a message that failed `maxRedeliverCount` 
times (Camel negatively acknowledges a failed exchange) goes to the default 
topic instead of the configured one. A route that reads the configured dead 
letter topic never sees it. Since CAMEL-17840 added retry mode.
   
   A second problem in the same branch: with `enableRetry=true` and no 
`maxRedeliverCount`, the `Integer` option is unboxed into 
`DeadLetterPolicyBuilder.maxRedeliverCount(int)`, so the consumer fails to 
start with a `NullPointerException` that does not name the option.
   
   Changes:
   - In retry mode the configured `deadLetterTopic` is set on the policy, as it 
already is without retry mode.
   - In retry mode without `maxRedeliverCount` the consumer no longer creates a 
policy, as the option description says ("If this value is not set, no Dead 
Letter Policy will be created"), so it starts instead of failing with the NPE. 
The Pulsar client then applies its own policy in retry mode: in pulsar-client 
4.2.4 `ConsumerBuilderImpl.subscribeAsync` builds 
`DeadLetterPolicy.builder().maxRedeliverCount(16).retryLetterTopic(<default>).deadLetterTopic(<default>)`
 when the policy is null (read with javap). As without retry mode, 
`retryLetterTopic` and `deadLetterTopic` only apply when `maxRedeliverCount` is 
set. I chose this over failing the start, as it follows both the option 
description and the client default; I can make a topic without a count fail 
instead if preferred.
   - Without retry mode nothing changes.
   - Upgrade guide (4.24): the dead letter topic now applies in retry mode. 
Messages already in the default topic stay there. Retry mode without 
`maxRedeliverCount` now starts with the client's defaults.
   - No option or generated file change.
   - Backport: camel-4.23.x, 4.22.x and 4.18.x have the same code.
   
   Tests:
   - New `CommonCreationStrategyImplTest`, 6 tests, JUnit assertions as in the 
module. It calls `getBuilder` with a mocked endpoint whose client is a real 
`PulsarClient` (`pulsar://localhost:6650`, which does not connect before a 
subscribe). It reads the `ConsumerConfigurationData` of the real 
`ConsumerBuilderImpl`, so the Pulsar client's own builder checks apply, for 
example `MaxRedeliverCount must be > 0`.
   - `retryModeUsesTheConfiguredDeadLetterTopic` fails on main: `the dead 
letter topic must be passed to the Pulsar client in retry mode ==> expected: 
<persistent://public/default/my-dlq> but was: <null>`.
   - `retryModeWithoutMaxRedeliverCountLeavesThePolicyToThePulsarClient` and 
`retryModeWithoutMaxRedeliverCountIgnoresTheTopicsAsWithoutRetryMode` fail on 
main with the `NullPointerException` from `getBuilder` (`Cannot invoke 
"java.lang.Integer.intValue()" ...`). With the fix retry mode is enabled and no 
policy is set.
   - `retryModeWithoutTopicsLeavesTheDefaultsToThePulsarClient`, 
`deadLetterTopicModeIsUnchanged` and 
`noMaxRedeliverCountWithoutRetryModeCreatesNoPolicy` are controls that pass on 
main and with the fix.
   - Unit tests of camel-pulsar with the fix: 40 run, 0 failures, 0 skipped. 
The integration tests need a Pulsar container and were not run locally (CI runs 
them). `PulsarConsumerDeadLetterPolicyIT` covers the dead letter topic without 
retry mode. I can add a retry-mode case there if wanted.
   - The formatter and import-sort plugins ran. I built offline with 
`-Dasm-version=9.11` because asm 9.11.1 was not in my local repository.
   
   # Target
   
   - [x] I checked that the commit is targeting the correct branch (Camel 4 
uses the `main` branch)
   
   # Tracking
   - [x] If this is a large change, bug fix, or code improvement, I checked 
there is a [JIRA issue](https://issues.apache.org/jira/browse/CAMEL) filed for 
the change (usually before you start working on it): 
[CAMEL-26046](https://issues.apache.org/jira/browse/CAMEL-26046).
   
   # Apache Camel coding standards and style
   
   - [x] I checked that each commit in the pull request has a meaningful 
subject line and body.
   - [ ] I have run `mvn clean install -DskipTests` locally from root folder 
and I have committed all auto-generated changes.
     (I built camel-pulsar and ran its unit tests, including the formatter and 
import-sort plugins. No generated file changes. I did not run the full root 
build.)
   
   # AI-assisted contributions
   
   - [x] If this PR includes AI-generated code, commits have proper 
co-authorship attribution (e.g., `Co-authored-by` trailers) and the PR 
description identifies the AI tool used.
     This PR was prepared with Claude Code (Claude Opus 5.5). The commit 
carries a `Co-Authored-By` trailer.
   
   _Claude Code on behalf of allthingssecurity_
   
   🤖 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