Federico Mariani created CAMEL-26646:
----------------------------------------
Summary: camel-couchdb - maxMessagesPerPoll 0 or negative,
documented as unlimited, is sent as the CouchDB _changes limit
Key: CAMEL-26646
URL: https://issues.apache.org/jira/browse/CAMEL-26646
Project: Camel
Issue Type: Bug
Components: camel-couchdb
Affects Versions: 4.18.5, 4.23.0, 4.22.2
Reporter: Federico Mariani
h3. Problem
The couchdb consumer documents {{maxMessagesPerPoll}} as "The default value is
10. Use 0 or a negative number to set it as unlimited"
({{components/camel-couchdb/src/main/java/org/apache/camel/component/couchdb/CouchDbEndpoint.java}}
lines 296-303 on main, commit 7978db3d42dd, and the catalog/component docs).
The value is never checked for 0 or a negative number. It is passed straight to
CouchDB as the {{limit}} of the {{_changes}} request
({{CouchDbClientWrapper.java}} lines 92-99, called from
{{CouchDbConsumer.java}} line 78):
{code:java}
PostChangesOptions postChangesOptions = new PostChangesOptions.Builder()
.db(dbName)
.since(since)
.limit(maxMessagesPerPoll)
.build();
{code}
The Cloudant SDK (0.10.22) adds the {{limit}} query parameter whenever it is
set. CouchDB does not treat 0 or a negative limit as "no limit":
* *0*: CouchDB returns no changes. The consumer never moves {{since}}, so every
poll is empty forever. Nothing is logged, and the route looks healthy.
* *negative*: CouchDB answers HTTP 400 {{bad_request: The limit value should be
a non-negative integer}}, so every poll fails.
h3. How to reproduce
Measured against CouchDB 3.5.3 ({{mirror.gcr.io/couchdb:3.5.3}}, the test-infra
image). The test creates the consumer of
{{couchdb:http://<host>:<port>/<db>?username=admin&password=...&createDatabase=true&maxMessagesPerPoll=<n>}},
which reads the latest update sequence of the database. It then saves five
documents with the couchdb producer and calls {{CouchDbConsumer.poll()}} once:
||maxMessagesPerPoll||poll() result||
|10 (default, control)|5 changes|
|0|0 changes, although 5 are waiting|
|-1|{{com.ibm.cloud.sdk.core.service.exception.BadRequestException:
bad_request: The limit value should be a non-negative integer}}|
The same holds for plain {{POST /db/_changes}} on a database with 12 documents.
{{limit=0}} gives 0 results and {{limit=-1}} / {{limit=-5}} give HTTP 400.
{{limit=3}} gives 3, and no {{limit}} gives 12. The CouchDB documentation of
{{_changes}} does not say what 0 or a negative limit does; the numbers above
are what the server returned.
h3. Proposed change
* In {{CouchDbClientWrapper.pollChanges}}, call {{.limit(...)}} only when
{{maxMessagesPerPoll > 0}}. With 0 or a negative value, the request then has no
limit, which is the documented "unlimited". All the changes since the last
{{since}} come back in one response and are processed in that poll.
* Add a unit test with a mocked {{Cloudant}} client that captures the
{{PostChangesOptions}}: {{limit()}} must be null for 0 and -1, and 10 by
default.
* Optional cleanup: the Javadoc of {{setMaxMessagesPerPoll}} repeats its first
sentence twice (this text is also the catalog description).
h3. Impact / upgrade
* The default (10) does not change, and nothing changes for positive values. No
upgrade-guide entry is needed: 0 and negative values change from "nothing is
ever received" / "every poll fails" to the documented behaviour.
* Only the consumer is affected; the producer does not use the option.
* The Camel code is the same on camel-4.18.x, camel-4.22.x and main, and in the
released 4.7.0, 4.18.5, 4.22.2 and 4.23.0 tags, so this is a backport candidate
for both LTS branches. The server reproduction was run on main only.
h3. Related
* Introduced in 4.7.0 by CAMEL-20800 (commit 77b58e811ead, "Use cloudant
instead of LightCouch"). That commit added {{maxMessagesPerPoll}} together with
this Javadoc; before it, the component had no such option.
* CAMEL-25290 (PR #27322): an earlier fix in the same {{poll()}} (skipped
changes did not move {{since}}).
* CAMEL-26224 (PR #29067): the latest couchdb change; it does not touch this
path.
_Claude Code on behalf of Federico Mariani_
--
This message was sent by Atlassian Jira
(v10.3.26#10030026)