diff --git a/kork-sql-test/src/main/java/com/netflix/spinnaker/kork/sql/test/SqlTestUtil.java b/kork-sql-test/src/main/java/com/netflix/spinnaker/kork/sql/test/SqlTestUtil.java index 1e55f132f..2ee16db68 100644 --- a/kork-sql-test/src/main/java/com/netflix/spinnaker/kork/sql/test/SqlTestUtil.java +++ b/kork-sql-test/src/main/java/com/netflix/spinnaker/kork/sql/test/SqlTestUtil.java @@ -223,7 +223,7 @@ public static TestDatabase initDatabase( Liquibase migrate; try { - DatabaseChangeLog changeLog = new DatabaseChangeLog(); + DatabaseChangeLog changeLog = new DatabaseChangeLog("db/changelog/"); changeLog.setChangeLogParameters( new ChangeLogParameters( diff --git a/kork-sql/src/main/kotlin/com/netflix/spinnaker/kork/sql/config/SqlMigrationProperties.kt b/kork-sql/src/main/kotlin/com/netflix/spinnaker/kork/sql/config/SqlMigrationProperties.kt index 7a52c2025..e88a7c578 100644 --- a/kork-sql/src/main/kotlin/com/netflix/spinnaker/kork/sql/config/SqlMigrationProperties.kt +++ b/kork-sql/src/main/kotlin/com/netflix/spinnaker/kork/sql/config/SqlMigrationProperties.kt @@ -15,6 +15,8 @@ */ package com.netflix.spinnaker.kork.sql.config +import liquibase.GlobalConfiguration + /** * Defines the configuration properties for connecting to a SQL database for schema migration purposes. * @@ -23,11 +25,14 @@ package com.netflix.spinnaker.kork.sql.config * @param password The password to authenticate the [user] * @param driver The JDBC driver name * @param additionalChangeLogs A list of additional change log paths. This is useful for libraries and extensions. + * @param duplicateFileMode flag to handle if multiple files are found in the search path that have duplicate paths. */ data class SqlMigrationProperties( var jdbcUrl: String? = null, var user: String? = null, var password: String? = null, var driver: String? = null, - var additionalChangeLogs: List = mutableListOf() + var additionalChangeLogs: List = mutableListOf(), + var duplicateFileMode: GlobalConfiguration.DuplicateFileMode = GlobalConfiguration.DUPLICATE_FILE_MODE.defaultValue + ) diff --git a/kork-sql/src/main/kotlin/com/netflix/spinnaker/kork/sql/migration/SpringLiquibaseProxy.kt b/kork-sql/src/main/kotlin/com/netflix/spinnaker/kork/sql/migration/SpringLiquibaseProxy.kt index 3cf1a7935..c2097327c 100644 --- a/kork-sql/src/main/kotlin/com/netflix/spinnaker/kork/sql/migration/SpringLiquibaseProxy.kt +++ b/kork-sql/src/main/kotlin/com/netflix/spinnaker/kork/sql/migration/SpringLiquibaseProxy.kt @@ -16,6 +16,8 @@ package com.netflix.spinnaker.kork.sql.migration import com.netflix.spinnaker.kork.sql.config.SqlMigrationProperties +import liquibase.GlobalConfiguration +import liquibase.Scope import javax.sql.DataSource import liquibase.integration.spring.SpringLiquibase import org.springframework.jdbc.datasource.SingleConnectionDataSource @@ -41,6 +43,13 @@ class SpringLiquibaseProxy( init { changeLog = "classpath:db/changelog-master.yml" dataSource = createDataSource() + // Liquibase 4.21.0 onwards, there is a check in liquibase based on labelFilter value. + // This labelFilter is supposed to be used for running all those changeLogs having that label on them. + // But liquibase also runs all those which don't have any label. + // And by not assigning any value to that field either in SpringLiquibaseProxy object or SpringLiquibase object, + // liquibase is ignoring all those changeLogs defined through SpringLiquibase objects under + // SpringLiquibaseProxy's afterPropertiesSet() method below. + labelFilter = "spinnaker" } /** @@ -52,18 +61,20 @@ class SpringLiquibaseProxy( super.afterPropertiesSet() // Then if anything else has been defined, do that afterwards - (sqlMigrationProperties.additionalChangeLogs + korkAdditionalChangelogs) - .map { - SpringLiquibase().apply { - changeLog = "classpath:$it" - dataSource = createDataSource() - resourceLoader = this@SpringLiquibaseProxy.resourceLoader - shouldRun = !sqlReadOnly + Scope.child(GlobalConfiguration.DUPLICATE_FILE_MODE.key, sqlMigrationProperties.duplicateFileMode) { + (sqlMigrationProperties.additionalChangeLogs + korkAdditionalChangelogs) + .map { + SpringLiquibase().apply { + changeLog = "classpath:$it" + dataSource = createDataSource() + resourceLoader = this@SpringLiquibaseProxy.resourceLoader + shouldRun = !sqlReadOnly + } } - } - .forEach { - it.afterPropertiesSet() - } + .forEach { + it.afterPropertiesSet() + } + } } private fun createDataSource(): DataSource = diff --git a/kork-sql/src/test/kotlin/com/netflix/spinnaker/kork/sql/SpringStartupTests.kt b/kork-sql/src/test/kotlin/com/netflix/spinnaker/kork/sql/SpringStartupTests.kt index 8310f98da..d23df51ee 100644 --- a/kork-sql/src/test/kotlin/com/netflix/spinnaker/kork/sql/SpringStartupTests.kt +++ b/kork-sql/src/test/kotlin/com/netflix/spinnaker/kork/sql/SpringStartupTests.kt @@ -30,6 +30,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication import org.springframework.boot.test.context.SpringBootTest import org.springframework.context.ApplicationContext import org.springframework.context.annotation.Import +import org.springframework.test.context.TestPropertySource import org.springframework.test.context.junit.jupiter.SpringExtension import strikt.api.expectThat import strikt.assertions.isA @@ -43,6 +44,7 @@ import strikt.assertions.isNotNull "sql.enabled=true", "sql.migration.jdbcUrl=jdbc:h2:mem:test", "sql.migration.dialect=H2", + "sql.migration.duplicateFileMode=WARN", "sql.connectionPool.jdbcUrl=jdbc:h2:mem:test", "sql.connectionPool.dialect=H2" ] diff --git a/kork-sql/src/test/resources/application-test.yml b/kork-sql/src/test/resources/application-test.yml index c3b01d241..662c6420d 100644 --- a/kork-sql/src/test/resources/application-test.yml +++ b/kork-sql/src/test/resources/application-test.yml @@ -26,10 +26,12 @@ sql: jdbcUrl: "jdbc:h2:mem:test" user: password: + duplicateFileMode: WARN secondaryMigration: jdbcUrl: "jdbc:h2:mem:test" user: password: + duplicateFileMode: WARN --- spring: @@ -52,3 +54,4 @@ sql: jdbcUrl: "jdbc:h2:mem:test" user: password: + duplicateFileMode: WARN diff --git a/spinnaker-dependencies/spinnaker-dependencies.gradle b/spinnaker-dependencies/spinnaker-dependencies.gradle index b8c5e29b0..8f62aeb1d 100644 --- a/spinnaker-dependencies/spinnaker-dependencies.gradle +++ b/spinnaker-dependencies/spinnaker-dependencies.gradle @@ -165,7 +165,7 @@ dependencies { // containing `afterColumn` construct, with a validation error for postgresql. So pin with 3.10.3 api("org.liquibase:liquibase-core"){ version { - strictly "3.10.3" + strictly "4.24.0" } } api("org.objenesis:objenesis:2.5.1")