fix(alerting): ClickHouseSearchIndex bean registered as concrete type (hotfix: production crashloop) #141
Reference in New Issue
Block a user
Delete Branch "fix/alerting-searchindex-bean-type"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
Hotfix — production crashlooping after #140 merge. One-line return-type change in
StorageBeanConfig.Root cause
StorageBeanConfig.clickHouseSearchIndex(...)declared return typeSearchIndex(interface). Spring registers beans by their declared type, not their runtime instance class.ExchangeMatchEvaluator(Plan 02) autowires the concreteClickHouseSearchIndexbecausecountExecutionsForAlertinglives only on the concrete class, not the interface. Spring can't match the concrete autowire against an interface-typed bean, so the app fails to start:ClickHouseLogStore's bean is already declared with the concrete return type (StorageBeanConfig.java:171), which is whyLogPatternEvaluatorautowires fine.Fix
Change the return type from
SearchIndextoClickHouseSearchIndex. Spring still auto-exposes it under theSearchIndexinterface forSearchIndexerand any other interface-typed consumers — widening the declared type doesn't break existing autowires.Why CI didn't catch this
All alerting ITs inherit from
AbstractPostgresIT, which has:@MockBeanreplaces the bean with a mock of the declared type (ClickHouseSearchIndex). Every test ran against a mock whose declared type IS the concrete class, soExchangeMatchEvaluator's autowire succeeded against the mock. The real production bean graph was never exercised.Follow-up (not in this PR — a separate branch)
@MockBean(name = "clickHouseSearchIndex")and@MockBean(name = "clickHouseLogStore")fromAbstractPostgresIT. Mocks belong on the specific ITs that actually need them, not on the base class.SpringContextSmokeITthat loads the full@SpringBootTestcontext with no mocks and assertsvoid contextLoads() {}. This is the minimum regression test that would have caught this bug pre-merge. Budget: ~15 minutes.@MockBean(name=...)workarounds for similar masked bugs.This follow-up is broader than a hotfix — I'll queue it for Plan 03 or a dedicated test-hygiene branch.
Test plan
ExchangeMatchEvaluatorautowire error.curl POST /api/v1/environments/{envSlug}/alerts/ruleswith anEXCHANGE_MATCHrule; wait a tick; confirm no exceptions in logs.SearchIndexerstill functions (ingestion path — untouched logically, just type-narrowed bean declaration).