[ 
https://issues.apache.org/jira/browse/CAMEL-24589?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Omar Atie reassigned CAMEL-24589:
---------------------------------

    Assignee: Omar Atie

> camel-platform-http-starter: stopping the second consumer on a shared path 
> unregisters the first consumer
> ---------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-24589
>                 URL: https://issues.apache.org/jira/browse/CAMEL-24589
>             Project: Camel
>          Issue Type: Bug
>    Affects Versions: 4.22.0
>         Environment: Apache Camel / camel-platform-http-starter 4.22.0; 
> Spring Boot 4.1.0; Java 25.0.4; macOS. Native routes with standard Spring 
> Boot auto-configuration.
>            Reporter: Serdar Gökay
>            Assignee: Omar Atie
>            Priority: Major
>
> h2. Summary
> With two {{platform-http}} consumers sharing a path but accepting different 
> HTTP methods, stopping the consumer registered second removes the Spring MVC 
> mapping for the consumer registered first. The surviving route therefore 
> stops serving requests even though it was not stopped.
> h2. Environment
> * Apache Camel / camel-platform-http-starter 4.22.0
> * Spring Boot 4.1.0
> * Java 25.0.4, macOS
> * Ordinary Spring Boot auto-configuration and native Camel routes; no custom 
> HTTP dispatcher or lifecycle implementation.
> h2. Reproduction
> Register the GET route first and the POST route second:
> {code:java}
> from("platform-http:/shared?httpMethodRestrict=GET")
>     .routeId("shared-get")
>     .setBody().constant("shared-get");
> from("platform-http:/shared?httpMethodRestrict=POST")
>     .routeId("shared-post")
>     .setBody().constant("shared-post");
> {code}
> # Start the application. Confirm GET {{/shared}} returns {{shared-get}} and 
> POST {{/shared}} returns {{shared-post}}.
> # Call {{camelContext.getRouteController().stopRoute("shared-post")}}.
> # Send GET {{/shared}} again.
> Expected: HTTP 200 with body {{shared-get}}; stopping POST must not 
> unregister GET.
> Actual: HTTP 405 Method Not Allowed.
> Control case, using a fresh application context with the same registration 
> order: stopping {{shared-get}} preserves POST successfully. The two isolated 
> tests produced 1 pass and 1 failure, with no errors or skipped tests. The 
> failing assertion was {{expected: <200> but was: <405>}}.
> h2. Existing upstream coverage
> [Spring Boot PR #1842|https://github.com/apache/camel-spring-boot/pull/1842] 
> added real mapping unregistration and a shared-path lifecycle test. The 
> [4.22.0 
> SpringBootPlatformHttpRouteLifecycleTest|https://github.com/apache/camel-spring-boot/blob/camel-spring-boot-4.22.0/components-starter/camel-platform-http-starter/src/test/java/org/apache/camel/component/platform/http/springboot/SpringBootPlatformHttpRouteLifecycleTest.java]
>  registers GET first and POST second, but stops only GET. That direction 
> passes; stopping POST instead exposes this issue.
> A regression case using the same route definitions and test fixture would be:
> {code:java}
> @Test
> void stoppingSecondConsumerPreservesFirstConsumerOnSamePath() throws 
> Exception {
>     given().get("/shared").then().statusCode(200).body(equalTo("shared-get"));
>     
> given().post("/shared").then().statusCode(200).body(equalTo("shared-post"));
>     camelContext.getRouteController().stopRoute("shared-post");
>     given().get("/shared").then().statusCode(200).body(equalTo("shared-get"));
> }
> {code}
> Run this case with an isolated application context so other lifecycle tests 
> do not change registration state. The Java snippet above is an equivalent 
> regression-case suggestion; the observed result came from a separate 
> Kotlin/JUnit probe using a fresh Spring Boot application per case.
> h2. Suspected cause from source inspection
> In 
> [PlatformHttpComponent|https://github.com/apache/camel/blob/camel-4.22.0/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/PlatformHttpComponent.java],
>  endpoint models are held in a TreeSet whose comparator uses only 
> {{HttpEndpointModel.getUri()}}. Both methods share that URI, so only the 
> first model is retained.
> [DefaultPlatformHttpConsumer.doStop()|https://github.com/apache/camel/blob/camel-4.22.0/components/camel-platform-http/src/main/java/org/apache/camel/component/platform/http/DefaultPlatformHttpConsumer.java]
>  removes an endpoint by path. Stopping POST consequently removes/notifies the 
> retained GET model. 
> [CamelRequestHandlerMapping|https://github.com/apache/camel-spring-boot/blob/camel-spring-boot-4.22.0/components-starter/camel-platform-http-starter/src/main/java/org/apache/camel/component/platform/http/springboot/CamelRequestHandlerMapping.java]
>  then unregisters that model's consumer mapping.
> This appears to require retaining/removing endpoint registrations by consumer 
> identity, not only by path. No dependency patch has been applied or validated 
> in this reproduction.
> h2. Version scope
> The runtime failure is confirmed on 4.22.0 only. The path-only core 
> bookkeeping predates that release, but the Spring Boot unregistration 
> behavior changed in PR #1842. This report does not claim that older releases 
> exhibit the same HTTP 405 failure.



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to