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

   Fixes [CAMEL-26196](https://issues.apache.org/jira/browse/CAMEL-26196).
   
   ### 1. pojoRequest=true with a body of the wrong type did nothing
   
   **Was:** every pojoRequest create/update operation (24 of them, such as 
`createUser`, `updateRealm`, `createOrganization`) did `if (payload instanceof 
XxxRepresentation)`. For a String or Map body there was no call to Keycloak, no 
error, and the body was kept.
   
   **Now:** a new `getPojoRequest(exchange, type)` gets the representation. 
Another type is converted: first by a Camel type converter, then a `Map` (such 
as unmarshalled JSON) or JSON text (String, byte[], InputStream) is mapped with 
Keycloak's own `JsonSerialization`. A body that does not convert, or invalid 
JSON, fails with an `InvalidPayloadException` for the expected type.
   
   ### 2. A failed create or delete was no error, and its Response was never 
closed
   
   **Was:** the operations that give the jakarta `Response` as body set it 
without looking at the status, so a 409 (already exists) or 404 (not found) 
completed the exchange. The Response was never closed, so its HTTP connection 
was not released. `deleteOrganization`, `removeOrganizationMember` and 
`unlinkOrganizationIdentityProvider` ignored their Response the same way.
   
   **Now:** a new `checkResponse(response, operation)` fails on a status other 
than 2xx with a `jakarta.ws.rs.WebApplicationException` that carries the 
Response (message: `Keycloak createUser failed with status 409: <Keycloak error 
text>`), and always closes the Response. This is the same exception type the 
Keycloak admin client throws for the operations that do not return a Response 
(for example `NotFoundException` from `updateUser`), so one 
`onException(WebApplicationException.class)` covers them all.
   
   The body is still the `Response`, now closed. With RESTEasy, `getStatus()`, 
`getLocation()` and `getHeaderString("Location")` work after `close()`, so 
routes that read the id of the created resource from the Location header keep 
working (the `KeycloakTestInfraIT` tests that do so pass against a real 
Keycloak). Only `readEntity` fails, and a 201/204 has no entity.
   
   Covered: createUser, deleteUser, createGroup, createClient, 
createClientScope, createIdentityProvider, createResource, 
createResourcePolicy, createResourcePermission, createOrganization, 
updateOrganization, addOrganizationMember, linkOrganizationIdentityProvider, 
deleteOrganization, removeOrganizationMember, 
unlinkOrganizationIdentityProvider.
   
   ### 3. bulkCreateUsers with a List of Map failed with a raw 
ClassCastException
   
   **Was:** `bulkCreateUsers` and `bulkUpdateUsers` cast the List (body or 
`CamelKeycloakUsers` header) to `List<UserRepresentation>`; a List of Map 
failed with a `ClassCastException` in the loop.
   
   **Now:** each element is converted the same way as in 1. An element that 
does not convert fails the exchange with an `IllegalArgumentException` that 
names the index and `UserRepresentation`, before any call to Keycloak.
   
   On the same lines: `bulkCreateUsers` and `bulkDeleteUsers` counted a 409 or 
404 as a `success`. They now use `checkResponse`, so such an item is `failed` 
with its `statusCode` (and the exchange fails unless 
`CamelKeycloakContinueOnError` is true). `bulkDeleteUsers` also closes the 
Response when the call throws.
   
   ### Tests
   
   - New `KeycloakProducerPojoRequestAndResponseTest` (14 tests, Mockito, no 
Keycloak needed): JSON text and Map bodies, wrong type and invalid JSON, 
409/404 for createUser, createGroup, deleteUser and deleteOrganization, the 
Response is closed on success and failure, bulk create/update from a List of 
Map and JSON text, a wrong element, and 409/404 items in bulk create/delete. 
All 14 fail without the fix.
   - `KeycloakProducerTest`: the shared mocked Response now returns status 201, 
and the three organization delete tests stub the Response of `delete()`.
   - Module: 161 unit tests pass; the ITs that ran against Keycloak from 
test-infra pass too (133 run, 31 skipped as before).
   
   ### Docs
   
   - `keycloak-producer.adoc`: new sections "Representation bodies" and 
"Results of create and delete operations"; the bulk result example shows a 
failed item with its `statusCode`.
   - `@BodyTypes` text of producerIn and producerOut updated (the old one 
documented the no-op and "a 409 or 404 is no error"); `keycloak.json` 
regenerated and copied to the catalog, with the producer doc page.
   - Upgrade guide 4.24: new `camel-keycloak` section, since a 409/404 now 
fails the exchange, the Response body is closed, and a pojoRequest body that 
did nothing now converts or fails.
   
   ### Not changed
   
   - The body of these operations stays the `Response` (closed), rather than 
becoming the created id or a text, so the body type and routes that read the 
status or Location header do not change.
   - Operations whose admin client methods return `void` or a representation 
already fail on an error status (the client throws), so they are untouched.
   
   _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]

Reply via email to