davsclaus opened a new pull request, #28942: URL: https://github.com/apache/camel/pull/28942
Fixes [CAMEL-26159](https://issues.apache.org/jira/browse/CAMEL-26159). ### 1. A Map or POJO body on a REST operation was sent as its toString `JsonRestProcessor.getRequestStream(Exchange)` tried `InputStream`, then `AbstractDTOBase`, then fell back to `getBody(String.class)`. A `Map` or any object that is not a DTO was sent as its `toString()`, e.g. `{Name=x}` for `createSObject`, with no error. Now a non-null body that is not text or a simple value (`CharSequence`, `Number`, `Boolean`, `Character`, `Enum`) is marshalled with the processor's `objectMapper`, as is done for DTOs. Text, bytes, streams and files still take the `InputStream` path and are sent as is. `apexCall` is unchanged: it still takes a `Map` body as query parameters. (I first tried to decide "text" by looking up a type converter to `String`, but the registry lookup matches `LinkedHashMap` through the `JsonObject` converters, so an explicit list of simple types is used.) ### 2. raw with a Map body sent a POST with an empty body `RawProcessor` read the body with `getBody(InputStream.class)`, which is `null` for a `Map`, so the request went out empty. A non-null body is now read with `getMandatoryBody(InputStream.class)`, so the exchange fails with an `InvalidPayloadException`. The raw operation still does no serialization, as documented; a null body still sends no body. ### 3. SObject Collections: an unparseable response completed the exchange silently `CompositeSObjectCollectionsProcessor.processResponse` called `responseBody.get()` on an empty `Optional` when the response could not be parsed. The `NoSuchElementException` was thrown on the HTTP client thread and the `finally` still called `callback.done(false)`, so the exchange completed with no exception. It now sets a `SalesforceException` when the response is empty or not valid JSON. ### 4. rawPayload description The option description said the raw payload is a `String` (JSON or XML depending on `format`). It now says the REST, apexCall and composite operations return the response as an `InputStream`, and the streaming subscribe consumer gives JSON text. ### Tests - `JsonRestProcessorTest`: a `Map` and a plain POJO are marshalled as JSON (both failed before), and text (a `String`, a `Reader`) is still sent as is. - New `ProducerRequestBodyTest` against the module's okhttp `MockWebServer`: `createSObject` with a `Map` posts `{"Name":"x"}`, `raw` with a `Map` fails with `InvalidPayloadException` and sends nothing, and `compositeCreateSObjectCollections` with a non-JSON response fails with a `SalesforceException`. All three failed before the fix. - Full module unit test suite: 196 tests, 0 failures (`mvn clean install -Psourcecheck`). ### Docs and generated files - `@BodyTypes` producerIn text updated (it said a Map is sent as its toString; it now says it is sent as JSON, and that raw fails on a body it cannot convert to a stream). - `salesforce-rest-api.adoc` says how request bodies are sent; the raw table in `salesforce-component.adoc` says a `Map` body fails. - Regenerated `salesforce.json` (component and catalog), the catalog doc copies, and the endpoint and component DSL builders. - Upgrade guide 4.24: a `camel-salesforce` entry for the Map/POJO body change and the raw failure. ### Not changed `CompositeApiProcessor` has the same pattern (an empty `Optional` with no exception sets a `null` exception, so the exchange also completes silently). It is a different processor and not part of this issue, so it is left for a separate fix. _Claude Code on behalf of Claus Ibsen (davsclaus)_ 🤖 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]
