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]
