change out-of-order-permitted from environment variablet to flag to work like dont-use-flyway

This commit is contained in:
Ken Stevens 2019-12-09 16:44:24 -05:00
parent 77373605bd
commit bd1b41ff82
6 changed files with 26 additions and 16 deletions

View File

@ -24,7 +24,6 @@ import ca.uhn.fhir.jpa.migrate.BaseMigrator;
import ca.uhn.fhir.jpa.migrate.BruteForceMigrator;
import ca.uhn.fhir.jpa.migrate.DriverTypeEnum;
import ca.uhn.fhir.jpa.migrate.FlywayMigrator;
import ca.uhn.fhir.jpa.migrate.SchemaMigrator;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
@ -45,7 +44,9 @@ public abstract class BaseFlywayMigrateDatabaseCommand<T extends Enum> extends B
public static final String MIGRATE_DATABASE = "migrate-database";
public static final String NO_COLUMN_SHRINK = "no-column-shrink";
public static final String DONT_USE_FLYWAY = "dont-use-flyway";
public static final String OUT_OF_ORDER_PERMITTED = "out-of-order-permitted";
private Set<String> myFlags;
private String myMigrationTableName;
@ -86,7 +87,8 @@ public abstract class BaseFlywayMigrateDatabaseCommand<T extends Enum> extends B
addRequiredOption(retVal, "d", "driver", "Driver", "The database driver to use (Options are " + driverOptions() + ")");
addOptionalOption(retVal, "x", "flags", "Flags", "A comma-separated list of any specific migration flags (these flags are version specific, see migrator documentation for details)");
addOptionalOption(retVal, null, DONT_USE_FLYWAY,false, "If this option is set, the migrator will not use FlywayDB for migration. This setting should only be used if you are trying to migrate a legacy database platform that is not supported by FlywayDB.");
addOptionalOption(retVal, null, "no-column-shrink", false, "If this flag is set, the system will not attempt to reduce the length of columns. This is useful in environments with a lot of existing data, where shrinking a column can take a very long time.");
addOptionalOption(retVal, null, OUT_OF_ORDER_PERMITTED,false, "If this option is set, the migrator will permit migration tasks to be run out of order. It shouldn't be required in most cases, however may be the solution if you see the error message 'Detected resolved migration not applied to database'.");
addOptionalOption(retVal, null, NO_COLUMN_SHRINK, false, "If this flag is set, the system will not attempt to reduce the length of columns. This is useful in environments with a lot of existing data, where shrinking a column can take a very long time.");
return retVal;
}
@ -110,7 +112,7 @@ public abstract class BaseFlywayMigrateDatabaseCommand<T extends Enum> extends B
}
boolean dryRun = theCommandLine.hasOption("r");
boolean noColumnShrink = theCommandLine.hasOption("no-column-shrink");
boolean noColumnShrink = theCommandLine.hasOption(BaseFlywayMigrateDatabaseCommand.NO_COLUMN_SHRINK);
String flags = theCommandLine.getOptionValue("x");
myFlags = Arrays.stream(defaultString(flags).split(","))
@ -118,7 +120,8 @@ public abstract class BaseFlywayMigrateDatabaseCommand<T extends Enum> extends B
.filter(StringUtils::isNotBlank)
.collect(Collectors.toSet());
boolean dontUseFlyway = theCommandLine.hasOption("dont-use-flyway");
boolean dontUseFlyway = theCommandLine.hasOption(BaseFlywayMigrateDatabaseCommand.DONT_USE_FLYWAY);
boolean outOfOrderPermitted = theCommandLine.hasOption(BaseFlywayMigrateDatabaseCommand.OUT_OF_ORDER_PERMITTED);
BaseMigrator migrator;
if (dontUseFlyway) {
@ -132,6 +135,7 @@ public abstract class BaseFlywayMigrateDatabaseCommand<T extends Enum> extends B
migrator.setPassword(password);
migrator.setDryRun(dryRun);
migrator.setNoColumnShrink(noColumnShrink);
migrator.setOutOfOrderPermitted(outOfOrderPermitted);
addTasks(migrator);
migrator.migrate();
}

View File

@ -9,7 +9,7 @@ Note that this feature was added in HAPI FHIR 3.5.0. It is not able to migrate f
The following example shows how to use the migrator utility to migrate to the latest version.
```bash
./hapi-fhir-cli migrate-database -d H2_EMBEDDED -u "jdbc:derby:directory:target/jpaserver_derby_files;create=true" -n "" -p ""
./hapi-fhir-cli migrate-database -d H2_EMBEDDED -u "jdbc:h2:directory:target/jpaserver_h2_files;create=true" -n "" -p ""
```
You may use the following command to get detailed help on the options:
@ -64,14 +64,10 @@ SELECT * FROM HFJ_RES_REINDEX_JOB
* Execute the migrator tool again, this time omitting the flag option, e.g.
```bash
./hapi-fhir-cli migrate-database -d DERBY_EMBEDDED -u "jdbc:h2:directory:target/jpaserver_h2_files;create=true" -n "" -p ""
./hapi-fhir-cli migrate-database -d H2_EMBEDDED -u "jdbc:h2:directory:target/jpaserver_h2_files;create=true" -n "" -p ""
```
* Rebuild, and start HAPI FHIR JPA again.
# Flyway
As of version 4.2.0, HAPI FHIR JPA now uses Flyway for schema migrations. The "from" and "to" parameters are no longer used. Flyway maintains a list of completed migrations in a table called `FLY_HFJ_MIGRATION`. When you run the migration command, flyway scans the list of completed migrations in this table and compares them to the list of known migrations, and runs only the new ones.
## Recovering from a failed migration
Under certain unlikely scenarios, you may see the error message "Detected resolved migration not applied to database". This means that Flyway has detected a new migration task that has an earlier version than the latest version in the Flyway table. You can set the environment variable `OUT_OF_ORDER_MIGRATION` to allow Flyway to run migration tasks out of order.

View File

@ -30,6 +30,7 @@ public abstract class BaseMigrator {
private boolean myDryRun;
private boolean myNoColumnShrink;
private boolean myOutOfOrderPermitted;
private DriverTypeEnum myDriverType;
private String myConnectionUrl;
private String myUsername;
@ -89,4 +90,11 @@ public abstract class BaseMigrator {
myPassword = thePassword;
}
public boolean isOutOfOrderPermitted() {
return myOutOfOrderPermitted;
}
public void setOutOfOrderPermitted(boolean theOutOfOrderPermitted) {
myOutOfOrderPermitted = theOutOfOrderPermitted;
}
}

View File

@ -33,12 +33,9 @@ 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<FlywayMigration> myTasks = new ArrayList<>();
@ -82,12 +79,11 @@ 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)
.outOfOrder(isOutOfOrderPermitted())
.javaMigrations(myTasks.toArray(new JavaMigration[0]))
.load();
for (FlywayMigration task : myTasks) {

View File

@ -43,6 +43,7 @@ public class SchemaMigrator {
private final String myMigrationTableName;
private final List<BaseTask<?>> myMigrationTasks;
private boolean myDontUseFlyway;
private boolean myOutOfOrderPermitted;
private DriverTypeEnum myDriverType;
/**
@ -64,6 +65,10 @@ public class SchemaMigrator {
myDontUseFlyway = theDontUseFlyway;
}
public void setOutOfOrderPermitted(boolean theOutOfOrderPermitted) {
myOutOfOrderPermitted = theOutOfOrderPermitted;
}
public void validate() {
if (mySkipValidation) {
ourLog.warn("Database running in hibernate auto-update mode. Skipping schema validation.");
@ -102,6 +107,7 @@ public class SchemaMigrator {
migrator.setPassword(myDataSource.getPassword());
} else {
migrator = new FlywayMigrator(myMigrationTableName, myDataSource);
migrator.setOutOfOrderPermitted(myOutOfOrderPermitted);
}
migrator.addTasks(myMigrationTasks);
return migrator;

View File

@ -62,7 +62,7 @@ public class SchemaMigratorTest extends BaseTest {
} 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.setOutOfOrderPermitted(true);
schemaMigrator.migrate();
}