shashank created CAMEL-25742:
--------------------------------
Summary: camel-coap - an observe=true consumer never cancels its
observation, so after a route stop and start every notification is routed twice
Key: CAMEL-25742
URL: https://issues.apache.org/jira/browse/CAMEL-25742
Project: Camel
Issue Type: Bug
Components: camel-coap
Reporter: shashank
Assignee: shashank
A route {{from("coap://host:5683/sensor?observe=true")}} uses {{CoAPObserver}}.
On start it calls {{client.observe(this)}} (RFC 7641) and drops the returned
{{CoapObserveRelation}}. The class has no {{doStop}} (main 826a664c5f16), so
stopping the consumer does nothing to the observation:
* the server keeps the stopped consumer as an observer, and each notification
is still delivered to it; while the route is stopped each one fails with
{{RouteStoppingException}} and is logged as a WARN by the consumer;
* when the route is started again, Camel creates a new consumer, which observes
the resource a second time. The stopped consumer still holds the route's
processor, which is started again, so from then on each notification is routed
twice, and once more for each further stop / start;
* {{onError}} observes again even after a stop;
* the {{CoapClient}} of a stopped consumer is never shut down.
Trigger: default options, a route with an {{observe=true}} consumer that is
stopped and started again ({{camel cmd stop-route}} / {{start-route}}, JMX /
management, the route controller API). A route reload removes the route
instead; the old consumer's observation is then also left (a WARN per
notification, and a client that is not shut down per reload), but it does not
route into the new route (read, not tested).
h3. Reproduction
New test {{CoAPObserveRestartTest}} (2 tests, Camel CoAP server with an
observable resource in the same JVM, no external service):
* stop and start the observer route, then change the resource once: the
notification must be routed once. On main it is routed twice: {{mock://observed
Received message count. Expected: <1> but was: <2>}} (3 of 3 runs);
* after {{stopRoute("observer")}} the resource must have no observer left,
after {{startRoute}} exactly one. On main the server still holds the stopped
consumer's observation ({{ConditionTimeout ... was not fulfilled within 10
seconds}} at the {{observerCount() == 0}} wait, 3 of 3 runs).
h3. Proposed fix
Keep the relation returned by {{observe}}, and in {{doStop}} cancel it with
{{proactiveCancel()}} (Californium cancels the observation in the client at
once, so a later notification is not delivered, and sends the deregistration to
the server), then shut the client down; {{onError}} observes again only while
the consumer is running. With the fix the camel-coap tests pass: 78 run, 0
failures, 0 errors, 0 skipped.
Not changed: the server side {{CoAPConsumer}} also has no {{doStop}} (a stopped
route keeps answering requests until its path is taken by a new consumer); its
client {{CoapEndpoint}} (socket and threads) is also not destroyed by
{{CoapClient.shutdown()}}. Both are left for a follow-up.
Affected: main (tested); camel-4.23.x, camel-4.22.x, camel-4.18.x and
camel-4.14.x have the same {{CoAPObserver}} without {{doStop}} (read, not run).
The observe consumer exists since CAMEL-19280.
Duplicate check (2026-10-17): JIRA text "CoAPObserver", "coap observe stop",
"coap observe cancel": nothing related. GitHub pull requests "coap observe":
none about the observer lifecycle.
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)