ENT-5654: Fixed migration error message, improved success message

This commit is contained in:
Edoardo Ierina 2020-08-13 11:32:56 +02:00
parent 748480c33e
commit 07fe1b0960
2 changed files with 45 additions and 4 deletions

View File

@ -92,6 +92,25 @@ open class SchemaMigration(
}
}
/**
* Returns the count of pending database migration changes
* @param schemas The set of MappedSchemas to check
* @param forceThrowOnMissingMigration throws an exception if a mapped schema is missing the migration resource. Can be set to false
* when allowing hibernate to create missing schemas in dev or tests.
*/
fun getPendingChangesCount(schemas: Set<MappedSchema>, forceThrowOnMissingMigration: Boolean) : Int {
val resourcesAndSourceInfo = prepareResources(schemas, forceThrowOnMissingMigration)
// current version of Liquibase appears to be non-threadsafe
// this is apparent when multiple in-process nodes are all running migrations simultaneously
mutex.withLock {
dataSource.connection.use { connection ->
val (_, changeToRunCount, _) = prepareRunner(connection, resourcesAndSourceInfo)
return changeToRunCount;
}
}
}
/**
* Synchronises the changelog table with the schema descriptions passed in without applying any of the changes to the database.
* This can be used when migrating a CorDapp that had its schema generated by hibernate to liquibase schema migration, or when

View File

@ -448,13 +448,24 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
updateAppSchemasWithCheckpoints: Boolean
) {
check(started == null) { "Node has already been started" }
check(updateCoreSchemas || updateAppSchemas) { "Neither core nor app schema scripts were specified" }
Node.printBasicNodeInfo("Running database schema migration scripts ...")
val props = configuration.dataSourceProperties
if (props.isEmpty) throw DatabaseConfigurationException("There must be a database configured.")
var pendingAppChanges: Int = 0
var pendingCoreChanges: Int = 0
database.startHikariPool(props, metricRegistry) { dataSource, haveCheckpoints ->
SchemaMigration(dataSource, cordappLoader, configuration.baseDirectory, configuration.myLegalName)
.checkOrUpdate(schemaService.internalSchemas, updateCoreSchemas, haveCheckpoints, true)
.checkOrUpdate(schemaService.appSchemas, updateAppSchemas, !updateAppSchemasWithCheckpoints && haveCheckpoints, false)
val schemaMigration = SchemaMigration(dataSource, cordappLoader, configuration.baseDirectory, configuration.myLegalName)
if(updateCoreSchemas) {
schemaMigration.runMigration(haveCheckpoints, schemaService.internalSchemas, true)
} else {
pendingCoreChanges = schemaMigration.getPendingChangesCount(schemaService.internalSchemas, true)
}
if(updateAppSchemas) {
schemaMigration.runMigration(!updateAppSchemasWithCheckpoints && haveCheckpoints, schemaService.appSchemas, false)
} else {
pendingAppChanges = schemaMigration.getPendingChangesCount(schemaService.appSchemas, false)
}
}
// Now log the vendor string as this will also cause a connection to be tested eagerly.
logVendorString(database, log)
@ -474,7 +485,18 @@ abstract class AbstractNode<S>(val configuration: NodeConfiguration,
cordappProvider.start()
}
}
Node.printBasicNodeInfo("Database migration done.")
val updatedSchemas = listOfNotNull(
("core").takeIf { updateCoreSchemas },
("app").takeIf { updateAppSchemas }
).joinToString(separator = " and ");
val pendingChanges = listOfNotNull(
("no outstanding").takeIf { pendingAppChanges == 0 && pendingCoreChanges == 0 },
("$pendingCoreChanges outstanding core").takeIf { !updateCoreSchemas && pendingCoreChanges > 0 },
("$pendingAppChanges outstanding app").takeIf { !updateAppSchemas && pendingAppChanges > 0 }
).joinToString(prefix = "There are ", postfix = " database changes.");
Node.printBasicNodeInfo("Database migration scripts for $updatedSchemas schemas complete. $pendingChanges")
}
fun runSchemaSync() {