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/09/05 16:56:00 UTC

[jira] [Updated] (CAMEL-24589) camel-platform-http-starter: stopping the second consumer on a shared path unregisters the first consumer

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

Claus Ibsen updated CAMEL-24589:
--------------------------------
    Fix Version/s: 4.23.0

> 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
>             Fix For: 4.23.0
>
>
> 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)