Skip to content

Commit a2d89ac

Browse files
committed
refactor: retire Schemifier from boot and delete ToSchemify.models
Third and final step of removing net.liftweb.mapper from obp-api. The previous two commits took every reference down to two schemify calls, both already no-ops (Schemifier.schemify(true, Schemifier.infoF _, ToSchemify.models: _*) on an empty list), plus a MapperRules setting and a MetaMapper-typed field that fed them. All four come out here, along with the last wildcard mapper import. - Boot.scala:173's MapperRules.createForeignKeys_? assignment: the only reader was Schemifier, and Schemifier's argument was always Nil, so this configured a foreign-key policy for a schema-creation pass that never created anything. The mapper_rules.create_foreign_keys prop it read is retired (release_notes.md, both props templates). - Boot.scala:539's schemifyAll(), renamed createDefaultChatRoom() with the Schemifier.schemify line removed - it kept exactly one live side effect (getOrCreateDefaultRoom()) and the name should say so, not describe schema work that stopped happening once ToSchemify.models went to Nil. - MockedRabbitMqAdapter.scala:3322's identical schemify call, and its now-dead net.liftweb.mapper.Schemifier / bootstrap.liftweb.ToSchemify imports. - ToSchemify.models itself: not just emptied, deleted. The object stays (it also starts the optional gRPC server and registers a JVM shutdown hook, unrelated to schema). Its four remaining "importers" - ServerSetup, LocalMappedConnectorTestSetup, TestConnectorSetupWithStandardPermissions, SandboxDataLoadingTest - never actually read the field; each import was dead weight left over from when their reset loops iterated it. Removing them is confirmed safe by the same evidence that made the field safe to delete: obp-api has had zero live Mapper entities since the Doobie migration finished. - Boot.scala:64's `import net.liftweb.mapper.{DefaultConnectionIdentifier => _, _}` - the wildcard that supplied MapperRules, Schemifier and MetaMapper to this file. Nothing else in it needed anything from that package. LiquibaseSchemaSetupTest asserted `ToSchemify.models shouldBe empty` as half of pinning "liquibase.enabled defaults to true because nothing else creates a table." That assertion doesn't compile once the field is gone, and doesn't need to: the invariant it protected is now enforced by the compiler rather than by a runtime check, since there is no Schemifier.schemify call left anywhere in obp-api to accidentally un-empty a list that no longer exists. Rewrote the test and the doc comments in LiquibaseSchemaSetup.scala and LiquibaseOnExistingSchemaTest.scala that described the old mechanism, so none of them keep pointing at a symbol that isn't there. One more comment turned out to be stale independently of this refactor, caught only because it was about to become more obviously wrong: AtmTableResetIsolationTest.scala's doc comment said MappedAtm was "still in Boot.ToSchemify.models" and reset "happens for free" via that list's bulkDelete_!! loop - checked, and all four reset paths it lists already carry an explicit `DELETE FROM mappedatm` (ServerSetup:150 and the same line number pattern in the other three). MappedAtm moved to Doobie a while ago; the comment was never updated to say so. Corrected to describe the current mechanism instead of a superseded one. obp-api/pom.xml's comment on the lift-persistence dependency said Scala 3 doesn't exist "see docs/scala3-lift-mapper-blocker.md" as if obp-api's own code were still blocked by it. It isn't, any more - grep -rn "net\.liftweb\.mapper" across obp-api and obp-commons main sources now turns up only comments and the pre-existing entirely-commented-out Lift-era files this refactor doesn't touch. What is still pinned to _2.13 is the ARTIFACT: lift-persistence bundles common+db+mapper+proto+util as one jar, and no Scala 3 build of the bundle exists because mapper can't compile under Scala 3. Reworded to say that rather than implying obp-api's own mapper usage is the blocker. Verification: clean compile in one pass. H2 Surefire audit: 4073/0/0, unchanged (the 4 dead-import deletions and the LiquibaseSchemaSetupTest rewrite add or remove no scenarios). Postgres: same isolated-per-shard-pair strategy as the previous commit, same numbers - shard 1 535/0, shard 2 1197/0, shard 3 1008/0, shard 4 1285/0, all BUILD SUCCESS, zero FAILED anywhere. Also did the one check the test suite cannot: a real production-mode boot (flushall_build_and_run.sh, backed by an isolated in-memory H2 rather than any suite's shared setup) reached `Ember-Server service bound to address: 127.0.0.1:8080` with no ExceptionInInitializerError and no Schemifier line anywhere in the log, then served two live requests against it - GET /obp/v5.1.0/root (200) and GET /obp/v5.1.0/resource-docs/v5.1.0/obp (200, 3.5MB, 599 resource_docs entries) - the second one specifically to drive the json4s Formats chain end to end now that MapperSerializer is gone from it (removed two commits ago), on a real multi-megabyte payload rather than a test fixture. End state: grep -rn "net\.liftweb\.mapper" obp-api/src obp-commons/src, filtered to non-comment lines, returns nothing. obp-api's dependency on net.liftweb.mapper is zero.
1 parent 85e09d4 commit a2d89ac

13 files changed

Lines changed: 60 additions & 69 deletions

File tree

‎obp-api/pom.xml‎

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,12 @@
6363
<artifactId>logback-classic</artifactId>
6464
<version>1.5.18</version>
6565
</dependency>
66-
<!-- No Scala 3 build exists (see docs/scala3-lift-mapper-blocker.md) - pinned to the 2.13
67-
line explicitly, both artifactId suffix and version, since the root pom's
66+
<!-- obp-api itself has had zero references to net.liftweb.mapper since this migration removed
67+
the last of them (docs/scala3-lift-mapper-blocker.md records why that package cannot be
68+
ported to Scala 3 - a moot point now, since nothing here uses it). What is still pinned
69+
to _2.13 is the ARTIFACT: lift-persistence bundles common+db+mapper+proto+util as one jar,
70+
and no Scala 3 build of it exists because mapper cannot compile under Scala 3. Both the
71+
artifactId suffix and the version are pinned explicitly here since the root pom's
6872
dependencyManagement entry for this coordinate is keyed to ${scala.version} (= 3 here)
6973
and would otherwise not match this _2.13 artifactId at all. -->
7074
<dependency>

‎obp-api/src/main/resources/props/sample.props.template‎

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1186,9 +1186,8 @@ featured_apis=elasticSearchWarehouseV300
11861186
# -------------------------------------------------
11871187

11881188
# -- Mapper rules -------------------------------
1189-
# Define mapper rules
1190-
# In case isn't defined default value is "false"
1191-
# mapper_rules.create_foreign_keys=false
1189+
# Retired: Schemifier (which read this) is no longer called anywhere in obp-api - see
1190+
# release_notes.md, 03/09/2026. Setting this now has no effect.
11921191
# -----------------------------------------------
11931192

11941193
# -- Akka connector --------------------------------------------

‎obp-api/src/main/scala/bootstrap/liftweb/Boot.scala‎

Lines changed: 10 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@ import com.openbankproject.commons.util.{ApiVersion, Functions}
6161
import net.liftweb.common._
6262
import net.liftweb.db.{DB, DBLogEntry}
6363
import org.json4s.Extraction
64-
import net.liftweb.mapper.{DefaultConnectionIdentifier => _, _}
6564
// SiteMap imports removed - API-only mode, no portal pages
6665
import net.liftweb.util.Helpers._
6766
import net.liftweb.util._
@@ -161,17 +160,6 @@ class Boot extends MdcLoggable {
161160
DB.defineConnectionManager(net.liftweb.util.DefaultConnectionIdentifier,
162161
new code.api.util.http4s.RequestAwareConnectionManager(APIUtil.vendor))
163162

164-
/**
165-
* Function that determines if foreign key constraints are
166-
* created by Schemifier for the specified connection.
167-
*
168-
* Note: The chosen driver must also support foreign keys for
169-
* creation to happen
170-
*
171-
* In case of PostgreSQL it works
172-
*/
173-
MapperRules.createForeignKeys_? = (_) => APIUtil.getPropsAsBoolValue("mapper_rules.create_foreign_keys", false)
174-
175163
// Liquibase owns the schema outright - Schemifier creates nothing, ToSchemify.models is Nil -
176164
// and has to run here, first, because everything below assumes the tables exist. The dedup
177165
// immediately after reads them, and executeScripts decides "new database or existing one" from
@@ -180,11 +168,12 @@ class Boot extends MdcLoggable {
180168
code.api.util.liquibase.LiquibaseSchemaSetup.runIfEnabled()
181169

182170
// The natural-key de-duplication that used to sit here is in the changelog now
183-
// (db.changelog-dedup.yaml, dedup-mappedentitlement / dedup-mapperaccountholders). It was here
184-
// to run before schemifyAll() issued their CREATE UNIQUE INDEX; schemifyAll() issues nothing
185-
// any more - ToSchemify.models is Nil - and the index comes from the Liquibase call above, so
186-
// this position was already after the thing it existed to precede.
187-
schemifyAll()
171+
// (db.changelog-dedup.yaml, dedup-mappedentitlement / dedup-mapperaccountholders). It ran
172+
// before Schemifier issued its CREATE UNIQUE INDEX statements; Schemifier is gone (obp-api
173+
// has had zero live Mapper entities for a while, so it had nothing left to do), and the
174+
// index comes from the Liquibase call above, so this position was already after the thing
175+
// it existed to precede.
176+
createDefaultChatRoom()
188177

189178
logger.info("Mapper database info: " + Migration.DbFunction.mapperDatabaseInfo)
190179

@@ -536,8 +525,10 @@ class Boot extends MdcLoggable {
536525
// which is no longer reachable (Lift bridge removed in Phase B). Disabled until migrated to http4s.
537526
}
538527

539-
def schemifyAll() = {
540-
Schemifier.schemify(true, Schemifier.infoF _, ToSchemify.models: _*)
528+
// Used to also run Schemifier.schemify(true, Schemifier.infoF _, ToSchemify.models: _*) here -
529+
// a no-op since ToSchemify.models has been Nil since the last Mapper entity moved to Doobie.
530+
// Liquibase (see LiquibaseSchemaSetup.runIfEnabled above) is what actually creates the schema.
531+
def createDefaultChatRoom() = {
541532
// Create default system-level "general" chat room (is_open_room = true)
542533
code.chat.ChatRoomTrait.chatRoomProvider.vend.getOrCreateDefaultRoom()
543534
}
@@ -826,10 +817,6 @@ class Boot extends MdcLoggable {
826817
}
827818

828819
object ToSchemify extends MdcLoggable {
829-
// Empty: every table is created from the Liquibase changelog now, none by Schemifier. Kept because the
830-
// test reset paths still iterate it, and because a future Mapper entity would go here.
831-
val models: List[MetaMapper[_]] = Nil
832-
833820
// start grpc server
834821
// start grpc server (optional)
835822
val grpcServerOpt: Option[ObpGrpcServer] =

‎obp-api/src/main/scala/code/api/util/liquibase/LiquibaseSchemaSetup.scala‎

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -20,15 +20,15 @@ import liquibase.resource.ClassLoaderResourceAccessor
2020
* data source does. Liquibase describes each change once and generates the dialect per vendor, so
2121
* those three become configurations that work rather than folders nobody filled in.
2222
*
23-
* `liquibase.enabled` defaults to TRUE, because nothing else creates a table: Schemifier creates
24-
* nothing (ToSchemify.models is Nil) and Flyway is gone. "Off" therefore does not mean "something
25-
* else handles it", it means the database has no tables - set it to false only to take schema
26-
* management out of the application entirely and run the migrations yourself. The default is also
27-
* the CI configuration, since the workflows write their props from scratch and mention no database
28-
* prop at all; that is how `flyway.enabled` defaulting to false, with Schemifier already empty, put
29-
* every CI shard on a database with no tables while local runs stayed green off a hand-edited props
30-
* file. LiquibaseSchemaSetupTest holds the default against ToSchemify.models so the two cannot
31-
* drift apart again.
23+
* `liquibase.enabled` defaults to TRUE, because nothing else creates a table: Schemifier is not
24+
* called anywhere in obp-api any more - the whole net.liftweb.mapper surface, ToSchemify.models
25+
* included, was removed once the last Mapper entity moved to Doobie - and Flyway is gone too.
26+
* "Off" therefore does not mean "something else handles it", it means the database has no tables -
27+
* set it to false only to take schema management out of the application entirely and run the
28+
* migrations yourself. The default is also the CI configuration, since the workflows write their
29+
* props from scratch and mention no database prop at all; that is how `flyway.enabled` defaulting
30+
* to false, with Schemifier already empty, put every CI shard on a database with no tables while
31+
* local runs stayed green off a hand-edited props file.
3232
*/
3333
object LiquibaseSchemaSetup extends MdcLoggable {
3434

@@ -45,9 +45,9 @@ object LiquibaseSchemaSetup extends MdcLoggable {
4545
/**
4646
* Whether Liquibase runs when `liquibase.enabled` is absent from the props.
4747
*
48-
* Named rather than inlined so a test can hold it against ToSchemify.models: while that list is
49-
* empty nothing but Liquibase creates a table, so a default of false means a deployment silently
50-
* gets no schema.
48+
* Named rather than inlined so LiquibaseSchemaSetupTest can assert on it directly: nothing but
49+
* Liquibase creates a table any more, so a default of false means a deployment silently gets no
50+
* schema.
5151
*/
5252
val enabledByDefault: Boolean = true
5353

‎obp-api/src/main/scala/code/bankconnectors/rabbitmq/Adapter/MockedRabbitMqAdapter.scala‎

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
package code.bankconnectors.rabbitmq.Adapter
22

33
import org.json4s._
4-
import bootstrap.liftweb.ToSchemify
54
import code.api.util.APIUtil
65
import code.bankconnectors.rabbitmq.RabbitMQUtils
76
import code.bankconnectors.rabbitmq.RabbitMQUtils._
@@ -14,7 +13,6 @@ import com.rabbitmq.client._
1413
import net.liftweb.db.DB
1514
import com.openbankproject.commons.util.json
1615
import org.json4s.native.Serialization.write
17-
import net.liftweb.mapper.Schemifier
1816

1917
import java.util.Date
2018
import scala.concurrent.Future
@@ -3319,7 +3317,6 @@ object MockedRabbitMqAdapter extends App with MdcLoggable{
33193317
private val RPC_QUEUE_NAME = "obp_rpc_queue"
33203318

33213319
DB.defineConnectionManager(net.liftweb.util.DefaultConnectionIdentifier, APIUtil.vendor)
3322-
Schemifier.schemify(true, Schemifier.infoF _, ToSchemify.models: _*)
33233320

33243321

33253322
var connection: Connection = null

‎obp-api/src/test/scala/code/api/util/liquibase/LiquibaseOnExistingSchemaTest.scala‎

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,11 @@ import org.scalatest.matchers.should.Matchers
88
/**
99
* Turning Liquibase on against a database that already has its tables must not fail.
1010
*
11-
* This is the whole upgrade path, and it is the same shape as the one Flyway needed: Schemifier
12-
* creates nothing any more - ToSchemify.models is Nil - so an existing deployment reaching this
13-
* build has a schema built by something that left no record of itself, whether that was Schemifier
14-
* or the Flyway scripts. Liquibase's own record is DATABASECHANGELOG, and on such a database it is
11+
* This is the whole upgrade path, and it is the same shape as the one Flyway needed: Schemifier is
12+
* not called anywhere in obp-api any more - the whole net.liftweb.mapper surface was removed once
13+
* the last Mapper entity moved to Doobie - so an existing deployment reaching this build has a
14+
* schema built by something that left no record of itself, whether that was Schemifier or the
15+
* Flyway scripts. Liquibase's own record is DATABASECHANGELOG, and on such a database it is
1516
* absent, so a plain `update` would run every createTable in the baseline against tables that are
1617
* already there and fail on the first one.
1718
*
@@ -223,8 +224,9 @@ class LiquibaseOnExistingSchemaTest extends AnyFlatSpec with Matchers {
223224
// de-duplications did not cover these two: Boot called
224225
// Migration.database.deduplicateBeforeUniqueIndexSchemify() for them instead, on the stated
225226
// grounds that it had to happen before schemifyAll() issued the CREATE UNIQUE INDEX. Neither
226-
// half of that holds any more - ToSchemify.models is Nil, so schemifyAll() issues nothing,
227-
// and the index comes from Liquibase, which Boot runs FOURTEEN LINES EARLIER. So the
227+
// half of that holds any more - schemifyAll() itself is gone (renamed createDefaultChatRoom,
228+
// its Schemifier.schemify call removed along with the rest of obp-api's net.liftweb.mapper
229+
// surface), and the index comes from Liquibase, which Boot runs FOURTEEN LINES EARLIER. So the
228230
// de-duplication ran after the index it was there to make creatable.
229231
//
230232
// It also named the wrong table: `mapperaccountholder`, where the table is

‎obp-api/src/test/scala/code/api/util/liquibase/LiquibaseSchemaSetupTest.scala‎

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,9 @@ import org.scalatest.matchers.should.Matchers
1515
* pinned here.
1616
*
1717
* 1. **It must be on by default, because nothing else creates a table.**
18-
* Schemifier creates nothing (ToSchemify.models is Nil) and Flyway is gone, so "off" does not
19-
* mean "something else handles it" - it means the database has no tables. The default is the
18+
* Schemifier is not called anywhere in obp-api any more - the whole net.liftweb.mapper surface
19+
* was removed once the last Mapper entity moved to Doobie - and Flyway is gone, so "off" does
20+
* not mean "something else handles it" - it means the database has no tables. The default is the
2021
* CI configuration too: the workflows write their props from scratch and mention no database
2122
* prop at all. That is not a hypothetical - when `flyway.enabled` defaulted to false with
2223
* Schemifier already empty, every CI shard died on the first table it touched while local runs
@@ -96,11 +97,10 @@ class LiquibaseSchemaSetupTest extends AnyFlatSpec with Matchers {
9697
}
9798

9899
"the liquibase.enabled default" should "be on, since nothing else creates the schema" in {
99-
// Held against ToSchemify.models: while that list is empty, nothing but Liquibase creates a
100-
// table, so a default of false means a deployment silently gets no schema at all.
101-
withClue("nothing else creates a table while ToSchemify.models is empty: ") {
102-
bootstrap.liftweb.ToSchemify.models shouldBe empty
103-
}
100+
// Used to hold this against ToSchemify.models being empty. That field is gone now - removed
101+
// along with the rest of obp-api's net.liftweb.mapper surface - rather than merely empty, so
102+
// the invariant this protects (nothing else creates a table) is enforced by the compiler:
103+
// there is no Schemifier.schemify call left anywhere in obp-api to accidentally un-empty it.
104104
LiquibaseSchemaSetup.enabledByDefault should equal(true)
105105
}
106106
}

‎obp-api/src/test/scala/code/api/v2_1_0/SandboxDataLoadingTest.scala‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import org.json4s._
3030
import java.util.Date
3131

3232
import code.api.Constant._
33-
import bootstrap.liftweb.ToSchemify
3433
import code.TestServer
3534
import code.api.Constant._
3635
import code.api.util.APIUtil.OAuth._

‎obp-api/src/test/scala/code/atms/AtmTableResetIsolationTest.scala‎

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,16 +9,15 @@ import doobie.implicits._
99
/**
1010
* The atm table must be empty at the start of every test.
1111
*
12-
* Right now that happens for free: MappedAtm is still in Boot.ToSchemify.models, and every reset
13-
* path loops that list calling bulkDelete_!!. The moment the entity leaves ToSchemify - the next
14-
* step of this table's migration - the loop stops clearing atm rows and nothing else does, unless
15-
* an explicit Doobie DELETE is added to all four reset paths (ServerSetup,
16-
* TestConnectorSetupWithStandardPermissions, LocalMappedConnectorTestSetup, and
17-
* SandboxDataLoadingTest's own beforeEach).
12+
* That happens via an explicit `DELETE FROM mappedatm` in each of the four reset paths
13+
* (ServerSetup, TestConnectorSetupWithStandardPermissions, LocalMappedConnectorTestSetup, and
14+
* SandboxDataLoadingTest's own beforeEach) - MappedAtm moved off Lift Mapper to Doobie a while
15+
* back, and ToSchemify.models (which used to clear it for free, along with every other entity, by
16+
* looping the list calling bulkDelete_!!) has been removed entirely since.
1817
*
19-
* A leak there does not fail here first. It fails somewhere far away, as a count that is one too
20-
* high in a suite that never mentions ATMs, hours of bisecting later. This test exists to make the
21-
* failure land on the change that caused it.
18+
* A leak in any one of the four does not fail here first. It fails somewhere far away, as a count
19+
* that is one too high in a suite that never mentions ATMs, hours of bisecting later. This test
20+
* exists to make the failure land on the change that caused it.
2221
*
2322
* It is deliberately written against the raw table rather than the provider: the point is whether
2423
* the ROWS are gone, not whether a provider method filters them.

‎obp-api/src/test/scala/code/setup/LocalMappedConnectorTestSetup.scala‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package code.setup
22

3-
import bootstrap.liftweb.ToSchemify
43
import code.api.JedisMethod
54
import code.api.cache.Redis
65
import code.api.util.APIUtil

0 commit comments

Comments
 (0)