shashank created CAMEL-25246:
--------------------------------

             Summary: 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


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