[ENT-1281]: Disable database.runMigration by default and enforce database version on startup. (#264)

* [ENT-1281]: set database.runMigration=false by default and add state check at startup

* [ENT-1281]: attempt to fix tests

* [ENT-1281]: attempt to fix tests

* [ENT-1281]: set runMigration=true in the cordformation plugin

* [ENT-1281]: attempt to fix tests

* [ENT-1281]: attempt to fix tests

* [ENT-1281]: attempt to fix tests

* [ENT-1281]: fix formatting

* [ENT-1281]: typo and javadocs

* [ENT-1281]: small refactoring and added test for SchemaMigration

* [ENT-1281]: update documentation to reflect changes

* [ENT-1281]: fix tests after merge

* [ENT-1339]: for h2, allow schemas without migrations to run (#294)

* [ENT-1339]: for h2, allow schemas without migrations to run

* [ENT-1339]: fix various migration issues and change author name

* [ENT-1339]: add naming convention for migrations

* [ENT-1339]: change naming convention to use hyphens

* [ENT-1339]: change mapping of participants to be able to control the table name

* [ENT-1339]: change FK names to <=30 for oracle 11g compatibility

* [ENT-1339]: cmd line argument for migrations made consistent

* [ENT-1339]: revert abstract state superclasses

* Update db integration test setup - new tables.

* Update db integration test setup - new tables.

* [ENT-1339]: remove final from participants to allow table name config

* [ENT-1339]: shortened pk

* [ENT-1339]: revert constructor

* [ENT-1339]: change getMigrationResource api to Nullable

* fix compile error

* [ENT-1281]: fix tests after merge

* [ENT-1281]: fix tests after merge
This commit is contained in:
Tudor Malene 2018-01-10 11:32:24 +00:00 committed by GitHub
parent 3c8ebdedae
commit 12546c0a7c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 135 additions and 40 deletions

View File

@ -48,7 +48,8 @@ public class StandaloneCordaRPCJavaClientTest {
port.getAndIncrement(),
port.getAndIncrement(),
true,
Collections.singletonList(rpcUser)
Collections.singletonList(rpcUser),
true
);
@Before

View File

@ -151,6 +151,7 @@ As a database migration tool, we use the open source library liquibase <http://
If migration is enabled, the database state is checked (and updated) during node startup. (After deploying a new version of the code that contains database migrations, they are executed at that point).
Possible database changes range from schema changes to data changes.
If migration is disabled (the default), then on node startup, the database "version" is checked if it is up-to-date with the deployed code.
Liquibase will create a table called ``DATABASECHANGELOG``, that will store useful information about each change ( like timestamp, description, user, md5 hash so it can't be changed, etc)
We can also "tag" the database at each release to make rollback easier.
@ -228,7 +229,7 @@ Usage:
Configurations:
- To enable migration at startup, set:
- database.runMigration = true // true by default
- database.runMigration = true // false by default,
Command line arguments:

View File

@ -87,6 +87,7 @@ class Node(private val project: Project) : CordformNode() {
}
private fun configureProperties() {
config = config.withValue("database.runMigration", ConfigValueFactory.fromAnyRef(true))
config = config.withValue("rpcUsers", ConfigValueFactory.fromIterable(rpcUsers))
if (notary != null) {
config = config.withValue("notary", ConfigValueFactory.fromMap(notary))

View File

@ -17,6 +17,7 @@ import net.corda.finance.DOLLARS
import net.corda.finance.flows.CashIssueAndPaymentFlow
import net.corda.nodeapi.internal.crypto.CertificateAndKeyPair
import net.corda.nodeapi.internal.network.NetworkParameters
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.SerializationEnvironmentRule
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.driver.NodeHandle
@ -136,7 +137,7 @@ class NodeRegistrationTest : IntegrationTest() {
return NetworkManagementServer().apply {
start(
serverAddress,
configureDatabase(makeTestDataSourceProperties()),
configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true)),
LocalSigner(intermediateCa.keyPair, arrayOf(intermediateCa.certificate, rootCaCert)),
networkParameters,
networkParameters?.let { NetworkMapConfig(cacheTimeout = timeoutMillis, signInterval = timeoutMillis) },

View File

@ -89,7 +89,7 @@ class SigningServiceIntegrationTest {
@Test
fun `Signing service signs approved CSRs`() {
//Start doorman server
val database = configureDatabase(makeTestDataSourceProperties())
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true))
NetworkManagementServer().use { server ->
server.start(NetworkHostAndPort(HOST, 0), database, networkMapServiceParameter = null, doormanServiceParameter = DoormanConfig(approveAll = true, approveInterval = 2.seconds.toMillis(), jiraConfig = null), updateNetworkParameters = null)
@ -99,7 +99,7 @@ class SigningServiceIntegrationTest {
doReturn(ALICE_NAME).whenever(it).myLegalName
doReturn(URL("http://${doormanHostAndPort.host}:${doormanHostAndPort.port}")).whenever(it).compatibilityZoneURL
}
val signingServiceStorage = DBSignedCertificateRequestStorage(configureDatabase(makeTestDataSourceProperties()))
val signingServiceStorage = DBSignedCertificateRequestStorage(configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true)))
val hsmSigner = givenSignerSigningAllRequests(signingServiceStorage)
// Poll the database for approved requests
@ -143,7 +143,7 @@ class SigningServiceIntegrationTest {
@Test
fun `DEMO - Create CSR and poll`() {
//Start doorman server
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig())
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true))
NetworkManagementServer().use { server ->
server.start(NetworkHostAndPort(HOST, 0), database, networkMapServiceParameter = null, doormanServiceParameter = DoormanConfig(approveAll = true, approveInterval = 2.seconds.toMillis(), jiraConfig = null), updateNetworkParameters = null)

View File

@ -38,9 +38,7 @@ fun configureDatabase(dataSourceProperties: Properties,
val dataSource = HikariDataSource(config)
val schemas = setOf(NetworkManagementSchemaServices.SchemaV1)
if (databaseConfig.runMigration) {
SchemaMigration(schemas, dataSource, true, databaseConfig.schema).runMigration()
}
SchemaMigration(schemas, dataSource, true, databaseConfig).nodeStartup()
return CordaPersistence(dataSource, databaseConfig, schemas, config.dataSourceProperties.getProperty("url", ""), emptyList())
}

View File

@ -10,6 +10,7 @@ import net.corda.core.identity.CordaX500Name
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.testing.internal.createDevNodeCaCertPath
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import org.assertj.core.api.Assertions.assertThat
import org.bouncycastle.pkcs.PKCS10CertificationRequest
import org.bouncycastle.pkcs.jcajce.JcaPKCS10CertificationRequest
@ -28,7 +29,7 @@ class PersistentCertificateRequestStorageTest : TestBase() {
@Before
fun startDb() {
persistence = configureDatabase(makeTestDataSourceProperties())
persistence = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true))
storage = PersistentCertificateRequestStorage(persistence)
}

View File

@ -12,6 +12,7 @@ import net.corda.nodeapi.internal.crypto.X509CertificateFactory
import net.corda.nodeapi.internal.network.NetworkMap
import net.corda.nodeapi.internal.network.SignedNetworkMap
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.common.internal.testNetworkParameters
import net.corda.testing.internal.TestNodeInfoBuilder
import net.corda.testing.internal.createDevIntermediateCaCertPath
@ -37,7 +38,7 @@ class PersistentNetworkMapStorageTest : TestBase() {
val (rootCa, intermediateCa) = createDevIntermediateCaCertPath()
rootCaCert = rootCa.certificate
this.intermediateCa = intermediateCa
persistence = configureDatabase(makeTestDataSourceProperties())
persistence = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true))
networkMapStorage = PersistentNetworkMapStorage(persistence, LocalSigner(intermediateCa.keyPair, arrayOf(intermediateCa.certificate, rootCaCert)))
nodeInfoStorage = PersistentNodeInfoStorage(persistence)
requestStorage = PersistentCertificateRequestStorage(persistence)

View File

@ -14,6 +14,7 @@ import net.corda.nodeapi.internal.crypto.CertificateType
import net.corda.nodeapi.internal.crypto.X509CertificateFactory
import net.corda.nodeapi.internal.crypto.X509Utilities
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.testing.internal.TestNodeInfoBuilder
import net.corda.testing.internal.createDevIntermediateCaCertPath
import net.corda.testing.internal.signWith
@ -41,7 +42,7 @@ class PersistentNodeInfoStorageTest : TestBase() {
val (rootCa, intermediateCa) = createDevIntermediateCaCertPath()
rootCaCert = rootCa.certificate
this.intermediateCa = intermediateCa
persistence = configureDatabase(MockServices.makeTestDataSourceProperties())
persistence = configureDatabase(MockServices.makeTestDataSourceProperties(), DatabaseConfig(runMigration = true))
nodeInfoStorage = PersistentNodeInfoStorage(persistence)
requestStorage = PersistentCertificateRequestStorage(persistence)
}

View File

@ -18,7 +18,7 @@ const val NODE_DATABASE_PREFIX = "node_"
// This class forms part of the node config and so any changes to it must be handled with care
data class DatabaseConfig(
val runMigration: Boolean = true,
val runMigration: Boolean = false,
val transactionIsolationLevel: TransactionIsolationLevel = TransactionIsolationLevel.REPEATABLE_READ,
val schema: String? = null,
val exportHibernateJMXStatistics: Boolean = false

View File

@ -2,6 +2,7 @@ package net.corda.nodeapi.internal.persistence
import com.fasterxml.jackson.databind.ObjectMapper
import liquibase.Contexts
import liquibase.LabelExpression
import liquibase.Liquibase
import liquibase.database.Database
import liquibase.database.DatabaseFactory
@ -14,17 +15,34 @@ import net.corda.core.utilities.contextLogger
import java.io.*
import javax.sql.DataSource
class SchemaMigration(val schemas: Set<MappedSchema>, val dataSource: DataSource, val failOnMigrationMissing: Boolean, private val schemaName: String? = null) {
class SchemaMigration(val schemas: Set<MappedSchema>, val dataSource: DataSource, val failOnMigrationMissing: Boolean, private val databaseConfig: DatabaseConfig) {
companion object {
private val logger = contextLogger()
}
fun generateMigrationScript(outputFile: File) = doRunMigration(PrintWriter(outputFile))
/**
* Main entry point to the schema migration.
* Called during node startup.
*/
fun nodeStartup() = if (databaseConfig.runMigration) runMigration() else checkState()
fun runMigration() = doRunMigration()
/**
* will run the liquibase migration on the actual database
*/
fun runMigration() = doRunMigration(run = true, outputWriter = null, check = false)
private fun doRunMigration(outputWriter: Writer? = null) {
/**
* will write the migration to the outputFile
*/
fun generateMigrationScript(outputFile: File) = doRunMigration(run = false, outputWriter = PrintWriter(outputFile), check = false)
/**
* ensures that the database is up to date with the latest migration changes
*/
fun checkState() = doRunMigration(run = false, outputWriter = null, check = true)
private fun doRunMigration(run: Boolean, outputWriter: Writer?, check: Boolean) {
// virtual file name of the changelog that includes all schemas
val dynamicInclude = "master.changelog.json"
@ -65,6 +83,7 @@ class SchemaMigration(val schemas: Set<MappedSchema>, val dataSource: DataSource
val liquibase = Liquibase(dynamicInclude, customResourceAccessor, getLiquibaseDatabase(JdbcConnection(connection)))
val schemaName: String? = databaseConfig.schema
if (!schemaName.isNullOrBlank()) {
if (liquibase.database.defaultSchemaName != schemaName) {
logger.debug("defaultSchemaName=${liquibase.database.defaultSchemaName} changed to $schemaName")
@ -79,10 +98,16 @@ class SchemaMigration(val schemas: Set<MappedSchema>, val dataSource: DataSource
logger.info("liquibaseSchemaName=${liquibase.database.liquibaseSchemaName}")
logger.info("outputDefaultSchema=${liquibase.database.outputDefaultSchema}")
if (outputWriter != null) {
liquibase.update(Contexts(), outputWriter)
} else {
liquibase.update(Contexts())
when {
run && !check -> liquibase.update(Contexts())
check && !run -> {
val unRunChanges = liquibase.listUnrunChangeSets(Contexts(), LabelExpression())
if (unRunChanges.isNotEmpty()) {
throw Exception("There are ${unRunChanges.size} outstanding database changes that need to be run. Please use the provided tools to update the database.")
}
}
(outputWriter != null) && !check && !run -> liquibase.update(Contexts(), outputWriter)
else -> throw IllegalStateException("Invalid usage.")
}
}
}

View File

@ -204,14 +204,14 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
fun generateDatabaseSchema(outputFile: String) {
HikariDataSource(HikariConfig(configuration.dataSourceProperties)).use { dataSource ->
val jdbcUrl = configuration.dataSourceProperties.getProperty("url", "")
SchemaMigration(cordappLoader.cordappSchemas, dataSource, !isH2Database(jdbcUrl), configuration.database.schema).generateMigrationScript(File(outputFile))
SchemaMigration(cordappLoader.cordappSchemas, dataSource, !isH2Database(jdbcUrl), configuration.database).generateMigrationScript(File(outputFile))
}
}
fun runDbMigration() {
HikariDataSource(HikariConfig(configuration.dataSourceProperties)).use { dataSource ->
val jdbcUrl = configuration.dataSourceProperties.getProperty("url", "")
SchemaMigration(cordappLoader.cordappSchemas, dataSource, !isH2Database(jdbcUrl), configuration.database.schema).runMigration()
SchemaMigration(cordappLoader.cordappSchemas, dataSource, !isH2Database(jdbcUrl), configuration.database).runMigration()
}
}
@ -887,7 +887,7 @@ fun configureDatabase(dataSourceProperties: Properties,
val jdbcUrl = config.dataSourceProperties.getProperty("url", "")
if (databaseConfig.runMigration) {
SchemaMigration(schemaService.schemaOptions.keys, dataSource, !isH2Database(jdbcUrl), databaseConfig.schema).runMigration()
SchemaMigration(schemaService.schemaOptions.keys, dataSource, !isH2Database(jdbcUrl), databaseConfig).runMigration()
}
return CordaPersistence(dataSource, databaseConfig, schemaService.schemaOptions.keys, jdbcUrl, attributeConverters)

View File

@ -32,7 +32,7 @@ class InteractiveShellTest {
@Before
fun setup() {
InteractiveShell.database = configureDatabase(MockServices.makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
InteractiveShell.database = configureDatabase(MockServices.makeTestDataSourceProperties(), DatabaseConfig(runMigration = true), rigorousMock())
}
@After

View File

@ -49,7 +49,7 @@ class PersistentIdentityServiceTests {
@Before
fun setup() {
identityService = PersistentIdentityService(DEV_ROOT_CA.certificate)
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), identityService)
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true), identityService)
}
@After

View File

@ -81,7 +81,7 @@ class ArtemisMessagingTests {
doReturn(true).whenever(it).useAMQPBridges
}
LogHelper.setLevel(PersistentUniquenessProvider::class)
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true), rigorousMock())
networkMapCache = NetworkMapCacheImpl(PersistentNetworkMapCache(database, emptyList()), rigorousMock())
}

View File

@ -45,7 +45,7 @@ class DBCheckpointStorageTests {
@Before
fun setUp() {
LogHelper.setLevel(PersistentUniquenessProvider::class)
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true), rigorousMock())
newCheckpointStorage()
}

View File

@ -40,7 +40,7 @@ class DBTransactionStorageTests {
fun setUp() {
LogHelper.setLevel(PersistentUniquenessProvider::class)
val dataSourceProps = makeTestDataSourceProperties()
database = configureDatabase(dataSourceProps, DatabaseConfig(), rigorousMock())
database = configureDatabase(dataSourceProps, DatabaseConfig(runMigration = true), rigorousMock())
newTransactionStorage()
}

View File

@ -108,7 +108,7 @@ class HibernateConfigurationTest {
}
}
val schemaService = NodeSchemaService(extraSchemas = setOf(CashSchemaV1, SampleCashSchemaV2, SampleCashSchemaV3, DummyLinearStateSchemaV1, DummyLinearStateSchemaV2, DummyDealStateSchemaV1 ))
database = configureDatabase(dataSourceProps, DatabaseConfig(), identityService, schemaService)
database = configureDatabase(dataSourceProps, DatabaseConfig(runMigration = true), identityService, schemaService)
database.transaction {
hibernateConfig = database.hibernateConfig
// `consumeCash` expects we can self-notarise transactions

View File

@ -44,7 +44,7 @@ class NodeAttachmentStorageTest {
LogHelper.setLevel(PersistentUniquenessProvider::class)
val dataSourceProperties = makeTestDataSourceProperties()
database = configureDatabase(dataSourceProperties, DatabaseConfig(), rigorousMock())
database = configureDatabase(dataSourceProperties, DatabaseConfig(runMigration = true), rigorousMock())
fs = Jimfs.newFileSystem(Configuration.unix())
}

View File

@ -0,0 +1,59 @@
package net.corda.node.services.persistence
import com.zaxxer.hikari.HikariConfig
import com.zaxxer.hikari.HikariDataSource
import net.corda.node.internal.configureDatabase
import net.corda.node.services.schema.NodeSchemaService
import net.corda.nodeapi.internal.persistence.CordaPersistence
import net.corda.nodeapi.internal.persistence.DatabaseConfig
import net.corda.nodeapi.internal.persistence.SchemaMigration
import net.corda.testing.internal.rigorousMock
import net.corda.testing.node.MockServices
import org.assertj.core.api.Assertions.assertThat
import org.assertj.core.api.Assertions.assertThatExceptionOfType
import org.junit.Test
import java.math.BigInteger
class SchemaMigrationTest {
@Test
fun `Ensure that runMigration is disabled by default`() {
assertThat(DatabaseConfig().runMigration).isFalse()
}
@Test
fun `Migration is run when runMigration is disabled, and database is H2`() {
val dataSourceProps = MockServices.makeTestDataSourceProperties()
val db = configureDatabase(dataSourceProps, DatabaseConfig(runMigration = false), rigorousMock())
checkMigrationRun(db)
}
@Test
fun `Migration is run when runMigration is enabled`() {
val dataSourceProps = MockServices.makeTestDataSourceProperties()
val db = configureDatabase(dataSourceProps, DatabaseConfig(runMigration = true), rigorousMock())
checkMigrationRun(db)
}
@Test
fun `Verification passes when migration is run as a separate step`() {
val schemaService = NodeSchemaService()
val dataSourceProps = MockServices.makeTestDataSourceProperties()
//run the migration on the database
val migration = SchemaMigration(schemaService.schemaOptions.keys, HikariDataSource(HikariConfig(dataSourceProps)), true, DatabaseConfig())
migration.runMigration()
//start the node with "runMigration = false" and check that it started correctly
val db = configureDatabase(dataSourceProps, DatabaseConfig(runMigration = false), rigorousMock(), schemaService)
checkMigrationRun(db)
}
private fun checkMigrationRun(db: CordaPersistence) {
//check that the hibernate_sequence was created which means the migration was run
db.transaction {
val value = this.session.createNativeQuery("SELECT NEXT VALUE FOR hibernate_sequence").uniqueResult() as BigInteger
assertThat(value).isGreaterThan(BigInteger.ZERO)
}
}
}

View File

@ -69,7 +69,7 @@ class HibernateObserverTests {
return parent
}
}
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock(), schemaService)
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true), rigorousMock(), schemaService)
HibernateObserver.install(rawUpdatesPublisher, database.hibernateConfig, schemaService)
database.transaction {
val MEGA_CORP = TestIdentity(CordaX500Name("MegaCorp", "London", "GB")).party

View File

@ -88,7 +88,7 @@ class DistributedImmutableMapTests {
private fun createReplica(myAddress: NetworkHostAndPort, clusterAddress: NetworkHostAndPort? = null): CompletableFuture<Member> {
val storage = Storage.builder().withStorageLevel(StorageLevel.MEMORY).build()
val address = Address(myAddress.host, myAddress.port)
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true), rigorousMock())
databases.add(database)
val stateMachineFactory = { DistributedImmutableMap(database, RaftUniquenessProvider.Companion::createMap) }

View File

@ -29,7 +29,7 @@ class PersistentUniquenessProviderTests {
@Before
fun setUp() {
LogHelper.setLevel(PersistentUniquenessProvider::class)
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true), rigorousMock())
}
@After

View File

@ -131,7 +131,7 @@ open class VaultQueryTests {
@Ignore
@Test
fun createPersistentTestDb() {
val database = configureDatabase(makePersistentDataSourceProperties(), DatabaseConfig(), identitySvc)
val database = configureDatabase(makePersistentDataSourceProperties(), DatabaseConfig(runMigration = true), identitySvc)
setUpDb(database, 5000)
database.close()

View File

@ -22,7 +22,7 @@ class ObservablesTests {
private val toBeClosed = mutableListOf<Closeable>()
private fun createDatabase(): CordaPersistence {
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
val database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true), rigorousMock())
toBeClosed += database
return database
}

View File

@ -74,7 +74,7 @@ class NodeInterestRatesTest {
@Before
fun setUp() {
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(), rigorousMock())
database = configureDatabase(makeTestDataSourceProperties(), DatabaseConfig(runMigration = true), rigorousMock())
database.transaction {
oracle = createMockCordaService(services, NodeInterestRates::Oracle)
oracle.knownFixes = TEST_DATA

View File

@ -107,7 +107,7 @@ open class MockServices private constructor(
val transactionIsolationLevel = if (config.hasPath(TRANSACTION_ISOLATION_LEVEL)) TransactionIsolationLevel.valueOf(config.getString(TRANSACTION_ISOLATION_LEVEL))
else TransactionIsolationLevel.READ_COMMITTED
val schema = if (config.hasPath(SCHEMA)) config.getString(SCHEMA) else ""
return DatabaseConfig(transactionIsolationLevel = transactionIsolationLevel, schema = schema)
return DatabaseConfig(runMigration = true, transactionIsolationLevel = transactionIsolationLevel, schema = schema)
}
/**

View File

@ -209,6 +209,7 @@ class DriverDSLImpl(
baseDirectory = baseDirectory(name),
allowMissingConfig = true,
configOverrides = configOf(
"database" to mapOf("runMigration" to "true"),
"myLegalName" to name.toString(),
"p2pAddress" to p2pAddress.toString(),
"rpcAddress" to rpcAddress.toString(),
@ -227,6 +228,7 @@ class DriverDSLImpl(
baseDirectory = baseDirectory,
allowMissingConfig = true,
configOverrides = configOf(
"database" to mapOf("runMigration" to "true"),
"p2pAddress" to "localhost:1222", // required argument, not really used
"compatibilityZoneURL" to compatibilityZoneURL.toString(),
"myLegalName" to providedName.toString())
@ -313,7 +315,8 @@ class DriverDSLImpl(
baseDirectory = baseDirectory(name),
allowMissingConfig = true,
configOverrides = cordform.config + rpcAddress + notary + mapOf(
"rpcUsers" to if (rpcUsers.isEmpty()) defaultRpcUserList else rpcUsers
"rpcUsers" to if (rpcUsers.isEmpty()) defaultRpcUserList else rpcUsers,
"database" to mapOf("runMigration" to "true")
)
))
return startNodeInternal(config, webAddress, null, "200m", localNetworkMap)

View File

@ -91,6 +91,7 @@ abstract class NodeBasedTest(private val cordappPackages: List<String> = emptyLi
baseDirectory = baseDirectory,
allowMissingConfig = true,
configOverrides = configOf(
"database" to mapOf("runMigration" to "true"),
"myLegalName" to legalName.toString(),
"p2pAddress" to p2pAddress,
"rpcAddress" to localPort[1].toString(),

View File

@ -14,7 +14,8 @@ class NodeConfig(
val rpcPort: Int,
val webPort: Int,
val isNotary: Boolean,
val users: List<User>
val users: List<User>,
val runMigration: Boolean = true
) {
companion object {
val renderOptions: ConfigRenderOptions = ConfigRenderOptions.defaults().setOriginComments(false)
@ -34,6 +35,7 @@ class NodeConfig(
.withValue("webAddress", addressValueFor(webPort))
.withValue("rpcAddress", addressValueFor(rpcPort))
.withValue("rpcUsers", valueFor(users.map(User::toMap).toList()))
.withValue("database", valueFor(mapOf("runMigration" to runMigration)))
.withValue("useTestClock", valueFor(true))
return if (isNotary) {
config.withValue("notary", ConfigValueFactory.fromMap(mapOf("validating" to true)))