diff --git a/.idea/compiler.xml b/.idea/compiler.xml
index ef69357c69..e0cf3b031c 100644
--- a/.idea/compiler.xml
+++ b/.idea/compiler.xml
@@ -43,14 +43,16 @@
+
+
+
+
-
-
@@ -326,4 +328,4 @@
-
+
\ No newline at end of file
diff --git a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt
index 4c35473fe7..fee301b3f7 100644
--- a/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt
+++ b/core/src/main/kotlin/net/corda/core/internal/InternalUtils.kt
@@ -515,8 +515,3 @@ fun SerializedBytes.checkPayloadIs(type: Class): Untrustworthy
return type.castIfPossible(payloadData)?.let { UntrustworthyData(it) }
?: throw IllegalArgumentException("We were expecting a ${type.name} but we instead got a ${payloadData.javaClass.name} ($payloadData)")
}
-
-/**
- * Extension method to make this method visible to nodeapi module.
- */
-fun MappedSchema.getMigrationResource(): String? = this.internalGetMigrationResource()
\ No newline at end of file
diff --git a/experimental/flow-worker/src/main/kotlin/net/corda/flowworker/FlowWorkerServiceHub.kt b/experimental/flow-worker/src/main/kotlin/net/corda/flowworker/FlowWorkerServiceHub.kt
index fc6be347ec..e10ed86091 100644
--- a/experimental/flow-worker/src/main/kotlin/net/corda/flowworker/FlowWorkerServiceHub.kt
+++ b/experimental/flow-worker/src/main/kotlin/net/corda/flowworker/FlowWorkerServiceHub.kt
@@ -54,6 +54,7 @@ import net.corda.node.utilities.AffinityExecutor
import net.corda.nodeapi.internal.DEV_ROOT_CA
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.persistence.CordaPersistence
+import net.corda.nodeapi.internal.persistence.isH2Database
import net.corda.serialization.internal.*
import org.apache.activemq.artemis.utils.ReusableLatch
import rx.schedulers.Schedulers
@@ -242,7 +243,10 @@ class FlowWorkerServiceHub(override val configuration: NodeConfiguration, overri
servicesForResolution.start(networkParameters)
persistentNetworkMapCache.start(networkParameters.notaries)
- database.startHikariPool(configuration.dataSourceProperties, configuration.database, schemaService)
+ val isH2Database = isH2Database(configuration.dataSourceProperties.getProperty("dataSource.url", ""))
+ val schemas = if (isH2Database) schemaService.internalSchemas() else schemaService.schemaOptions.keys
+
+ database.startHikariPool(configuration.dataSourceProperties, configuration.database, schemas)
identityService.start(trustRoot, listOf(myInfo.legalIdentitiesAndCerts.first().certificate, nodeCa))
database.transaction {
diff --git a/node-api/build.gradle b/node-api/build.gradle
index 01452cb19c..2aa8f97de4 100644
--- a/node-api/build.gradle
+++ b/node-api/build.gradle
@@ -63,11 +63,6 @@ dependencies {
// For caches rather than guava
compile "com.github.ben-manes.caffeine:caffeine:$caffeine_version"
- // For db migration
- compile "org.liquibase:liquibase-core:$liquibase_version"
- compile "com.fasterxml.jackson.core:jackson-databind:$jackson_version"
- runtime 'com.mattbertolini:liquibase-slf4j:2.0.0'
-
// Unit testing helpers.
testCompile "junit:junit:$junit_version"
testCompile "org.assertj:assertj-core:$assertj_version"
diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/MigrationHelpers.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/MigrationHelpers.kt
index b098574556..96686008fd 100644
--- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/MigrationHelpers.kt
+++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/MigrationHelpers.kt
@@ -34,7 +34,7 @@ object MigrationHelpers {
}
// SchemaName will be transformed from camel case to lower_hyphen then add ".changelog-master"
- private fun migrationResourceNameForSchema(schema: MappedSchema): String {
+ fun migrationResourceNameForSchema(schema: MappedSchema): String {
val name: String = schema::class.simpleName!!
val fileName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_HYPHEN, name)
return "$MIGRATION_PREFIX/$fileName.$CHANGELOG_NAME"
diff --git a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/SchemaMigration.kt b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/SchemaMigration.kt
index 0d15b28268..3364c7a468 100644
--- a/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/SchemaMigration.kt
+++ b/node-api/src/main/kotlin/net/corda/nodeapi/internal/persistence/SchemaMigration.kt
@@ -42,13 +42,13 @@ class SchemaMigration(
* Main entry point to the schema migration.
* Called during node startup.
*/
- fun nodeStartup(existingCheckpoints: Boolean) {
+ fun nodeStartup(existingCheckpoints: Boolean, isH2Database: Boolean) {
when {
- databaseConfig.initialiseSchema -> {
- //TODO if it's h2 only
+ databaseConfig.initialiseSchema && isH2Database -> {
migrateOlderDatabaseToUseLiquibase(existingCheckpoints)
runMigration(existingCheckpoints)
}
+ databaseConfig.initialiseSchema -> runMigration(existingCheckpoints)
else -> checkState()
}
}
@@ -66,7 +66,7 @@ class SchemaMigration(
/**
* Ensures that the database is up to date with the latest migration changes.
*/
- private fun checkState() = doRunMigration(run = false, outputWriter = null, check = true)
+ fun checkState() = doRunMigration(run = false, outputWriter = null, check = true)
/**
* Can be used from an external tool to release the lock in case something went terribly wrong.
@@ -138,7 +138,6 @@ class SchemaMigration(
check && !run && unRunChanges.isNotEmpty() -> throw OutstandingDatabaseChangesException(unRunChanges.size)
check && !run -> {} // Do nothing will be interpreted as "check succeeded"
(outputWriter != null) && !check && !run -> liquibase.update(Contexts(), outputWriter)
- (outputWriter != null) && !check && !run -> liquibase.update(Contexts(), outputWriter)
else -> throw IllegalStateException("Invalid usage.")
}
}
diff --git a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt
index f0de64bf0d..a7fe619f9a 100644
--- a/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt
+++ b/node/src/main/kotlin/net/corda/node/internal/AbstractNode.kt
@@ -149,8 +149,7 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
configuration.database,
identityService::wellKnownPartyFromX500Name,
identityService::wellKnownPartyFromAnonymous,
- schemaService,
- configuration.dataSourceProperties
+ schemaService
)
init {
// TODO Break cyclic dependency
@@ -1049,11 +1048,10 @@ fun configureDatabase(hikariProperties: Properties,
databaseConfig: DatabaseConfig,
wellKnownPartyFromX500Name: (CordaX500Name) -> Party?,
wellKnownPartyFromAnonymous: (AbstractParty) -> Party?,
- schemaService: NodeSchemaService = NodeSchemaService()): CordaPersistence {
-
+ schemaService: SchemaService = NodeSchemaService()): CordaPersistence {
val isH2Database = isH2Database(hikariProperties.getProperty("dataSource.url", ""))
- val schemas = if (isH2Database) schemaService.internalSchemas() else schemaService.schemaOptions.keys
- createCordaPersistence(databaseConfig, wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous, schemaService)
+ val schemas = if (isH2Database) NodeSchemaService().internalSchemas() else NodeSchemaService().schemaOptions.keys
+ return createCordaPersistence(databaseConfig, wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous, schemaService)
.apply { startHikariPool(hikariProperties, databaseConfig, schemas) }
}
@@ -1061,16 +1059,14 @@ fun configureDatabase(hikariProperties: Properties,
fun createCordaPersistence(databaseConfig: DatabaseConfig,
wellKnownPartyFromX500Name: (CordaX500Name) -> Party?,
wellKnownPartyFromAnonymous: (AbstractParty) -> Party?,
- schemaService: SchemaService,
- hikariProperties: Properties): CordaPersistence {
+ schemaService: SchemaService): CordaPersistence {
// Register the AbstractPartyDescriptor so Hibernate doesn't warn when encountering AbstractParty. Unfortunately
// Hibernate warns about not being able to find a descriptor if we don't provide one, but won't use it by default
// so we end up providing both descriptor and converter. We should re-examine this in later versions to see if
// either Hibernate can be convinced to stop warning, use the descriptor by default, or something else.
JavaTypeDescriptorRegistry.INSTANCE.addDescriptor(AbstractPartyDescriptor(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
val attributeConverters = listOf(AbstractPartyToX500NameAsStringConverter(wellKnownPartyFromX500Name, wellKnownPartyFromAnonymous))
- val jdbcUrl = hikariProperties.getProperty("dataSource.url", "")
- return CordaPersistence(databaseConfig, schemaService.schemaOptions.keys, jdbcUrl, attributeConverters)
+ return CordaPersistence(databaseConfig, schemaService.schemaOptions.keys, attributeConverters)
}
fun CordaPersistence.startHikariPool(hikariProperties: Properties, databaseConfig: DatabaseConfig, schemas: Set) {
@@ -1078,7 +1074,7 @@ fun CordaPersistence.startHikariPool(hikariProperties: Properties, databaseConfi
val dataSource = DataSourceFactory.createDataSource(hikariProperties)
val jdbcUrl = hikariProperties.getProperty("dataSource.url", "")
val schemaMigration = SchemaMigration(schemas, dataSource, databaseConfig)
- schemaMigration.nodeStartup(dataSource.connection.use { DBCheckpointStorage().getCheckpointCount(it) != 0L })
+ schemaMigration.nodeStartup(dataSource.connection.use { DBCheckpointStorage().getCheckpointCount(it) != 0L }, isH2Database(jdbcUrl))
start(dataSource, jdbcUrl)
} catch (ex: Exception) {
when {
diff --git a/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt b/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt
index 2b60955184..5ba3223ea8 100644
--- a/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt
+++ b/node/src/main/kotlin/net/corda/node/services/schema/NodeSchemaService.kt
@@ -75,10 +75,13 @@ class NodeSchemaService(private val extraSchemas: Set = emptySet()
// Required schemas are those used by internal Corda services
private val requiredSchemas: Map =
mapOf(Pair(CommonSchemaV1, SchemaOptions()),
- Pair(VaultSchemaV1, SchemaOptions()),
- Pair(NodeInfoSchemaV1, SchemaOptions()),
- Pair(NodeCoreV1, SchemaOptions())) +
- if (includeNotarySchemas) mapOf(Pair(NodeNotaryV1, SchemaOptions())) else emptyMap()
+ Pair(VaultSchemaV1, SchemaOptions()),
+ Pair(NodeInfoSchemaV1, SchemaOptions()),
+ Pair(NodeCoreV1, SchemaOptions())) +
+ if (includeNotarySchemas) mapOf(Pair(NodeNotaryV1, SchemaOptions())) else emptyMap()
+
+ fun internalSchemas() = requiredSchemas.keys + extraSchemas.filter { schema -> // when mapped schemas from the finance module are present, they are considered as internal ones
+ schema::class.simpleName == "net.corda.finance.schemas.CashSchemaV1" || schema::class.simpleName == "net.corda.finance.schemas.CommercialPaperSchemaV1" }
override val schemaOptions: Map = requiredSchemas + extraSchemas.associateBy({ it }, { SchemaOptions() })
diff --git a/node/src/test/kotlin/net/corda/node/services/persistence/SchemaMigrationTest.kt b/node/src/test/kotlin/net/corda/node/services/persistence/SchemaMigrationTest.kt
index 35ecb94c26..ec0289ef68 100644
--- a/node/src/test/kotlin/net/corda/node/services/persistence/SchemaMigrationTest.kt
+++ b/node/src/test/kotlin/net/corda/node/services/persistence/SchemaMigrationTest.kt
@@ -60,7 +60,7 @@ class SchemaMigrationTest {
val dataSourceProps = MockServices.makeTestDataSourceProperties()
//run the migration on the database
- val migration = SchemaMigration(schemaService.schemaOptions.keys, HikariDataSource(HikariConfig(dataSourceProps)), true, DatabaseConfig())
+ val migration = SchemaMigration(schemaService.schemaOptions.keys, HikariDataSource(HikariConfig(dataSourceProps)), DatabaseConfig())
migration.runMigration(false)
//start the node with "runMigration = false" and check that it started correctly
diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt
index 59aaf19db4..8c1f5dd7e5 100644
--- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt
+++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/MockServices.kt
@@ -114,7 +114,6 @@ open class MockServices private constructor(
val cordappLoader = cordappLoaderForPackages(cordappPackages)
val dataSourceProps = makeInternalTestDataSourceProperties(initialIdentity.name.organisation, SecureHash.randomSHA256().toString())
val schemaService = NodeSchemaService(cordappLoader.cordappSchemas)
- //TODO different schemas based on h2 or not
val database = configureDatabase(dataSourceProps, makeTestDatabaseProperties(initialIdentity.name.organisation), identityService::wellKnownPartyFromX500Name, identityService::wellKnownPartyFromAnonymous, schemaService)
val mockService = database.transaction {
object : MockServices(cordappLoader, identityService, networkParameters, initialIdentity, moreKeys) {
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 c282dc289b..4cd857126d 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
@@ -169,12 +169,12 @@ private fun handleCommand(options: OptionSet, baseDirectory: Path, configFile: P
val config = parsedConfig.parseAs(Configuration::class, UnknownConfigKeysPolicy.IGNORE::handle)
fun runMigrationCommand(withMigration: (SchemaMigration, DataSource) -> Unit): Unit = runWithDataSource(config, baseDirectory, classLoader) { dataSource ->
- withMigration(SchemaMigration(schemas, dataSource, true, config.database, classLoader), dataSource)
+ withMigration(SchemaMigration(schemas, dataSource, config.database, classLoader), dataSource)
}
when {
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()
+ SchemaMigration(emptySet(), it, config.database, Thread.currentThread().contextClassLoader).forceReleaseMigrationLock()
}
options.has(DRY_RUN) -> {
val writer = getMigrationOutput(baseDirectory, options)