oscerd opened a new pull request, #29067: URL: https://github.com/apache/camel/pull/29067
Fixes [CAMEL-26224](https://issues.apache.org/jira/browse/CAMEL-26224), found while adding the catalog body types (CAMEL-24961). ## 1. The consumer's method header makes the producer do nothing **Was:** `CouchDbConsumer` sets `CamelCouchDbMethod` to `UPDATE` or `DELETE` on each change, and `CouchDbProducer` reads the same header as its method: it saved only without the header and handled only `DELETE` and `GET`. Any other value, such as the consumer's `UPDATE`, fell through both checks, so the exchange succeeded and nothing was written. A route `couchdb:a -> couchdb:b` never saved anything. **Now:** `UPDATE` saves, as no header does: it is the method the consumer sets for an insert or an update, and a save is an insert or an update by the `_rev` of the body. `GET` and `DELETE` work as before, and any other method fails with a `CouchDbException` that names it and lists the methods, instead of doing nothing. `UPDATE` is added to `CouchDbOperations`. Values are still matched without regard to case. A change of a deleted document that reaches the producer with the consumer's `DELETE` failed with a `NullPointerException`, as a change has no `_id` and `_rev`. It now fails with a `CouchDbException` that says the body must hold the `_id` and `_rev` of the document to delete. ## 2. GET needs a valid JSON body it does not use **Was:** `process` parsed the body before it looked at the method, so a `GET` with no body, or with a body that is not JSON, failed with an `InvalidPayloadException`, although `GET` only reads the `CamelCouchDbId` header. **Now:** The body is parsed only to save or delete. `GET` reads the document of the `CamelCouchDbId` header whatever the body is, and sets it as the body as before. ## 3. Invalid JSON text gives a confusing error **Was:** The `JsonSyntaxException` was dropped and the producer threw `new InvalidPayloadException(exchange, body.getClass())`, whose message is `No body available of type: java.lang.String but has type: java.lang.String`. **Now:** It is still an `InvalidPayloadException`, so error handlers that catch it keep working, but it names `JsonElement` as the type it needs, says `the body is not valid JSON`, and has the `JsonSyntaxException` as its cause. The body is not put in the message, as it may hold secrets. An unsupported body type, such as a `Map` or bytes, had the same message naming its own type as the one needed; it now names `JsonElement` and says which bodies the producer takes. ## 4. A JSON array fails with "Could not save document [unknown reason]" **Was:** Only a JSON object was saved. A JSON array, or any JSON that is not an object, made the save return null, and the producer threw `CouchDbException("Could not save document [unknown reason]")`. **Now:** The producer fails before calling CouchDB with a `CouchDbException` that says the body must be one JSON object: for an array, it says to send each document in its own message, for example with the Split EIP. A `DELETE` of a JSON array failed with Gson's `IllegalStateException`, whose message holds the body; it now fails with the same `CouchDbException`, which does not. ## Tests `CouchDbProducerMethodAndBodyTest` uses a mocked `CouchDbClientWrapper` and real exchanges: - A route from a couchdb consumer to a couchdb producer: the consumer polls an update change and hands the exchange, with its `UPDATE` method, to the producer, which saves it and sets `CamelCouchDbId` and `CamelCouchDbRev`. The change of a deleted document fails with the `CouchDbException` and deletes nothing. - An unknown method (`INSERT`) fails and writes nothing. - `GET` reads the document with no body, and with a body that is not JSON. - Invalid JSON text fails with an `InvalidPayloadException` that says the body is not valid JSON, has the `JsonSyntaxException` as its cause, and does not hold the body. - A JSON array, as text and as a Gson `JsonArray`, fails with the message that the body must be one JSON object, and a `DELETE` of an array fails without the body in the message. - A `Map` body fails with an `InvalidPayloadException` that names `JsonElement`. `CouchDbProducerTest.testGetResponse` no longer stubs the body, and checks that `GET` does not read it. Revert check: with the change to `src/main` reverted, the 9 new tests fail, each for its reason: the update change is not saved (`save` is never called), the change of a deleted document fails with a `NullPointerException`, an unknown method throws nothing, `GET` fails with an `InvalidPayloadException` with no body and with a body that is not JSON, invalid JSON has the old message and no cause, a JSON array fails with `Could not save document [unknown reason]`, a `DELETE` of an array fails with an `IllegalStateException`, and a `Map` body names `HashMap` as the type it needs. The changed `CouchDbProducerTest.testGetResponse` fails too, as `GET` reads the body. Module: 25 tests, 0 failures (`CouchDbCrudIT` needs CouchDB in a container and was not run; it sets the method header only to `GET` and `DELETE`). ## Docs and generated files - `@BodyTypes`: the producer body says that a JSON array or invalid JSON fails, that `UPDATE` saves, that `GET` does not read the body, and that another method fails. - The description of the `CamelCouchDbMethod` header lists what the consumer sets and what each method does in the producer. - The component page says which methods the producer takes, what happens in a route from a couchdb consumer to a couchdb producer, and that `GET` does not read the body. - Regenerated `couchdb.json`, and the catalog copies of the JSON and the page. The new header description is also in the generated endpoint DSL. - Upgrade guide entry for 4.24, as `UPDATE` now saves and an unknown method now fails. ## Not changed - Treating any method other than `GET` and `DELETE` as a save, the other reading of the first proposal of the issue, is not done: a misspelt `DELETE` would then save the document. Only `UPDATE`, the value the consumer sets, saves; another value fails, which is the second proposal. - The producer does not ignore the header when the exchange comes from a couchdb consumer: the page documents reading the document of a change by setting `GET` after the consumer, and the consumer's `DELETE` is the same value a user sets. The consumer keeps setting the header, as routes use it to tell updates from deletes. - A route from a couchdb consumer to a couchdb producer saves the change it receives, not the document, as the body of the consumer is the change. When it writes to the database the consumer reads, each save is a new change; the page and the upgrade guide say so. - A JSON array is not saved as several documents (a bulk save would be a new feature). Main only, as the other fixes of the CAMEL-24961 follow-ups. _Claude Code on behalf of Andrea Cosentino (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]
