From 882b18184f74a5f898ac107660997c459ba67df9 Mon Sep 17 00:00:00 2001 From: Tudor Malene Date: Tue, 20 Mar 2018 17:29:14 +0000 Subject: [PATCH 1/2] sqlserver --- tools/dbmigration/build.gradle | 3 +- .../com/r3/corda/dbmigration/Launcher.kt | 33 ++++++++++++------- 2 files changed, 24 insertions(+), 12 deletions(-) diff --git a/tools/dbmigration/build.gradle b/tools/dbmigration/build.gradle index 0bf49b19f9..99c49304f9 100644 --- a/tools/dbmigration/build.gradle +++ b/tools/dbmigration/build.gradle @@ -37,6 +37,7 @@ dependencies{ shadowJar { transform(de.sebastianboegl.gradle.plugins.shadow.transformers.Log4j2PluginsFileTransformer) + archiveName = "migration-tool-${version}.jar" } - +task buildMigrationTool(dependsOn: shadowJar) \ No newline at end of file diff --git a/tools/dbmigration/src/main/kotlin/com/r3/corda/dbmigration/Launcher.kt b/tools/dbmigration/src/main/kotlin/com/r3/corda/dbmigration/Launcher.kt index e6a3d08a2d..dc82cd9e66 100644 --- a/tools/dbmigration/src/main/kotlin/com/r3/corda/dbmigration/Launcher.kt +++ b/tools/dbmigration/src/main/kotlin/com/r3/corda/dbmigration/Launcher.kt @@ -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 @@ -37,6 +36,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 +71,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 +141,12 @@ private fun runCommand(options: OptionSet, parser: OptionParser) { private fun handleCommand(options: OptionSet, baseDirectory: Path, configFile: Path, mode: Mode, classLoader: ClassLoader, schemas: Set) { 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 +165,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,11 +211,22 @@ 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" + val dataSourceClass = config.dataSourceProperties["dataSourceClassName"] as String? + + return URLClassLoader(Files.newDirectoryStream(driversFolder, "*.jar").map { it.toUri().toURL() }.toTypedArray(), classLoader).use { driversClassLoader -> + val driverClass = driversClassLoader.loadClass(dataSourceClass) + val dataSourceInstance = driverClass.newInstance() as DataSource + + val props = Properties().also { + it.putAll(config.dataSourceProperties.propertyNames().toList() + .filter { name -> (name as String).startsWith("dataSource.") } + .map { name -> (name as String).substring("dataSource.".length) to (config.dataSourceProperties[name]) }.toMap()) + } + PropertyElf.setTargetFromProperties(dataSourceInstance, props) + + withDatasource(dataSourceInstance) } } From 8371a65ed80541739aba55498e87428685d7f434 Mon Sep 17 00:00:00 2001 From: Tudor Malene Date: Wed, 21 Mar 2018 15:29:46 +0000 Subject: [PATCH 2/2] ENT-1673 Created reusable "createDatasourceFromDriverJars" function --- .../corda/node/internal/DataSourceFactory.kt | 30 ++++++++++++++++++- .../com/r3/corda/dbmigration/Launcher.kt | 17 ++--------- 2 files changed, 31 insertions(+), 16 deletions(-) diff --git a/node/src/main/kotlin/net/corda/node/internal/DataSourceFactory.kt b/node/src/main/kotlin/net/corda/node/internal/DataSourceFactory.kt index b9f99dff37..7304fa22cc 100644 --- a/node/src/main/kotlin/net/corda/node/internal/DataSourceFactory.kt +++ b/node/src/main/kotlin/net/corda/node/internal/DataSourceFactory.kt @@ -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) + } +} \ No newline at end of file diff --git a/tools/dbmigration/src/main/kotlin/com/r3/corda/dbmigration/Launcher.kt b/tools/dbmigration/src/main/kotlin/com/r3/corda/dbmigration/Launcher.kt index dc82cd9e66..84162ec370 100644 --- a/tools/dbmigration/src/main/kotlin/com/r3/corda/dbmigration/Launcher.kt +++ b/tools/dbmigration/src/main/kotlin/com/r3/corda/dbmigration/Launcher.kt @@ -22,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 @@ -213,21 +214,7 @@ private fun getMigrationOutput(baseDirectory: Path, options: OptionSet): Writer private fun runWithDataSource(config: Configuration, baseDirectory: Path, classLoader: ClassLoader, withDatasource: (DataSource) -> Unit) { val driversFolder = baseDirectory / "drivers" - val dataSourceClass = config.dataSourceProperties["dataSourceClassName"] as String? - - return URLClassLoader(Files.newDirectoryStream(driversFolder, "*.jar").map { it.toUri().toURL() }.toTypedArray(), classLoader).use { driversClassLoader -> - val driverClass = driversClassLoader.loadClass(dataSourceClass) - val dataSourceInstance = driverClass.newInstance() as DataSource - - val props = Properties().also { - it.putAll(config.dataSourceProperties.propertyNames().toList() - .filter { name -> (name as String).startsWith("dataSource.") } - .map { name -> (name as String).substring("dataSource.".length) to (config.dataSourceProperties[name]) }.toMap()) - } - PropertyElf.setTargetFromProperties(dataSourceInstance, props) - - withDatasource(dataSourceInstance) - } + return withDatasource(createDatasourceFromDriverJars(config.dataSourceProperties, classLoader, driversFolder)) } private fun errorAndExit(message: String?) {