Andrea Cosentino created CAMEL-25160:
----------------------------------------
Summary: camel-mongodb - harden the persistent tail tracking
manager
Key: CAMEL-25160
URL: https://issues.apache.org/jira/browse/CAMEL-25160
Project: Camel
Issue Type: Bug
Components: camel-mongodb
Reporter: Andrea Cosentino
Assignee: Andrea Cosentino
h3. Summary
Two small robustness problems in {{MongoDbTailTrackingManager}}, both on the
persistent tail tracking
path ({{persistentTailTracking=true}}).
h3. The update filter grows, defeating the stated optimisation
{{initialize()}} deliberately reduces the tracking document to its id:
{code:java}
// keep only the _id, the rest is useless and causes more overhead during update
trackingObj = new Document(MONGO_ID, trackingObj.get(MONGO_ID));
{code}
and {{persistToStore()}} immediately undoes it, because it stores the full
updated document back:
{code:java}
FindOneAndUpdateOptions options = new
FindOneAndUpdateOptions().returnDocument(ReturnDocument.AFTER);
trackingObj = dbCol.findOneAndUpdate(trackingObj, updateObj, options);
{code}
>From the first persist onwards the filter is {{{_id, <field>: <previous
>value>}}} rather than
{{{_id}}}. That is self-consistent for a single writer, but if anything else
changes that field - two
routes configured with the same {{persistentId}}, or an external writer - the
update matches nothing,
{{findOneAndUpdate}} returns {{null}}, and the *next* call passes a null filter.
That throws from the {{finally}} of {{MongoDbTailingThread.doRun()}}, which
lands in the consumer
thread's catch, regenerates the cursor and persists again: the same
non-terminating shape as
CAMEL-25025.
h3. recoverFromStore does not guard against a missing document
{code:java}
lastVal = dbCol.find(trackingObj).first().get(config.field);
{code}
{{first()}} returns {{null}} if the tracking document has gone between
{{initialize()}} and this call.
h3. Proposed fix
Keep filtering by {{_id}} only, and null-guard the recovery read. Note also
that the {{ReentrantLock}} in
this class guards state that only the single consumer thread touches, so it is
redundant rather than
wrong - worth leaving alone unless it is confusing.
----
_Reported by Claude Code on behalf of oscerd (Andrea Cosentino)._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)