[ 
https://issues.apache.org/jira/browse/CAMEL-25246?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Claus Ibsen resolved CAMEL-25246.
---------------------------------
    Resolution: Fixed

Merged via https://github.com/apache/camel/pull/27243

> camel-hazelcast - the queue consumer keeps its item listener after stop 
> (events processed twice after a route restart), and in poll mode stops 
> polling for good after one failed poll
> -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25246
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25246
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-hazelcast
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>             Fix For: 4.23.0
>
>
> CAMEL-15899 (3.7) made the Hazelcast consumers register their listener in 
> {{doStart}} and remove it in {{doStop}}, because a listener left behind keeps 
> sending events into a stopped route. The PR changed the list, map, multimap, 
> replicated map, set and topic consumers, but not {{HazelcastQueueConsumer}} 
> nor {{HazelcastInstanceConsumer}}. On main:
> # *Queue consumer, listen mode (the default).* {{doStart}} submits a task 
> that calls {{queue.addItemListener(...)}}; the returned registration id is 
> dropped and {{doStop}} never removes the listener. After the route is 
> stopped, item events are still sent to the stopped route; after a restart 
> (route controller, supervising controller, {{ClusteredRoutePolicy}} / 
> {{master:}} failover, suspend/resume of the route) a second listener is 
> added, and *every queue event is processed twice*, one more time per restart.
> # *Instance consumer.* The membership listener is added in the constructor 
> and never removed (same symptom for cluster membership events).
> # *Queue consumer, poll mode.* The poll loop only catches 
> {{InterruptedException}}. Any other exception from {{queue.poll}} (a 
> Hazelcast client that lost its connection: 
> {{HazelcastClientOfflineException}}, {{TargetDisconnectedException}}; an 
> {{OperationTimeoutException}}) ends the single polling thread silently. The 
> route stays started but never consumes again, and nothing is logged. 
> {{hazelcast-seda}}, which polls a queue the same way, already handles poll 
> errors ({{onErrorDelay}}).
> h3. Reproduction
> Mock-based tests, as the module's other consumer tests:
> * listen mode: start the route, stop it, start it again, fire one item event 
> on the listeners registered on the queue: the route receives it twice 
> ({{Received message count. Expected: <1> but was: <2>}}); after a stop one 
> listener is still registered ({{expected: <0> but was: <1>}});
> * poll mode: the first {{queue.poll}} throws {{HazelcastException}}, then an 
> item is offered: it is never received ({{Expected: <1> but was: <0>}});
> * instance consumer: stopping the route never calls 
> {{removeMembershipListener}}.
> All fail on main, three runs each.
> h3. Proposed fix
> * {{HazelcastQueueConsumer}}: get the queue in {{doStart}}; in listen mode 
> add the item listener there and keep its id, remove it in {{doStop}} (no 
> executor is needed for listen mode any more); in poll mode keep the polling 
> task as is, but catch an exception from {{poll}}, pass it to the consumer's 
> exception handler and poll again after {{pollingTimeout}}.
> * {{HazelcastInstanceConsumer}}: add the membership listener in {{doStart}} 
> and remove it in {{doStop}}.
> No option or API change. {{HazelcastQueueConsumerTest}} is adapted: its mock 
> waited inside {{addItemListener}} for the test method to provide the event 
> (CAMEL-17952 replaced an argument captor with it, because the registration on 
> another thread raced with the test); the registration is now synchronous, so 
> the test captures the listener again. New tests: 
> {{HazelcastQueueConsumerRestartTest}}, 
> {{HazelcastQueueConsumerPollErrorTest}}, 
> {{HazelcastInstanceConsumerTest.testStopRemovesListener}}. The 
> camel-hazelcast suite passes (237 tests; 
> {{HazelcastAggregationRepositoryRoutesTest.checkAggregationFromTwoRoutes}} is 
> a known flake that also fails on main and passes on rerun).
> Affected: 4.14.x, 4.18.x and main (same code; listen mode since CAMEL-11666, 
> poll mode since CAMEL-16035).
> Duplicate check (2026-10-01): JIRA component camel-hazelcast with "listener", 
> "queue consumer", "poll", and text "HazelcastQueueConsumer": only CAMEL-15899 
> (fixed in 3.7 for the other consumers), CAMEL-16035 (null body in poll mode), 
> CAMEL-11666, CAMEL-16018. GitHub pull requests "HazelcastQueueConsumer": only 
> #4901 (CAMEL-16035).
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to