Let an alternative execution engine be selected, with MySQL as the default - #24
Open
dionmcm wants to merge 2 commits into
Open
Let an alternative execution engine be selected, with MySQL as the default#24dionmcm wants to merge 2 commits into
dionmcm wants to merge 2 commits into
Conversation
…fault Adds the seam only. There is no second engine in this PR, and MySQL behaviour is unchanged: `rvf.execution.engine` defaults to `mysql` through `matchIfMissing = true`, so a deployment that sets nothing gets exactly the beans it gets today. What the seam is: * `@ConditionalOnMysqlEngine` - one meta-annotation, applied to the beans that are MySQL-specific: AssertionExecutionService, MysqlValidationService, MysqlFailuresExtractor, AssertionServiceImpl, ValidationVersionLoader, ReleaseDataManager, ResourceDataLoader, RvfDynamicDataSource, and the `dataSource` bean. * `ExecutionEngine` - the property contract. Anything that is not exactly `duckdb` is `mysql`, deliberately: a typo must not be able to start the service with its database half missing. * `MysqlPersistenceConfig` - `@EntityScan` and `@EnableJpaRepositories` moved out of `Config` so they can be conditional. Bean-for-bean identical in mysql mode. * `SqlAssertionValidationService` - the interface `ValidationRunner` now depends on, instead of naming `MysqlValidationService` directly. `MysqlValidationService` implements it with a one-line delegate to its existing `runRF2MysqlValidations`. * `ReleaseAcquisitionService` - the four acquisition methods lifted verbatim out of `ValidationVersionLoader`, which stays MySQL-only because it also loads schemas. Deliberately NOT conditional: acquiring files is engine-independent, and this is what lets `ValidationRunner` run without the MySQL half. `ValidationVersionLoader` keeps deprecated one-line delegates so existing callers are unaffected. * `DuckDbEngineEnvironmentPostProcessor` - excludes Boot's JPA and datasource auto-configuration when the engine is not mysql, so a no-database deployment does not fail on a missing URL. Registered through spring.factories. It holds no reference to any engine implementation. * `MySqlQueryTransformer` - the sentinel substitution rules extracted from AssertionExecutionService, unchanged, with the unit tests they never had. They are a specification any engine has to match, and they were previously only expressible by running MySQL. * `AssertionGroupImporter.resolveGroups` - resolves group membership from groups.xml and policies.xml without a database, which the assertion tables previously required. `ManifestResolveProbe` exercises it standalone. * `AssertionsDatabaseImporter` gains pre-requisites.sql handling, which routes through the extracted transformer. The seam does not depend on a second engine: this branch compiles and its tests pass with no `org.ihtsdo.rvf.core.service.duck` package present at all. Selecting `duckdb` here is a startup failure rather than a silent fallback - nothing implements `SqlAssertionValidationService` in that mode - which is the honest behaviour for a build that carries no such engine. Full suite on this host, offline Maven, no Docker: clean upstream-develop 213 run, 0 failures, 142 errors, 21 skipped + the bug-fix PR 219 run, 0 failures, 142 errors, 21 skipped + this PR 241 run, 0 failures, 142 errors, 21 skipped Same 142 pre-existing errors at every step, all of them Testcontainers with no Docker daemon. 22 tests added, none broken. Also removes four duplicated import lines this refactor had accumulated in AssertionExecutionService.
AssertionHelper injects AssertionExecutionService, which is now MySQL-only, so without this the application cannot start at all under a non-mysql engine: the context fails with 'No qualifying bean of type AssertionExecutionService' while building assertionHelper for assertionController. Gated, because they administer a database an alternative engine need not have - they reach ReleaseDataManager and AssertionGroupRepository directly: AssertionController, AssertionGroupController, ReleaseController, AssertionHelper. Deliberately NOT gated: TestUploadFileController and AutomatedTestController. Their only MySQL coupling is the AssertionService interface, and an alternative engine has to supply that itself. Gating them would leave an application that boots and cannot be asked to validate anything, which is worse than not starting.
This was referenced Aug 29, 2026
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.
The seam only. No second engine in this PR.
rvf.execution.enginedefaults tomysqlviamatchIfMissing = true, so a deployment that sets nothing gets the beans it gets today.Stacked on #23; review that first.
What it adds
@ConditionalOnMysqlEngineExecutionEngineduckdbismysql, so a typo cannot start the service without its database halfMysqlPersistenceConfig@EntityScan/@EnableJpaRepositoriesmoved out ofConfigto be conditional. Bean-for-bean identical in mysql modeSqlAssertionValidationServiceValidationRunnerdepends on instead ofMysqlValidationService. The MySQL class implements it with a one-line delegate to existingrunRF2MysqlValidationsReleaseAcquisitionServiceValidationVersionLoader. Not conditional: acquiring files is engine-independent.ValidationVersionLoaderkeeps deprecated delegatesDuckDbEngineEnvironmentPostProcessorMySqlQueryTransformerAssertionExecutionService, unchanged, with unit tests it did not haveAssertionGroupImporter.resolveGroupsgroups.xml/policies.xmlwithout a databaseAssertionController,AssertionGroupController,ReleaseControllerandAssertionHelpergated (they administer database tables).TestUploadFileControllerandAutomatedTestControllerdeliberately not: gating them leaves a service that starts and cannot be asked to validateTwo things to look at
MySqlQueryTransformeris useful even without a second engine. Those substitution rules are a specification —<PROSPECTIVE>,<PREVIOUS>,<DEPENDENCY>, and the rule that a statement holding an unbound sentinel is dropped per statement, not per assertion. They previously could only be exercised by running MySQL. Now 171 lines of unit test.ReleaseAcquisitionServiceis the only change that moves code rather than adding an annotation, so it is where a behaviour change would hide. The methods are byte-identical to the originals, which remain as delegates.Separability
This branch compiles and its tests pass with no
org.ihtsdo.rvf.core.service.duckpackage present. Nothing here imports one.Selecting
duckdbin this build is a startup failure, not a fallback: nothing implementsSqlAssertionValidationServicein that mode.Verification
Same 142 pre-existing errors (Testcontainers, no Docker daemon). 22 tests added.
Also removes four duplicated
importlines inAssertionExecutionService.