[ 
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)

Reply via email to