From ec37138138eaeabbac8a23807aa42871ff0abb64 Mon Sep 17 00:00:00 2001 From: Ken Stevens Date: Mon, 9 Dec 2019 11:32:25 -0500 Subject: [PATCH] add environment variable to allow flyway out of order migration --- .../uhn/fhir/jpa/migrate/FlywayMigrator.java | 5 +++ .../fhir/jpa/migrate/SchemaMigratorTest.java | 37 +++++++++++++++---- 2 files changed, 35 insertions(+), 7 deletions(-) diff --git a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java index 7a4dd0c48bd..947bef342b6 100644 --- a/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java +++ b/hapi-fhir-jpaserver-migrate/src/main/java/ca/uhn/fhir/jpa/migrate/FlywayMigrator.java @@ -33,9 +33,12 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import static org.apache.commons.lang3.StringUtils.isNotBlank; + public class FlywayMigrator extends BaseMigrator { private static final Logger ourLog = LoggerFactory.getLogger(FlywayMigrator.class); + public static final String OUT_OF_ORDER_MIGRATION = "OUT_OF_ORDER_MIGRATION"; private final String myMigrationTableName; private List myTasks = new ArrayList<>(); @@ -79,10 +82,12 @@ public class FlywayMigrator extends BaseMigrator { private Flyway initFlyway(DriverTypeEnum.ConnectionProperties theConnectionProperties) { // TODO KHS Is there a way we can use datasource instead of url, username, password here + boolean outOfOrder = isNotBlank(System.getProperty(OUT_OF_ORDER_MIGRATION)); Flyway flyway = Flyway.configure() .table(myMigrationTableName) .dataSource(getConnectionUrl(), getUsername(), getPassword()) .baselineOnMigrate(true) + .outOfOrder(outOfOrder) .javaMigrations(myTasks.toArray(new JavaMigration[0])) .load(); for (FlywayMigration task : myTasks) { diff --git a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/SchemaMigratorTest.java b/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/SchemaMigratorTest.java index 4631d4afa32..d778c511baa 100644 --- a/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/SchemaMigratorTest.java +++ b/hapi-fhir-jpaserver-migrate/src/test/java/ca/uhn/fhir/jpa/migrate/SchemaMigratorTest.java @@ -13,6 +13,7 @@ import java.sql.SQLException; import java.util.Properties; import java.util.Set; +import static org.hamcrest.CoreMatchers.containsString; import static org.junit.Assert.*; public class SchemaMigratorTest extends BaseTest { @@ -20,7 +21,7 @@ public class SchemaMigratorTest extends BaseTest { @Test public void testMigrationRequired() { - SchemaMigrator schemaMigrator = createSchemaMigrator("create table SOMETABLE (PID bigint not null, TEXTCOL varchar(255))"); + SchemaMigrator schemaMigrator = createTableMigrator(); try { schemaMigrator.validate(); @@ -37,21 +38,38 @@ public class SchemaMigratorTest extends BaseTest { @Test public void testRepairFailedMigration() { - SchemaMigrator schemaMigrator = createSchemaMigrator("create fable SOMETABLE (PID bigint not null, TEXTCOL varchar(255))"); + SchemaMigrator schemaMigrator = createSchemaMigrator("SOMETABLE", "create fable SOMETABLE (PID bigint not null, TEXTCOL varchar(255))", "1"); try { schemaMigrator.migrate(); fail(); } catch (FlywayException e) { assertEquals(org.springframework.jdbc.BadSqlGrammarException.class, e.getCause().getCause().getClass()); } - schemaMigrator = createSchemaMigrator("create table SOMETABLE (PID bigint not null, TEXTCOL varchar(255))"); + schemaMigrator = createTableMigrator(); + schemaMigrator.migrate(); + } + + @Test + public void testOutOfOrderMigration() { + SchemaMigrator schemaMigrator = createSchemaMigrator("SOMETABLE", "create table SOMETABLE (PID bigint not null, TEXTCOL varchar(255))", "2"); + schemaMigrator.migrate(); + + schemaMigrator = createSchemaMigrator("SOMETABLE" ,"create table SOMEOTHERTABLE (PID bigint not null, TEXTCOL varchar(255))", "1"); + + try { + schemaMigrator.migrate(); + fail(); + } catch (FlywayException e) { + assertThat(e.getMessage(), containsString("Detected resolved migration not applied to database: 1.1")); + } + System.setProperty(FlywayMigrator.OUT_OF_ORDER_MIGRATION, "true"); schemaMigrator.migrate(); } @Test public void testMigrationRequiredNoFlyway() throws SQLException { - SchemaMigrator schemaMigrator = createSchemaMigrator("create table SOMETABLE (PID bigint not null, TEXTCOL varchar(255))"); + SchemaMigrator schemaMigrator = createTableMigrator(); schemaMigrator.setDriverType(DriverTypeEnum.H2_EMBEDDED); schemaMigrator.setDontUseFlyway(true); @@ -69,9 +87,14 @@ public class SchemaMigratorTest extends BaseTest { } @Nonnull - private SchemaMigrator createSchemaMigrator(String theSql) { - AddTableRawSqlTask task = new AddTableRawSqlTask("1", "1"); - task.setTableName("SOMETABLE"); + private SchemaMigrator createTableMigrator() { + return createSchemaMigrator("SOMETABLE", "create table SOMETABLE (PID bigint not null, TEXTCOL varchar(255))", "1"); + } + + @Nonnull + private SchemaMigrator createSchemaMigrator(String theTableName, String theSql, String theSchemaVersion) { + AddTableRawSqlTask task = new AddTableRawSqlTask("1", theSchemaVersion); + task.setTableName(theTableName); task.addSql(DriverTypeEnum.H2_EMBEDDED, theSql); SchemaMigrator retval = new SchemaMigrator(SchemaMigrator.HAPI_FHIR_MIGRATION_TABLENAME, getDataSource(), new Properties(), ImmutableList.of(task)); retval.setDriverType(DriverTypeEnum.H2_EMBEDDED);