allthingssecurity opened a new pull request, #28204: URL: https://github.com/apache/camel/pull/28204
# Description [CAMEL-25815](https://issues.apache.org/jira/browse/CAMEL-25815) With `jetstreamEnabled=true` the consumer uses a pull subscription by default, and without `durableName` the JetStream consumer behind it is ephemeral. The NATS server deletes an ephemeral consumer that had no waiting pull request for its inactive threshold (5 seconds by default, once no ack is pending), for example while the client was disconnected for a few seconds before jnats reconnected, and a server restart loses it too. jnats does not give a pull subscription a new consumer: every fetch then ends with an empty list (the pull request has no responder), or once with `409 Consumer Deleted`, which the pull loop logged and continued. The route stayed started and consumed nothing again until it was restarted. Changes (`NatsConsumer`, `DefaultNatsManualAck`): - When a fetch returned nothing, the pull loop asks the server for its consumer (`getConsumerInfo`), at most every 5 seconds. A 404, or a `409 Consumer Deleted` from a fetch, means the consumer is gone. A failed check (not connected, timeout) changes nothing. - When the consumer is gone the loop subscribes again. An ephemeral consumer is created again starting at the first stream sequence the route has not acknowledged (or after the last one fetched): nothing is skipped, and the stream is not replayed from the deliver policy. A durable consumer is created again from its configuration, so it starts where its deliver policy says (with the default `DeliverPolicy.All`, at the start of the stream). It is not given a start sequence: instances that share a durable must all create it with the same configuration (jnats does not bind to an existing consumer whose configuration differs). - To know where to start, the loop keeps the stream sequences it fetched and has not acknowledged yet; an ack by the consumer or through the manual ack header (`ack`, `term`) removes them. What users can notice: after an outage of more than about 5 seconds or a server restart, a pull consumer without `durableName` consumes again (a WARN says it subscribed again and from which stream sequence). A pull consumer with `durableName` whose JetStream consumer was deleted (for example by an administrator) is created again, and with the default deliver policy consumes the stream again from its start, where before it stopped consuming. No option changed; a `camel-nats` note in the 4.24 upgrade guide describes both cases. Tests: - New `NatsConsumerPullConsumerDeletedTest` (2 tests) with a fake JetStream server behind the jnats interfaces the consumer calls. Without the change both fail: after the deletion nothing is routed (`Expected: <2> but was: <0>` and `Expected: <1> but was: <0>`). With the change both pass, and the message acknowledged before the deletion is not routed again. - With the change the camel-nats unit tests pass: 7 run, 0 failures. How it was found: deterministic simulation testing (the camel-test-dst harness of CAMEL-25738). The world runs the real consumer against a fake JetStream server with connection outages and restarts, ephemeral and durable consumers. 274 of 1000 seeds left published messages unrouted on main, all with an ephemeral consumer deleted after an outage or a restart, and 0 of 1000 with this change. The server rule is the one of nats-server `consumer.go` (`JsDeleteWaitTimeDefault`), the client behaviour that of jnats 2.26.4. What was not run: a real NATS server (the integration tests need a container); the full root build. # 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-25815](https://issues.apache.org/jira/browse/CAMEL-25815). # 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 and tested camel-nats. No option and no component page changed. 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]
