oscerd opened a new pull request, #27116:
URL: https://github.com/apache/camel/pull/27116

   Two defects from a second pass over `camel-mongodb`, a commit each.
   
   ## CAMEL-25159 — `findAll`, `distinct` and `aggregate` ran their query twice
   
   All three had this shape:
   
   ```java
   try {
       ret.iterator().forEachRemaining(result::add);
       exchange.getMessage().setHeader(RESULT_PAGE_SIZE, result.size());
   } finally {
       ret.iterator().close();
   }
   ```
   
   `MongoIterable.iterator()` is not an accessor for an already-open cursor — 
it **executes**. From
   `mongodb-driver-sync` 5.9.2:
   
   ```java
   public MongoCursor<T> iterator() {
       return new MongoBatchCursorAdapter<>(execute());
   }
   ```
   
   So the `finally` opened a *second* cursor — another round trip, and for 
`aggregate` a second run of the
   whole pipeline — closed that one, and left the cursor that had actually been 
read unclosed. If
   `forEachRemaining` threw part-way, that first cursor leaked outright.
   
   Now a held cursor in try-with-resources: the query runs once, and the cursor 
that is read is the one that
   is closed. Affects `findAll` and `aggregate` whenever `outputType` is not 
`MongoIterable`, and `distinct`
   always.
   
   ## CAMEL-25160 — the tail tracker undid its own optimisation, and could wedge
   
   `initialize()` reduces the tracking document to its id on purpose:
   
   ```java
   // keep only the _id, the rest is useless and causes more overhead during 
update
   trackingObj = new Document(MONGO_ID, trackingObj.get(MONGO_ID));
   ```
   
   and `persistToStore()` immediately undid it by storing the full 
`findOneAndUpdate(..., AFTER)` result
   back. From the first persist onwards the filter also matched on the previous 
value. That is
   self-consistent for a single writer, but anything else touching the field — 
two routes sharing a
   `persistentId` — leaves the update matching nothing, `trackingObj` null, and 
the *next* persist throwing
   from the `finally` of `doRun()`, which lands in the consumer thread's catch, 
regenerates the cursor and
   persists again. That is the non-terminating shape of CAMEL-25025, which is 
why the issues are linked.
   
   Filter on the id only, and null-guard the recovery read, which previously 
dereferenced `first()`
   unguarded.
   
   ## Tests
   
   `MongoDbProducerCursorTest` drives all three operations through a mocked 
`MongoClient` chain and asserts
   `verify(iterable, times(1)).iterator()`. The endpoint starts as long as 
`mongoConnection` is supplied, so
   no server is needed.
   
   Revert-checked one site at a time: restoring the old `finally` on `distinct` 
alone fails exactly
   `testDistinctOpensOneCursor` with *wanted 1 time but was 2 times*, while the 
other two keep passing.
   
   **This adds `mockito-core` in test scope**, which is the one thing here 
worth a second opinion. A call
   count is the only way to prove this fix, the module had no mocking library, 
and mockito-core is already
   the convention in sibling components (`camel-pulsar`, 
`camel-debezium-common`). If you would rather not
   take the dependency, the fix stands on the driver evidence and the existing 
ITs cover the functional
   path — say so and I will drop the test rather than argue for it.
   
   No upgrade-guide entry: neither change alters a user-visible contract, just 
one fewer round trip and
   tail-tracking persistence that behaves identically for the single-writer 
case it was already restricted
   to.
   
   Module suite green (18 tests); full reactor `mvn clean install -DskipTests 
-DskipITs` green with no
   generated drift.
   
   _Claude Code on behalf of oscerd_
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to