davsclaus opened a new pull request, #29109: URL: https://github.com/apache/camel/pull/29109
Fixes [CAMEL-26270](https://issues.apache.org/jira/browse/CAMEL-26270). ### 1. A producer only works on the thread that created it **What was wrong:** openstack4j keeps its session in a thread local (`OSClientSession`), and its services (`os.compute()`, `os.objectStorage()`, ...) use the session of the calling thread. Every openstack producer authenticated its client once in `createProducer()`, on the thread that starts the route. A call from any other thread (a file, seda or timer consumer) failed with `NullPointerException: Unable to retrieve current session`. All six components (cinder, glance, keystone, neutron, nova, swift) share this code. **What changed:** `AbstractOpenstackProducer.process` now creates the session of the calling thread from the token of the client on each call (`OSFactory.clientFromToken` for v3, `OSFactory.clientFromAccess` for v2), which is how openstack4j documents using a client from several threads. No extra authentication happens per call. When openstack4j renews an expired token (on a 401 it re-authenticates into the session in use), the producer keeps the session with the renewed token, so the next calls use it and do not re-authenticate every time. The 17 producers implement `doProcess(Exchange)` instead of `process(Exchange)`; the base class does the session handling and then calls `doProcess`. **Tests** (WireMock, in-JVM): - `OpenstackSwiftObjectTest.getFromAnotherThreadShouldSucceed`: 20 requests through a `seda` route with 5 consumers. Failed before with "Unable to retrieve current session". - `OpenstackSessionTest.renewedTokenShouldBeKept`: the first token gets a 401, the renewed one works; 5 calls make 2 authentications. Without keeping the renewed session it makes 6 (one per call). ### 2. swift and glance: the payload has no type conversion **What was wrong:** `AbstractOpenstackProducer.createPayload` accepted only a `Payload`, `URL`, `File` or `InputStream` body, so a String, byte[] or the `GenericFile` of the file consumer failed with "You have to set payload" (swift object create, glance create/upload). **What changed:** any other non-null body is converted to an `InputStream` with the type converter. Text becomes its bytes (it is never treated as a file name). **Tests:** - `OpenstackSwiftObjectTest.createFromTextShouldSucceed`, `createFromBytesShouldSucceed`: the WireMock stub only answers a PUT with the expected content. - `OpenstackSwiftObjectTest.createFromFileConsumerShouldSucceed`: a route from a file consumer to swift (both bugs: other thread and `GenericFile` body). - `OpenstackGlanceTest.uploadTextFromAnotherThreadShouldSucceed`: a String body uploaded from a seda route. All failed before the fix. Module: 154 tests, all pass with `-Psourcecheck`. ### Docs and generated files - `@BodyTypes` of swift and glance no longer say text, bytes and files fail; glance create/upload list `text` and `bytes` carriers. Regenerated `openstack-swift.json` and `openstack-glance.json`, copied to `camel-catalog`. - The swift doc example drops the `convertBodyTo: java.io.File` step that worked around bug 2. Copied to `camel-catalog`. ### Not changed - No upgrade guide entry: bodies that failed before now work, and nothing that worked changes. The only API change is `doProcess` in the producer classes, which are internal to the component. - Each producer still authenticates once when it is created (unchanged). _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]
