You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@camel.apache.org by "Claus Ibsen (Jira)" <ji...@apache.org> on 2026/10/06 09:21:00 UTC
[jira] [Resolved] (CAMEL-25314) camel-cxf, camel-cxfrs - a suspended consumer keeps accepting and routing new requests (graceful shutdown, suspendRoute, route policies)
[ https://issues.apache.org/jira/browse/CAMEL-25314?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Claus Ibsen resolved CAMEL-25314.
---------------------------------
Resolution: Fixed
Merged in https://github.com/apache/camel/pull/27390 (commit 8e4d1c2a0e84) for 4.23.0.
_Claude Code on behalf of davsclaus_
> camel-cxf, camel-cxfrs - a suspended consumer keeps accepting and routing new requests (graceful shutdown, suspendRoute, route policies)
> ----------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25314
> URL: https://issues.apache.org/jira/browse/CAMEL-25314
> Project: Camel
> Issue Type: Bug
> Components: camel-cxf, camel-cxfrs
> Reporter: shashank
> Assignee: shashank
> Priority: Minor
> Fix For: 4.23.0
>
>
> Since CAMEL-12870 {{CxfConsumer}} and {{CxfRsConsumer}} implement {{Suspendable}}: {{DefaultShutdownStrategy}} suspends them instead of stopping them, defers their shutdown until no exchange is inflight, and the CXF server stays up so the requests in flight can still send their responses. But neither consumer has suspend logic, and their invokers ({{CxfConsumer.CxfConsumerInvoker.invoke}}, {{CxfRsInvoker.performInvocation}}) never check the status, so a suspended consumer keeps accepting and routing *new* requests:
> * graceful shutdown: with a steady flow of requests the number of inflight exchanges does not drop to 0, so the route (or the CamelContext) is only stopped at the shutdown timeout, and the requests in flight at that moment are forced; the requests accepted during the shutdown are processed by a stopping application;
> * {{suspendRoute}} (route controller, JMX) and the route policies that suspend the consumer ({{ThrottlingInflightRoutePolicy}}, {{ThrottlingExceptionRoutePolicy}}): nothing is held back.
> The HTTP consumers (servlet, jetty, undertow, netty-http, platform-http) answer 503 (Service Unavailable) while they are suspended.
> h3. Reproduction
> {{CxfConsumerSuspendTest}} (camel-cxf-soap) and {{CxfRsConsumerSuspendTest}} (camel-cxf-rest), on main:
> {noformat}
> CxfConsumerSuspendTest.testSuspendedRouteRejectsRequests: suspendRoute, then a request
> A suspended route must not accept a request ==> Expected java.lang.Exception to be thrown, but nothing was thrown.
> CxfConsumerSuspendTest.testGracefulStopCompletesInflightAndRejectsNewRequests: request A blocks in the route,
> stopRoute (graceful) suspends the consumer, request B is sent
> A request received while stopping must be rejected ==> Expected java.lang.Exception to be thrown, but nothing was thrown.
> CxfRsConsumerSuspendTest.testSuspendedRouteRejectsRequests:
> A suspended route must answer 503 ==> expected: <503> but was: <200>
> CxfRsConsumerSuspendTest.testGracefulStopCompletesInflightAndRejectsNewRequests (asynchronous request in flight):
> A request received while stopping must be rejected ==> expected: <503> but was: <200>
> {noformat}
> With the fix the rejected requests get HTTP 503, request A (asynchronous, its continuation resumes after the suspend) still gets its response, and the route stops. No sleeps: latches, Awaitility.
> The defect was found with a TLA+ model of the consumer under a graceful shutdown / route suspend, with synchronous and asynchronous (continuation) requests: "a suspended consumer takes no new work" is violated in 3 steps (suspend, a request arrives, it is admitted). The property of CAMEL-12870, "the consumer is only stopped when nothing is inflight", holds on the current code and with the fix. A fix that also rejected resumed continuations would lose the responses of the requests in flight (shown by the model: "an admitted request gets its response" violated), so the fix only rejects new invocations.
> h3. Proposed fix
> In both invokers, reject a new invocation (synchronous, or a continuation that {{isNew()}}) while the consumer {{isSuspendingOrSuspended()}}: {{CxfConsumer}} throws a {{Fault}} with status code 503 (CXF's {{PhaseInterceptorChain}} logs it at WARN with the stack trace, as it does for any undeclared fault, e.g. a route failure; making it quieter would need {{FaultMode.CHECKED_APPLICATION_FAULT}}, which also drives WS-Addressing, WS-RM and the management counters, so it is left as is), {{CxfRsInvoker}} returns a 503 {{Response}} (a {{WebApplicationException}} is logged at WARN with its stack trace by CXF's {{WebApplicationExceptionMapper}}, once per rejected request). {{CxfRsInvoker}} still skips the continuation lookup for a sub resource locator invocation (its sub resource method is checked next). A resumed continuation is always completed. CAMEL-12870 only added {{implements Suspendable}} (no discussion on the ticket); its purpose, completing the requests in flight, is kept.
> Upgrade guide note, as a {{====}} subsection of the existing {{=== camel-cxf}} section (a suspended CXF consumer answers 503 to new requests).
> With the fix the new tests and the camel-cxf-soap (168, 2 skipped), camel-cxf-rest (51), camel-cxf-spring-soap (161, 3 skipped) and camel-cxf-spring-rest (111) suites pass.
> Affected: 4.14.x, 4.18.x and main (same code, GitHub contents API), since 2.21.3 / 2.22.2 / 2.23.0.
> Duplicate check (2026-10-04): JIRA "cxf" with 503 / "graceful shutdown" / suspended (CAMEL-12870 above; CAMEL-18528 SpringBus shutdown order; CAMEL-24179 continuation timeout race; none about new requests while suspended). GitHub pull requests "cxf suspend", "CxfRsInvoker": none about this; the open draft #22358 (CAMEL-20009, getOut replacement) changes other lines of {{CxfRsInvoker}} (imports, {{prepareExchange}}).
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)