oscerd opened a new pull request, #28962:
URL: https://github.com/apache/camel/pull/28962

   Fixes [CAMEL-26252](https://issues.apache.org/jira/browse/CAMEL-26252), 
found while adding the catalog body types (CAMEL-24961).
   
   ## 1. A failed call gave an empty body and no exception
   
   **Was:** `GoogleCloudFunctionsProducer.callFunction` set 
`response.getResult()` as the body and never looked at `response.getError()`. A 
function whose execution failed gave an empty String and the route went on as a 
success.
   
   **Now:** when the `CallFunctionResponse` has an error, the exchange fails 
with a `CamelExchangeException`: "The function 
projects/.../functions/myFunction failed in execution <id>: <error>" (the 
execution id part only when the response has one). The `CallFunctionResponse` 
is set in the `CamelGoogleCloudFunctionsResponseObject` header before the 
exception, so an error handler can read the error and the execution id; the 
body is left as it was (the data sent), so a redelivery sends the same data. 
This holds with and without `pojoRequest`.
   
   ## 2. callFunction without a body failed with a bare NullPointerException
   
   **Was:** `setData(getBody(String.class))` passed null to protobuf, which 
threw a NullPointerException without a message.
   
   **Now:** no body fails with an `InvalidPayloadException` (expected type 
`String`) before the function is called. I chose failing over sending an empty 
string: `data` is a required field of `CallFunctionRequest` in the Cloud 
Functions v1 API, and the catalog body types already documented "no body 
fails". A route that wants to call a function without input can set an empty 
body (`""`) or `{}` explicitly.
   
   ## 3. A Map or POJO body was sent as its toString()
   
   **Was:** the body was read as String, so a Map went out as `{name=Camel}`, a 
List as `[a, b]` and a POJO as its `toString()`.
   
   **Now:** text (a `CharSequence`) is sent as it is, and bytes, a stream (also 
a stream cache or a Reader), a `File`, a `Path` and a `GenericFile` are read as 
text, as before. Any other body, such as a `Map`, a `List` or a POJO, is 
marshalled to JSON with Jackson. A body Jackson cannot marshal fails with an 
`InvalidPayloadException` that carries the Jackson error. The module now 
declares `jackson-databind` (version managed by the parent): before, only 
`jackson-core` was on its classpath, through google-http-client-jackson2.
   
   ## Tests
   
   - New `GoogleCloudFunctionsCallFunctionTest` (13 tests) on the module's 
in-process gRPC mock (`MockCloudFunctionsService`): a failed call with and 
without `pojoRequest`, a successful call, no body, a Map, a List and a POJO (a 
record) sent as JSON, and a String, bytes, a stream, a `File`, a `Path` and a 
`GenericFile` sent as text.
   - `GoogleCloudFunctionsComponentTest.callFunctionTest` and 
`callFunctionPojoTest` stubbed a successful response that also had an error set 
(`setError("error96784904")`, generated sample data); the error is removed, as 
such a response now fails the exchange.
   - With the `src/main` changes reverted, 6 of the 13 new tests fail, each on 
an assertion that shows the bug: the two failed-call tests (no exception), no 
body (a `NullPointerException` instead of an `InvalidPayloadException`), and 
the Map, List and POJO tests (`{name=Camel, count=2}`, `[a, b]`, 
`Greeting[text=Hello, count=2]`). The 7 that pass are the successful call and 
the text bodies, which were already read as text: they guard that the change 
keeps them.
   - Module tests: 37 tests, 0 failures, 1 skipped (skipped before this change 
too).
   
   ## Docs and generated files
   
   Component doc: what `callFunction` sends for each body, that no body fails, 
what it returns, and that a failed function fails the exchange with the 
response still in the header. `@BodyTypes`: the input carriers add file, map, 
list and pojo and the description says how each is sent; the output description 
says that a response with an error fails the exchange. The regenerated 
`google-functions.json` and the doc are copied into the catalog. Upgrade guide 
entry: `callFunction` fails the exchange when the function fails, a Map, List 
or POJO is sent as JSON, and no body fails with an `InvalidPayloadException`.
   
   ## Not changed
   
   - There is no option to keep the old behaviour (a failed call going on as a 
success, as `aws2-lambda` does with its function error header). **Open 
question:** should a `throwExceptionOnFailure`-style option be added? It would 
be a new feature, so I left it out.
   - Gson is also on the module's classpath (transitively, through the Google 
libraries) and would have avoided the new `jackson-databind` dependency. I used 
Jackson because the other Google components (firestore, secret-manager, 
vertexai) use it and it honours the Jackson annotations users put on their 
POJOs.
   - Bytes are still read as text: `data` is a string field of the API, so 
binary data cannot go through it unencoded.
   
   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]

Reply via email to