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)