oscerd opened a new pull request, #26207: URL: https://github.com/apache/camel/pull/26207
## Issue [CAMEL-24435](https://issues.apache.org/jira/browse/CAMEL-24435) ## Problem `AS2ServerConnection.RequestHandlerThread.run()` creates its `HttpContext` once, **outside** the request loop, and reuses it for every request handled on that connection: ```java final HttpContext context = HttpCoreContext.create(); while (!Thread.interrupted()) { this.httpService.handleRequest(this.serverConnection, context); ... String recipientAddress = coreContext.getAttribute(AS2AsynchronousMDNManager.RECIPIENT_ADDRESS, String.class); if (recipientAddress != null && config != null) { // Send the MDN asynchronously. ``` `ResponseMDN` sets `RECIPIENT_ADDRESS` and `ASYNCHRONOUS_MDN` on that context while handling a request that carried `Receipt-Delivery-Option`, and nothing removed them afterwards. A later request on the same connection that did **not** ask for an asynchronous receipt therefore still found a non-null recipient address, and the handler dispatched a second asynchronous MDN — carrying whatever report was still stored under `ASYNCHRONOUS_MDN` — to the address supplied by the *earlier* request. ## Fix Both attributes are removed in a `finally` after every request. Using `finally` rather than clearing at the end of the send block also covers the paths that skip the send — in particular a request URI with no registered consumer configuration, where `config` is null and the old code left the address behind untouched. ### Also clears `CURRENT_CONSUMER_CONFIG` The same `finally` clears the `CURRENT_CONSUMER_CONFIG` ThreadLocal, which is not in the issue text but has the identical defect. `setupConfigurationForRequest` returns early **without** setting it when a path has no registered configuration: ```java if (config == null) { LOG.warn("No AS2 consumer configuration found for canonical path: {} ...", requestUriPath); return null; } ... CURRENT_CONSUMER_CONFIG.set(wrapper); ``` so the thread kept the previous request's wrapper. On its own that cannot trigger a send, but paired with a *new* legitimate recipient address it would have signed the MDN with the previous path's key. Clearing only the context attributes would have left that half of the leak in place. The post-processing block is extracted into `handleAsynchronousMDN` so the `finally` reads clearly; the logic inside is unchanged. ## Test `AS2AsyncMdnContextReuseTest` sends two messages through one `as2://client/send` route, so both travel over the same pooled connection to the server: 1. the first carries `receiptDeliveryOption` → exactly one MDN must reach the receipt endpoint; 2. the second does not → the receipt endpoint must see **no** further MDN. The second assertion uses `setAssertPeriod(5s)` so a leaked delivery has time to arrive rather than the test passing simply by being quick. Verified both ways: against the unfixed `camel-as2-api` the test fails with `mock://receipts Received message count. Expected: <0> but was: <1>`, and it passes with the fix. `components/camel-as2` suite green (API + Component). Full reactor build clean. ## Documentation No upgrade-guide entry: the previous behaviour was sending an MDN nobody asked for, to an address from an unrelated earlier request. There is nothing for a user to migrate. --- _Claude Code on behalf of 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]
