oscerd opened a new pull request, #28955: URL: https://github.com/apache/camel/pull/28955
Fixes [CAMEL-26247](https://issues.apache.org/jira/browse/CAMEL-26247), found while adding the catalog body types (CAMEL-24961). ## 1. A stream body was sent as its toString(), a File as its path **Was:** `FunctionsInvocationClient.convertBodyToString` sent a String as it is, decoded a byte[] as UTF-8 (so bytes that are not UTF-8, such as 0xff, were replaced) and sent any other body as its `toString()`: an InputStream as `java.io.ByteArrayInputStream@...`, a File as its path, the file of a file consumer as `GenericFile[...]`, a Map as `{name=Camel}`. **Now:** text is sent as UTF-8, and any other body is converted to bytes with the type converter (`getMandatoryBody(byte[].class)`) and sent with `BodyPublishers.ofByteArray`: bytes as they are, and an InputStream, a File or the GenericFile of a file consumer as their content. A body that does not convert to bytes, such as a Map or a POJO, fails with `InvalidPayloadException` instead of being sent as its `toString()`. GET and DELETE still send no body, and the body is not converted for them, so a GET with a Map body does not fail. `FunctionsInvocationClient.invoke` keeps its signature; it takes a String or a byte[] and throws `IllegalArgumentException` for another body, which the producer no longer passes. ## 2. The default Content-Type was only added when the headers map was set **Was:** `Content-Type: application/json` was added only when the `CamelAzureFunctionsHttpHeaders` header was set and had no `Content-Type` key, so without that header a body was sent with no Content-Type. The key was compared case-sensitively, so a `content-type` key got a second `application/json` value. **Now:** a request with a body gets `Content-Type: application/json` unless the headers map sets a Content-Type, in any letter case. ## 3. An HTTP error status did not fail the exchange **Was:** a 4xx or 5xx response became the message body, with the status in `CamelAzureFunctionsStatusCode`, and the route continued as a success. **Now:** a status of 400 or above fails the exchange with `org.apache.camel.http.base.HttpOperationFailedException`, the exception of the HTTP components, filled as camel-http fills it: the function URL, the status, the response headers and the response body (the JDK HttpClient gives no reason phrase, so the status text is null). The `CamelAzureFunctionsStatusCode` and `CamelAzureFunctionsResponseHeaders` headers are still set. The new option `throwExceptionOnFailure` (default `true`, named and described as in camel-http) keeps the previous behaviour when set to `false`. The module now depends on `camel-http-base` for the exception; that module only depends on camel-support. A 3xx status does not fail: the issue asks for 4xx/5xx, and the JDK client does not follow redirects, so a 3xx is the answer of the function. ## Tests - New `FunctionsProducerInvokeTest` (14 tests) against a JDK `HttpServer` that stands in for the function app; the test points the invocation client at it through the `FunctionsClientFactory` of the endpoint. It covers text (UTF-8), a byte[] with 0xff and 0x00, an InputStream, a File, the GenericFile of a file consumer, no body, a Map (fails, nothing sent), GET with a body, the Content-Type with and without the headers map and with a lower-case `content-type` key, a 500 and a 404 (exception with the status, body, headers and URI), and `throwExceptionOnFailure=false`. - With the `src/main` changes and the regenerated configurers reverted, 10 of the 14 tests fail: bytes, stream, file, file consumer and Map (the wrong bytes are sent, or no exception), the two Content-Type tests (no Content-Type, or two values), the 500 and 404 tests (no exception), and `throwExceptionOnFailure=false` (the option does not exist). The 4 that pass are text, no body, GET with a body, and the default Content-Type with a headers map: the behaviour of those does not change. - `mvn clean install` of the module: 14 tests, 0 failures; the 11 integration tests are skipped without Azure credentials. ## Docs and generated files - Component doc: a new "Invoking a function" section (the request body, the Content-Type, the response and the error status). - `@BodyTypes`: the producerIn carriers are now text, bytes, stream, file and null; the producerIn and producerOut descriptions say what the code does now. - Regenerated `azure-functions.json` (new option, body types) and configurers; the JSON and the doc are copied into the catalog. - Upgrade guide entry for 4.24: the error status fails the exchange (and `throwExceptionOnFailure=false` to keep the old behaviour), the body is sent as bytes, a Map or a POJO body fails, and the default Content-Type. - The endpoint and component DSLs are regenerated for the new option. ## Not changed - The exception is camel-http-base's `HttpOperationFailedException`, so an `onException(HttpOperationFailedException.class)` written for the HTTP components also catches it. camel-http, camel-undertow, camel-vertx-http and camel-chaos throw the same class, and `camel-http-base` only depends on camel-support, so the module gains no third-party dependency. - The `Content-Type` header of the Camel message is not used for the request: only the `CamelAzureFunctionsHttpHeaders` map sets HTTP headers, as before. **Open question:** use the message `Content-Type` when the map has none? - A Map or a POJO is not marshalled to JSON: the issue proposes the type converter, and the module uses no JSON library of its own. Such a body fails, and the docs say to marshal it first. - The response is still read as text (`BodyHandlers.ofString()`), so a binary response is decoded as text; that is not part of this issue. 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]
