[
https://issues.apache.org/jira/browse/CAMEL-24351?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18101980#comment-18101980
]
Henrik commented on CAMEL-24351:
--------------------------------
you're welcome :)
> camel-platform-http-starter: CamelRequestHandlerMapping is @Lazy, so every
> platform-http endpoint can silently return 404
> ---------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-24351
> URL: https://issues.apache.org/jira/browse/CAMEL-24351
> Project: Camel
> Issue Type: Bug
> Components: camel-platform-http, camel-spring-boot
> Affects Versions: 4.21.0
> Reporter: Henrik
> Priority: Major
> Labels: regression, spring-boot
> Fix For: 4.22.0
>
> Attachments:
> 0001-CAMEL-24351-camel-platform-http-starter-the-request-.patch
>
>
> On 4.21.0 a Spring Boot application can start with every platform-http route
> reporting itself started, while every request to them returns 404 from
> Spring's {{{}BasicErrorController{}}}:
> {code:json}
> {"status":404,"error":"Not Found","path":"/myroute"}
> {code}
> Camel logs nothing for these requests because no route is invoked, and the
> app looks healthy: startup shows {{{}Started myroute
> (rest://get:/myroute){}}}, non-HTTP routes work, health probes stay green.
> Whether an instance is affected is decided at startup and fixed for its
> lifetime, so restarts appear to fix it at random.
> h3. Cause
> {{SpringBootPlatformHttpAutoConfiguration}} declares the mapping bean
> {{{}@Bean @Lazy{}}}. {{CamelRequestHandlerMapping}} registers itself as a
> {{PlatformHttpListener}} in its constructor, and
> {{PlatformHttpComponent.addHttpEndpoint()}} notifies only listeners that
> already exist. A lazy bean is created on first demand, which is not ordered
> against CamelContext startup: if Camel starts before anything resolves
> {{HandlerMapping}} beans, all endpoints are registered before the mapping
> exists and its registry stays empty forever. It is silent because
> {{addPlatformHttpListener()}} does not replay {{getHttpEndpoints()}} to a new
> listener, and {{addHttpEndpoint()}} logs listener exceptions at WARN only.
> h3. Why 4.21.0
> Eager singletons are created in {{{}preInstantiateSingletons(){}}}, always
> before {{finishRefresh()}} starts Camel, so the listener could not miss a
> registration.
> ||Version||Annotation||Instantiation||
> |4.18.3|none|eager|
> |4.20.0|@DependsOn|eager|
> |4.21.0|@Lazy|lazy|
> Verified from the constant pool of the released class in each starter jar.
> {{@Lazy}} arrived in commit 264db4c12e0 ("Fix compilation error in
> camel-aws-s3 (#1783)"), which replaced an {{ObjectProvider<CamelContext>}}
> parameter, used to defer the lookup and avoid a circular dependency, with
> direct injection plus {{{}@Lazy{}}}.
> Applications with a separate management port are not affected: the management
> child context initialises its DispatcherServlet during startup, which
> instantiates the parent's mapping before Camel starts. Deterministic check:
> {{{}getBeanDefinition("platformHttpEngineRequestMapping").isLazyInit(){}}}.
> h3. Fix
> Drop {{@Lazy}} and resolve the CamelContext from an {{ObjectProvider}} inside
> the method, restoring eager instantiation while keeping the circular
> dependency avoidance:
> {code:java}
> @Bean
> public CamelRequestHandlerMapping platformHttpEngineRequestMapping(
> PlatformHttpEngine engine, ObjectProvider<CamelContext> camelContextProvider)
> {
> CamelContext camelContext = camelContextProvider.getObject();
> PlatformHttpComponent component = camelContext.getComponent("platform-http",
> PlatformHttpComponent.class);
> return new CamelRequestHandlerMapping(component, engine);
> }
> {code}
> h3. Workaround
> {{{}spring.mvc.servlet.load-on-startup=1{}}}: Tomcat's
> {{performDeferredLoadOnStartup()}} runs inside {{{}onRefresh(){}}}, before
> the {{ContextRefreshedEvent}} that starts Camel.
> PR: [https://github.com/apache/camel-spring-boot/pull/1874]
--
This message was sent by Atlassian Jira
(v8.20.10#820010)