oscerd opened a new pull request, #27123: URL: https://github.com/apache/camel/pull/27123
Four defects found while auditing `camel-couchbase`, one commit each. The component had no open behavioural Jiras and no non-cosmetic commit since May 2026. ### CAMEL-25169 — the connection was never closed Both the consumer and the producer ended their lifecycle with `client.core().shutdown()`. `Core.shutdown()` returns `Mono<Void>`, and in `core-io` 3.12.3 `shutdown(Duration)` is assembled purely from `Mono.fromRunnable(...)`, `.then(...)` and `Mono.defer(...)` — a cold publisher. The returned `Mono` was discarded, so nothing subscribed and nothing closed. `createClient()` also built a fresh `ClusterEnvironment` **and** a fresh `Cluster` per producer and per consumer, returning only the `Bucket` and dropping the `Cluster` handle — so nothing *could* have closed it. The endpoint now owns one `Cluster`, shared by its producer and consumer, and closes it on stop. Both halves of the close are needed. Camel supplies its own environment via `ClusterOptions.environment(...)`, which `AsyncCluster.extractClusterEnvironment` records as `external` rather than `owned`, and an external environment is **not** shut down by `disconnect()` — its event loops and schedulers would outlive the cluster. So it is `cluster.disconnect()` followed by `environment.shutdown()`. Worth knowing: **CAMEL-11674 (2017) is titled "Couchbase client is never shut down"** and fixed exactly this with `client.shutdown()`, a blocking call on the 2.x SDK. The 3.0.5 upgrade rewrote it to `core().shutdown()` as part of a large API migration. It has been inert for five years. Linked as Related. ### CAMEL-25170 — `connectTimeout` was ignored on its own Both timeouts were configured inside a condition testing only `queryTimeout`, so `connectTimeout` was applied only as a side effect of changing an unrelated option: - `?connectTimeout=1234` alone → the environment reports **`PT10S`** (the SDK's default) - `?connectTimeout=1234&queryTimeout=9999` → **`PT1.234S`** The documented 30000 ms default never applied either. The guard was correct when its body set only `queryTimeout`; `connectTimeout` was folded in later without widening the condition. `connectTimeout` is now applied unconditionally. **`queryTimeout` deliberately keeps its guard**: its documented 2500 ms default is far shorter than the SDK's 75 s, and making it effective would cut short queries that succeed today. That asymmetry is in the upgrade guide rather than left implicit — say the word if you would rather have both applied and the 2500 ms default honoured, but that felt like the wrong default to change quietly. ### CAMEL-25171 — route failures were discarded, after the document had been deleted `processBatch` called `getProcessor().process(exchange)` and ignored the outcome. A failing route does not throw out of `process()` — the failure is left on `exchange.getException()` — and `getExceptionHandler()` appeared **nowhere** in the consumer, so `bridgeErrorHandler` was inert and a failed exchange produced no log line at all. It bites hardest with `consumerProcessedStrategy=delete`, where `removeDocument` runs in the polling loop *before* `processBatch`: by the time the route fails the document is already gone, so the message was lost silently. `processBatch` is a copy of `GenericFileConsumer.processBatch` with the recovery machinery left out — the original keeps a `notStarted` queue and drains both it and the leftover exchanges. The copy kept the `int answer = total` shape but never drained the remainder, so exchanges still queued when `isBatchAllowed()` flips at shutdown were neither processed nor released. Same defect class as CAMEL-25024 in camel-mongodb; linked as Related. ### CAMEL-25172 — `persistTo=2` was rejected The switch covered 0, 1, 3, 4 and skipped 2, so the one value inside the range its own message advertises failed: ``` persistTo=0 -> accepted persistTo=3 -> accepted persistTo=1 -> accepted persistTo=4 -> accepted persistTo=2 -> REJECTED: Unsupported persistTo parameter. Supported values are 0 to 4. Currently provided: 2 ``` `PersistTo.TWO` exists, and the `replicateTo` switch below covers 0–3 with no gap. ### Testing Six new tests, no server required — a mocked `Bucket`/`Cluster` is enough, and `createClusterEnvironment()` is package-private so the timeouts can be read straight back off the environment. **Each fix was revert-checked individually.** Reverting CAMEL-25170 fails both `connectTimeout` tests while `queryTimeoutIsAppliedWhenSet` keeps passing, which is the evidence that the change is confined to the reported defect. Reverting CAMEL-25171 fails both consumer tests; reverting CAMEL-25172 fails on `persistTo=2`; reverting CAMEL-25169 fails the connection test. One note on the consumer tests: `isBatchAllowed()` is `status >= STARTING`, so a batch run against an unstarted consumer skips the loop entirely and any assertion on it passes vacuously. The tests start the consumer with a very long initial delay so the scheduler never polls the mock. My first version of the drain test was green for exactly that wrong reason. Module suite 41/41. Full reactor `mvn clean install -DskipTests -DskipITs` green, no generated drift — no `@UriParam` changed, so the catalog is untouched. ### Backports Proposing **main only** for now. CAMEL-25169 and CAMEL-25172 would be safe on 4.22.x and 4.18.x, but CAMEL-25170 changes an effective default and CAMEL-25171 makes previously invisible failures visible — on an LTS patch release those are behaviour changes a committer should sign off on rather than me labelling them. Happy to prepare the backports for whichever subset you want. 🤖 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]
