mirror of
https://github.com/corda/corda.git
synced 2025-03-14 16:26:36 +00:00
ENT-1940 Improve error checking for the db migration tool (#868)
* ENT-1940 Improve error checking for the db migration tool
This commit is contained in:
parent
2b2b856a17
commit
4d715e4d5c
@ -192,11 +192,11 @@ It has the following command line options:
|
||||
==================================== =======================================================================
|
||||
Option Description
|
||||
==================================== =======================================================================
|
||||
--help Print help message
|
||||
--mode Either 'NODE' or 'DOORMAN'. By default 'NODE'
|
||||
--base-directory(*) The node or doorman directory
|
||||
--help Print help message.
|
||||
--mode Either 'NODE' or 'DOORMAN'. By default 'NODE'.
|
||||
--base-directory(*) The node or doorman directory.
|
||||
--config-file The name of the config file. By default 'node.conf' for a simple node and 'network-management.conf' for a doorman.
|
||||
--doorman-jar-path The path to the doorman fat jar
|
||||
--doorman-jar-path The path to the doorman fat jar.
|
||||
--create-migration-sql-for-cordapp Create migration files for a CorDapp. You can specify the fully qualified name of the `MappedSchema` class. If not specified it will generate the migration for all schemas that don't have migrations. The output directory is the base-directory, where a `migration` folder is created.
|
||||
--dry-run Output the database migration to the specified output file. The output directory is the base-directory. You can specify a file name or 'CONSOLE' if you want to send the output to the console.
|
||||
--execute-migration This option will run the db migration on the configured database. This is the only command that will actually write to the database.
|
||||
@ -207,6 +207,7 @@ For example:
|
||||
|
||||
``java -jar db-migration-tool-R3.CORDA-3.0-DP3-RC01.jar --base-directory /path/to/node --execute-migration``
|
||||
|
||||
.. note:: When running the migration tool, prefer using absolute paths when specifying the "base-directory".
|
||||
|
||||
|
||||
How-To:
|
||||
|
@ -21,6 +21,7 @@ import joptsimple.util.EnumConverter
|
||||
import net.corda.core.internal.MigrationHelpers
|
||||
import net.corda.core.internal.copyTo
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.internal.exists
|
||||
import net.corda.core.schemas.MappedSchema
|
||||
import net.corda.node.internal.DataSourceFactory.createDatasourceFromDriverJarFolders
|
||||
import net.corda.node.internal.cordapp.CordappLoader
|
||||
@ -60,7 +61,8 @@ const val RELEASE_LOCK = "release-lock"
|
||||
// output type
|
||||
const val CONSOLE = "CONSOLE"
|
||||
|
||||
private val logger = LoggerFactory.getLogger("migration.tool")
|
||||
private val migrationLogger = LoggerFactory.getLogger("migration.tool")
|
||||
private val errorLogger = LoggerFactory.getLogger("errors")
|
||||
|
||||
private enum class Mode {
|
||||
NODE, DOORMAN
|
||||
@ -121,7 +123,13 @@ private fun runCommand(options: OptionSet, parser: OptionParser) {
|
||||
options.has(HELP) -> parser.printHelpOn(System.out)
|
||||
mode == Mode.NODE -> {
|
||||
val baseDirectory = baseDirectory()
|
||||
if (!baseDirectory.exists()) {
|
||||
errorAndExit("Could not find base-directory: '$baseDirectory'.")
|
||||
}
|
||||
val config = configFile("node.conf")
|
||||
if (!config.exists()) {
|
||||
errorAndExit("Not a valid node folder. Could not find the config file: '$config'.")
|
||||
}
|
||||
val nodeConfig = ConfigHelper.loadConfig(baseDirectory, config).parseAsNodeConfiguration()
|
||||
val cordappLoader = CordappLoader.createDefault(baseDirectory)
|
||||
|
||||
@ -131,13 +139,16 @@ private fun runCommand(options: OptionSet, parser: OptionParser) {
|
||||
}
|
||||
mode == Mode.DOORMAN -> {
|
||||
val fatJarPath = Paths.get(options.valueOf(DOORMAN_JAR_PATH) as String)
|
||||
if (!fatJarPath.exists()) {
|
||||
errorAndExit("Could not find the doorman jar in location: '$fatJarPath'.")
|
||||
}
|
||||
val doormanClassloader = classLoaderFromCapsuleFatJar(fatJarPath)
|
||||
val doormanSchema = "com.r3.corda.networkmanage.common.persistence.NetworkManagementSchemaServices\$SchemaV1"
|
||||
val schema = loadMappedSchema(doormanSchema, doormanClassloader)
|
||||
handleCommand(options, baseDirectory(), configFile("network-management.conf"), mode, doormanClassloader, setOf(schema))
|
||||
}
|
||||
}
|
||||
logger.info("Done")
|
||||
migrationLogger.info("Done")
|
||||
}
|
||||
|
||||
private fun handleCommand(options: OptionSet, baseDirectory: Path, configFile: Path, mode: Mode, classLoader: ClassLoader, schemas: Set<MappedSchema>) {
|
||||
@ -162,19 +173,19 @@ private fun handleCommand(options: OptionSet, baseDirectory: Path, configFile: P
|
||||
}
|
||||
options.has(DRY_RUN) -> {
|
||||
val writer = getMigrationOutput(baseDirectory, options)
|
||||
logger.info("Exporting the current db migrations ...")
|
||||
migrationLogger.info("Exporting the current db migrations ...")
|
||||
runMigrationCommand {
|
||||
it.generateMigrationScript(writer)
|
||||
}
|
||||
}
|
||||
options.has(RUN_MIGRATION) -> {
|
||||
logger.info("Running the database migration on $baseDirectory")
|
||||
migrationLogger.info("Running the database migration on $baseDirectory")
|
||||
runMigrationCommand { it.runMigration() }
|
||||
}
|
||||
options.has(CREATE_MIGRATION_CORDAPP) && (mode == Mode.NODE) -> {
|
||||
|
||||
fun generateMigrationFileForSchema(schemaClass: String) {
|
||||
logger.info("Creating database migration files for schema: $schemaClass into ${baseDirectory / "migration"}")
|
||||
migrationLogger.info("Creating database migration files for schema: $schemaClass into ${baseDirectory / "migration"}")
|
||||
try {
|
||||
runWithDataSource(config, baseDirectory, classLoader) {
|
||||
MigrationExporter(baseDirectory, config.dataSourceProperties, classLoader, it).generateMigrationForCorDapp(schemaClass)
|
||||
@ -223,11 +234,26 @@ private fun getMigrationOutput(baseDirectory: Path, options: OptionSet): Writer
|
||||
}
|
||||
|
||||
private fun runWithDataSource(config: Configuration, baseDirectory: Path, classLoader: ClassLoader, withDatasource: (DataSource) -> Unit) {
|
||||
val driversFolder = (baseDirectory / "drivers")
|
||||
return withDatasource(createDatasourceFromDriverJarFolders(config.dataSourceProperties, classLoader, listOf(driversFolder) + config.jarDirs.map { Paths.get(it) }))
|
||||
val driversFolder = (baseDirectory / "drivers").let { if (it.exists()) listOf(it) else emptyList() }
|
||||
val jarDirs = config.jarDirs.map { Paths.get(it) }
|
||||
for (jarDir in jarDirs) {
|
||||
if (!jarDir.exists()) {
|
||||
errorAndExit("Could not find the configured JDBC driver directory: '${jarDir}'.")
|
||||
}
|
||||
}
|
||||
|
||||
return try {
|
||||
withDatasource(createDatasourceFromDriverJarFolders(config.dataSourceProperties, classLoader, driversFolder + jarDirs))
|
||||
} catch (e: Exception) {
|
||||
errorAndExit("""Failed to create datasource.
|
||||
|Please check that the correct JDBC driver is installed in one of the following folders:
|
||||
|${(driversFolder + jarDirs).joinToString("\n\t - ", "\t - ")}
|
||||
|Caused By ${e}""".trimMargin(), e)
|
||||
}
|
||||
}
|
||||
|
||||
private fun errorAndExit(message: String?) {
|
||||
private fun errorAndExit(message: String?, exception: Exception? = null) {
|
||||
errorLogger.error(message, exception)
|
||||
System.err.println(message)
|
||||
System.exit(1)
|
||||
}
|
||||
|
@ -26,12 +26,19 @@
|
||||
<File name="File-Appender" fileName="logs/migration.log">
|
||||
<PatternLayout pattern="[%-5level] %date{ISO8601}{UTC}Z [%t] %c{2}.%method - %msg %X%n"/>
|
||||
</File>
|
||||
|
||||
<File name="Errors-File-Appender" fileName="logs/migration-errors.log">
|
||||
<PatternLayout pattern="[%-5level] %date{ISO8601}{UTC}Z [%t] %c{2}.%method - %msg %X%n"/>
|
||||
</File>
|
||||
</Appenders>
|
||||
|
||||
<Loggers>
|
||||
<Root level="${sys:defaultLogLevel}">
|
||||
<AppenderRef ref="File-Appender" />
|
||||
</Root>
|
||||
<Logger name="errors" >
|
||||
<AppenderRef ref="Errors-File-Appender" />
|
||||
</Logger>
|
||||
<Logger name="migration.tool" >
|
||||
<AppenderRef ref="Console-Appender"/>
|
||||
<AppenderRef ref="File-Appender" />
|
||||
|
Loading…
x
Reference in New Issue
Block a user