oscerd opened a new pull request, #29078: URL: https://github.com/apache/camel/pull/29078
Fixes [CAMEL-26236](https://issues.apache.org/jira/browse/CAMEL-26236), found while adding the catalog body types (CAMEL-24961). ## 1. ignite-cache consumer: fireExistingQueryResults sends the wrong exchange **Was:** for each entry that the initial query found, `IgniteCacheContinuousQueryConsumer` built an exchange with the value as the body and the key in `CamelIgniteCacheKey`, then processed `createExchange(entry)` instead. Each existing entry arrived as a `javax.cache.Cache.Entry` body without the key header, unlike the events that follow. The code has been like this since the component was added. **Now:** the consumer processes the exchange it built: the value as the body and the key in `CamelIgniteCacheKey`, like the events. ## 2. ignite-cache PUT of a Map: null body, and a Map cannot be stored as one value **Was:** `doPut` put all the entries of a `Map` body, whatever the `CamelIgniteCacheKey` header and `treatCollectionsAsCacheObjects` said, and returned before `IgniteHelper.maybePropagateIncomingBody`, so the body was null after such a PUT. A `Map` could never be stored as one value. **Now:** a `Map` body is put as its entries only when there is no `CamelIgniteCacheKey` header and `treatCollectionsAsCacheObjects` is false. With the header, or with `treatCollectionsAsCacheObjects=true`, the `Map` is stored as the value of the key, like any other body; with `treatCollectionsAsCacheObjects=true` and no header the PUT fails with the existing message, which now mentions the option, as there is no key to store the `Map` under. Both branches keep the body when `propagateIncomingBodyIfNoReturnValue` is true (the default), and leave no body when it is false. ## 3. No operation: NullPointerException (cache, idgen, queue, set) **Was:** the producers switched on the operation of the header, else of the endpoint option, and with neither the switch failed with a `NullPointerException`. **Now:** they fail with an `IllegalArgumentException`: "No operation specified. Set the operation via the operation option of the endpoint or the header CamelIgniteCacheOperation" (with the header of each component), the wording of the state-store producer. The `operation` options stay optional, because the header alone can set the operation per message. `ignite-compute` is not affected, as its `executionType` option is required. ## 4. ignite-idgen: GET and the increments fail on a body they do not use **Was:** the producer converted the body to `Long` before the switch, so `GET`, `GET_AND_INCREMENT` and `INCREMENT_AND_GET` failed with a `TypeConversionException` on text that is not a number, although they ignore the body, and `ADD_AND_GET` or `GET_AND_ADD` without a body failed with a `NullPointerException` on unboxing. **Now:** only `ADD_AND_GET` and `GET_AND_ADD` convert the body. Without a body (or with one that has no conversion to a number) they fail with an `InvalidPayloadException` that says "the ADD_AND_GET operation needs the number to add in the message body". Text that is not a number still fails with the conversion error, as before. ## 5. ignite-compute: null body and the error messages **Was:** `CALL`, `RUN`, `BROADCAST` and `EXECUTE` called `job.getClass()` on the body, so a null body failed with a `NullPointerException`; `EXECUTE` did so even with the `taskName` option, where the body is only the optional argument of the task. The `APPLY`, `AFFINITY_CALL` and `AFFINITY_RUN` errors called `getBody().getClass()` to build their message, so the error itself failed with a `NullPointerException`. `RUN` and `AFFINITY_RUN` have no result, and the body after them was null whatever `propagateIncomingBodyIfNoReturnValue` said. **Now:** without a body every execution type fails with an `InvalidPayloadException` that says what it needs, such as "the CALL executionType needs an IgniteCallable, or a Collection of them, in the message body", except `EXECUTE` with `taskName`, which runs the task with the `CamelIgniteComputeParameters` header as its argument, as the body was documented to be optional there. The `APPLY`, `AFFINITY_CALL` and `AFFINITY_RUN` errors name the type of the body again. `RUN` and `AFFINITY_RUN` keep the incoming body when `propagateIncomingBodyIfNoReturnValue` is true (the default) and leave no body when it is false. ## 6. ignite-queue and ignite-set: ADD, CONTAINS, REMOVE and RETAIN_ALL with no body **Was:** these operations called `body.getClass()`, so a null body failed with a `NullPointerException`. `OFFER` and `PUT` of ignite-queue failed too, with the `NullPointerException` of Ignite ("Argument cannot be null: item"). **Now:** the operations that use the body as the element (`ADD`, `CONTAINS`, `REMOVE` and `RETAIN_ALL`, and `OFFER` and `PUT` of the queue) fail before they touch the queue or set, with an `InvalidPayloadException` that says "the ADD operation needs the element in the message body". `OFFER` and `PUT` are included so that every operation that takes an element fails the same way. ## Tests New tests, with the embedded Ignite node the module tests already use: - `IgniteCacheContinuousQueryTest.testContinuousQueryFireExistingEntriesSendsTheValueWithTheKey` (item 1). - `IgniteCacheTest`: `testPutMapWithKeyStoresTheMapAsOneValue`, `testPutMapTreatCollectionsAsCacheObjectsStoresTheMapAsOneValue`, `testPutMapEntriesPropagatesTheBody` (item 2) and `testNoOperationFails` (item 3). - `IgniteIdGenTest`: `testOperationsThatDoNotAddIgnoreTheBody`, `testAddWithoutBodyFails` (item 4) and `testNoOperationFails` (item 3). - `IgniteComputeTest`: `testNoBodyFails` (every execution type), `testExecuteTaskNameWithoutBodyTakesTheParametersHeader` (with a task that Ignite deploys by its class name), `testAffinityRunKeepsTheBody` and `testRunWithoutPropagateIncomingBodyLeavesNoBody` (item 5). `testRun` expected the null body after `RUN`; it now expects the incoming body. - `IgniteQueueTest` and `IgniteSetTest`: `testOperationsWithAnElementFailWithoutBody` (item 6) and `testNoOperationFails` (item 3). Revert check: without the changes in the producers and the consumer, 16 of the 17 new or changed tests fail, on an assertion or on the old exception (the `NullPointerException`, or the `TypeConversionException` of idgen). The one that passes is `testRunWithoutPropagateIncomingBodyLeavesNoBody`, which checks the behaviour that `propagateIncomingBodyIfNoReturnValue=false` keeps. Module: 63 tests, 0 failures, 0 errors. ## Docs and generated files The `@BodyTypes` of ignite-cache (consumer, PUT input and output), ignite-compute (input, and `RUN` and `AFFINITY_RUN` now keep the body), ignite-idgen and ignite-queue match the fixed behaviour; their component JSON files are regenerated and the catalog copies updated. The cache, compute, idgen, queue and set docs describe the body each operation needs and the failure without an operation, and their catalog copies are updated. The upgrade guide has an entry for the outputs that change: the existing query results, the PUT of a `Map`, and the body after `RUN` and `AFFINITY_RUN`. ## Not changed - A `BROADCAST` of an `IgniteRunnable` has no result either, and still leaves no body: the issue covers `RUN` and `AFFINITY_RUN` only. It could follow the same rule in a follow-up. - The `operation` options are not made required, as routes may set the operation with the header only. - The failures for no operation are thrown from the producer, like the existing failures for a missing key header; the failures for a missing body are set on the exchange as an `InvalidPayloadException`. 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]
