mirror of
https://github.com/corda/corda.git
synced 2024-12-28 00:38:55 +00:00
Merge pull request #587 from corda/feature/ENT-1637/migration-tool-changes
ENT-1673 Update migration tool to use the drivers folder and created reusable "createDatasourceFromDriverJars" function
This commit is contained in:
commit
72b97be42c
@ -14,10 +14,14 @@ import com.zaxxer.hikari.HikariConfig
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
import com.zaxxer.hikari.util.PropertyElf
|
||||
import net.corda.core.internal.declaredField
|
||||
import net.corda.core.internal.div
|
||||
import org.h2.engine.Database
|
||||
import org.h2.engine.Engine
|
||||
import org.slf4j.LoggerFactory
|
||||
import java.lang.reflect.Modifier
|
||||
import java.net.URLClassLoader
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.*
|
||||
import javax.sql.DataSource
|
||||
|
||||
@ -53,4 +57,28 @@ object DataSourceFactory {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun createDatasourceFromDriverJars(dataSourceProperties: Properties, baseClassLoader: ClassLoader, driverJarsPath: Path): DataSource {
|
||||
return URLClassLoader(Files.newDirectoryStream(driverJarsPath, "*.jar").map { it.toUri().toURL() }.toTypedArray(), baseClassLoader).use { driversClassLoader ->
|
||||
val dataSourceClassName = dataSourceProperties["dataSourceClassName"] as String?
|
||||
val dataSourceClass = driversClassLoader.loadClass(dataSourceClassName)
|
||||
val dataSourceInstance = dataSourceClass.newInstance() as DataSource
|
||||
|
||||
val props = Properties().also {
|
||||
it.putAll(dataSourceProperties.propertyNames().toList()
|
||||
.filter { name -> (name as String).startsWith("dataSource.") }
|
||||
.map { name -> (name as String).substring("dataSource.".length) to (dataSourceProperties[name]) }.toMap())
|
||||
}
|
||||
PropertyElf.setTargetFromProperties(dataSourceInstance, props)
|
||||
|
||||
dataSourceInstance
|
||||
}
|
||||
}
|
||||
|
||||
fun createHikariDatasourceFromDriverJars(dataSourceProperties: Properties, baseClassLoader: ClassLoader, driverJarsPath: Path): DataSource {
|
||||
val dataSource = createDatasourceFromDriverJars(dataSourceProperties, baseClassLoader, driverJarsPath)
|
||||
val cfg = HikariConfig(dataSourceProperties)
|
||||
cfg.dataSource = dataSource
|
||||
return HikariDataSource(cfg)
|
||||
}
|
||||
}
|
@ -37,6 +37,7 @@ dependencies{
|
||||
|
||||
shadowJar {
|
||||
transform(de.sebastianboegl.gradle.plugins.shadow.transformers.Log4j2PluginsFileTransformer)
|
||||
archiveName = "migration-tool-${version}.jar"
|
||||
}
|
||||
|
||||
|
||||
task buildMigrationTool(dependsOn: shadowJar)
|
@ -13,8 +13,7 @@
|
||||
package com.r3.corda.dbmigration
|
||||
|
||||
import com.typesafe.config.ConfigFactory
|
||||
import com.zaxxer.hikari.HikariConfig
|
||||
import com.zaxxer.hikari.HikariDataSource
|
||||
import com.zaxxer.hikari.util.PropertyElf
|
||||
import joptsimple.OptionException
|
||||
import joptsimple.OptionParser
|
||||
import joptsimple.OptionSet
|
||||
@ -23,6 +22,7 @@ import net.corda.core.internal.MigrationHelpers
|
||||
import net.corda.core.internal.copyTo
|
||||
import net.corda.core.internal.div
|
||||
import net.corda.core.schemas.MappedSchema
|
||||
import net.corda.node.internal.DataSourceFactory.createDatasourceFromDriverJars
|
||||
import net.corda.node.internal.cordapp.CordappLoader
|
||||
import net.corda.node.services.config.ConfigHelper
|
||||
import net.corda.node.services.config.parseAsNodeConfiguration
|
||||
@ -37,6 +37,7 @@ import java.io.FileWriter
|
||||
import java.io.PrintWriter
|
||||
import java.io.Writer
|
||||
import java.net.URLClassLoader
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.Paths
|
||||
import java.text.SimpleDateFormat
|
||||
@ -71,7 +72,7 @@ private fun initOptionParser(): OptionParser = OptionParser().apply {
|
||||
.defaultsTo(Mode.NODE)
|
||||
|
||||
accepts(BASE_DIRECTORY, "The node or doorman directory")
|
||||
.withRequiredArg()
|
||||
.withRequiredArg().required()
|
||||
|
||||
accepts(CONFIG, "The name of the config file. By default 'node.conf' for a simple node and 'network-management.conf' for a doorman.")
|
||||
.withOptionalArg()
|
||||
@ -141,12 +142,12 @@ private fun runCommand(options: OptionSet, parser: OptionParser) {
|
||||
private fun handleCommand(options: OptionSet, baseDirectory: Path, configFile: Path, mode: Mode, classLoader: ClassLoader, schemas: Set<MappedSchema>) {
|
||||
val config = ConfigFactory.parseFile(configFile.toFile()).resolve().parseAs(Configuration::class, false)
|
||||
|
||||
fun runMigrationCommand(withMigration: (SchemaMigration) -> Unit): Unit = runWithDataSource(config) { dataSource ->
|
||||
fun runMigrationCommand(withMigration: (SchemaMigration) -> Unit): Unit = runWithDataSource(config, baseDirectory, classLoader) { dataSource ->
|
||||
withMigration(SchemaMigration(schemas, dataSource, true, config.database, classLoader))
|
||||
}
|
||||
|
||||
when {
|
||||
options.has(RELEASE_LOCK) -> runWithDataSource(ConfigFactory.parseFile(configFile.toFile()).resolve().parseAs(Configuration::class)) {
|
||||
options.has(RELEASE_LOCK) -> runWithDataSource(ConfigFactory.parseFile(configFile.toFile()).resolve().parseAs(Configuration::class), baseDirectory, classLoader) {
|
||||
SchemaMigration(emptySet(), it, true, config.database, Thread.currentThread().contextClassLoader).forceReleaseMigrationLock()
|
||||
}
|
||||
options.has(DRY_RUN) -> {
|
||||
@ -165,7 +166,7 @@ private fun handleCommand(options: OptionSet, baseDirectory: Path, configFile: P
|
||||
fun generateMigrationFileForSchema(schemaClass: String) {
|
||||
logger.info("Creating database migration files for schema: $schemaClass into ${baseDirectory / "migration"}")
|
||||
try {
|
||||
runWithDataSource(config) {
|
||||
runWithDataSource(config, baseDirectory, classLoader) {
|
||||
MigrationExporter(baseDirectory, config.dataSourceProperties, classLoader, it).generateMigrationForCorDapp(schemaClass)
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@ -211,12 +212,9 @@ private fun getMigrationOutput(baseDirectory: Path, options: OptionSet): Writer
|
||||
}
|
||||
}
|
||||
|
||||
private fun runWithDataSource(config: Configuration, withDatasource: (DataSource) -> Unit) {
|
||||
val cfg = HikariConfig(config.dataSourceProperties)
|
||||
cfg.maximumPoolSize = 1
|
||||
return HikariDataSource(cfg).use { dataSource ->
|
||||
withDatasource(dataSource)
|
||||
}
|
||||
private fun runWithDataSource(config: Configuration, baseDirectory: Path, classLoader: ClassLoader, withDatasource: (DataSource) -> Unit) {
|
||||
val driversFolder = baseDirectory / "drivers"
|
||||
return withDatasource(createDatasourceFromDriverJars(config.dataSourceProperties, classLoader, driversFolder))
|
||||
}
|
||||
|
||||
private fun errorAndExit(message: String?) {
|
||||
|
Loading…
Reference in New Issue
Block a user