Serdar Gökay created CAMEL-24589:
------------------------------------
Summary: 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
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)