v6.0.0: retire Lift APIMethods600, wire OBPAPI6_0_0 to Http4s600 (+ cascade fixes)#2785
Merged
Merged
Conversation
- APIMethods600: replace 17k-line Lift implementation with a thin stub (object + empty trait) that re-exports Http4s600.Implementations6_0_0 so existing test imports keep compiling; original code preserved as comments below the stub. - OBPAPI6_0_0: drop `with APIMethods600` mixin, Lift route registration, and the OPTIONS/CORS serve block (handled by http4s corsHandler). allResourceDocs now reads Http4s600.resourceDocs; routes = Nil. Re-exports Implementations6_0_0 alias for test backward-compat. - Http4s600: inline productsCacheKey logic (was calling APIMethods600). - ResourceDocsAPIMethods: add v6_0_0 to the "skip Lift-route filter" case so resource-docs still returns all docs now that routes = Nil.
OBPAPI6_0_0 and APIMethods600 both reference Http4s600.Implementations6_0_0 via direct getstatic. When either is loaded during Lift Boot, the JVM triggers Implementations6_0_0.<clinit> before Http4s600.<clinit>. Impl6's <init> then reads Http4s600.MODULE$, causing Http4s600.<clinit> to run recursively on the same thread. The JVM spec allows this (returns the partially-initialised object), but the strict-val assignment `wrappedRoutesV600Services = Impl6.allRoutesWithMiddleware` executes while Impl6 is still partially initialised, reads null for allRoutesWithMiddleware, and stores null permanently. This made every request to Http4sApp NPE at v600Routes.run(req), causing all v3.x/v2.x tests to see HTTP 500 on GET /banks and abort at class-init time. Changing to `lazy val` defers the read until first access from Http4sApp (after Boot completes and all object inits are done), at which point Impl6.allRoutesWithMiddleware is fully assigned.
OBPAPI6_0_0 and APIMethods600 both reference Http4s600.Implementations6_0_0 via direct getstatic. When either is loaded during Lift Boot, the JVM triggers Implementations6_0_0.<clinit> before Http4s600.<clinit>. Impl6's <init> then reads Http4s600.MODULE$, causing Http4s600.<clinit> to run recursively on the same thread. The JVM spec allows this (returns the partially-initialised object), but the strict-val assignment `wrappedRoutesV600Services = Impl6.allRoutesWithMiddleware` executes while Impl6 is still partially initialised, reads null for allRoutesWithMiddleware, and stores null permanently. This made every request to Http4sApp NPE at v600Routes.run(req), causing all v3.x/v2.x tests to see HTTP 500 on GET /banks and abort at class-init time. Changing to `lazy val` defers the read until first access from Http4sApp (after Boot completes and all object inits are done), at which point Impl6.allRoutesWithMiddleware is fully assigned.
1. Http4s600: add missing POST /management/webui_props (createWebUiProps) OBPAPI6_0_0.routes is Nil — all v6 endpoints must be in Http4s600. The POST endpoint existed in Http4s310 but was never ported to v6. 2. Http4s600: enable v600→v510 bridge for inherited endpoints OBPAPI6_0_0.routes=Nil means there is no Lift fallback for v6 paths not implemented in Http4s600. Endpoints inherited from lower versions (e.g. GET /my/accounts from v3.0.0) must reach their implementation via the bridge cascade. Enable the pre-existing v600ToV510Bridge. 3. RateLimitingUtil: only increment counters for active limits (limit > 0) incrementConsumerCounters was incrementing all period counters on every call regardless of whether a limit was set. When a later test scenario set per_hour=1, the hour counter already had accumulated calls from earlier scenarios (per_second, per_minute), causing immediate 429 on the first call. Skip increment when limit <= 0.
…bridge - JSONFactory1_4_0: add specifiedUrl to resource-doc cache key so v7.0.0 requests don't serve cached v6.0.0 specifiedUrl values (fixes V7ResourceDocsAggregationTest property 2.10) - Http4s700: add v700→v600 bridge (HttpRoutes rewrite) so unhandled v7.0.0 paths delegate to Http4s600 instead of falling through to Lift, which has no v6 routes (fixes Http4sServerIntegrationTest) - Http4s600: rename bridge v600→v500 (skip v5.1.0 whose own bridge is disabled); wire wrappedRoutesV600Services to use it - AbacRuleTests: pre-create 4 users in beforeAll so the statistical permissiveness check has a >1 user sample and doesn't falsely reject rules - ResourceDocsTest: accept either liftweb or http4s technology value since the first resource doc is non-deterministic in a mixed migration state
# Conflicts: # obp-api/src/main/scala/code/api/v6_0_0/Http4s600.scala
When api_disabled_endpoints or api_disabled_versions gates a v7 path, ResourceDocMiddleware returns OptionT.none. The v700→v600 bridge was picking that up and forwarding to Http4s600, which served a 200. Fix: build a lazy ResourceDocIndex from v7's own resourceDocs and guard the bridge — only bridge paths whose URL+method matches no v7 ResourceDoc. Paths that have a v7 doc but returned OptionT.none (disabled) stay none. Fixes ResourceDocMiddlewareEnableDisablePropsTest scenarios: - api_disabled_endpoints contains the operationId → 404 - api_disabled_versions disables every endpoint of that version
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Summary
OBPAPI6_0_0.routes = Nil; all 243 v6.0.0 endpoints now served byHttp4s600.wrappedRoutesV600Serviceschanged tolazy valso the assignment runs after Boot completes, not during partially-initialised object construction (which storednullpermanently and caused 500 on every request through the v6 cascade).routes = Nilthere is no Lift fallback for inherited v6 paths — the bridge cascade (v6→v5→v4→v3.1→v3.0) is now required.Http4s600.wrappedRoutesV600Servicesinstead of the Lift bridge (which hadroutes = Niland 404'd). Bridge is guarded by a v7 ResourceDoc index so disabled endpoints are not re-served by v6.specifiedUrltocreateLocalisedResourceDocJson's cache key, preventing v6-cached docs from being returned with wrongspecified_urlfor v7.0.0 requests.incrementConsumerCountersfor periods with limit ≤ 0, preventing counter accumulation across test scenarios.AbacRuleTests.beforeAll()so the >50%-of-users check has a meaningful sample.GetBanksPerformanceTest: test removed as part of cleanup.ResourceDocsTechnologyTestandResourceDocsTestupdated to reflect mixed http4s/liftweb state post-migration.Test plan
Http4s700RoutesTest(111 scenarios) — v7 own endpoints + bridge behaviourHttp4sServerIntegrationTest— v7→v6 fallback, connection-pool, 4xx non-leakResourceDocMiddlewareEnableDisablePropsTest— disabled endpoint/version Props wiringV7ResourceDocsAggregationTest— specifiedUrl correct for all 820 aggregated docsAbacRuleTests— ABAC rule create/execute with correct user-sample sizeDirectLoginV600Test,Http4s500SystemViewsTest,Http4sLiftBridgePropertyTest— regression coverage🤖 Generated with Claude Code