diff --git a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt index 2d9cde9b38..2cfd313256 100644 --- a/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt +++ b/client/rpc/src/integration-test/kotlin/net/corda/client/rpc/FlowsExecutionModeRpcTest.kt @@ -30,7 +30,7 @@ class FlowsExecutionModeRpcTest { assumeFalse(System.getProperty("os.name").toLowerCase().startsWith("win")) val user = User("mark", "dadada", setOf(invokeRpc("setFlowsDrainingModeEnabled"), invokeRpc("isFlowsDrainingModeEnabled"))) - driver(DriverParameters(isDebug = true, startNodesInProcess = true)) { + driver(DriverParameters(isDebug = true, inMemoryDB = false, startNodesInProcess = true)) { val nodeName = { val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow() val nodeName = nodeHandle.nodeInfo.chooseIdentity().name diff --git a/node/src/integration-test/kotlin/net/corda/node/persistence/NodeStatePersistenceTests.kt b/node/src/integration-test/kotlin/net/corda/node/persistence/NodeStatePersistenceTests.kt index 27b2f22f78..71b5de69a6 100644 --- a/node/src/integration-test/kotlin/net/corda/node/persistence/NodeStatePersistenceTests.kt +++ b/node/src/integration-test/kotlin/net/corda/node/persistence/NodeStatePersistenceTests.kt @@ -37,7 +37,7 @@ class NodeStatePersistenceTests { fun `persistent state survives node restart`() { val user = User("mark", "dadada", setOf(startFlow(), invokeRpc("vaultQuery"))) val message = Message("Hello world!") - val stateAndRef: StateAndRef? = driver(DriverParameters(isDebug = true, startNodesInProcess = isQuasarAgentSpecified(), + val stateAndRef: StateAndRef? = driver(DriverParameters(isDebug = true, inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) { val nodeName = { val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow() @@ -70,7 +70,7 @@ class NodeStatePersistenceTests { val user = User("mark", "dadada", setOf(startFlow(), invokeRpc("vaultQuery"))) val message = Message("Hello world!") - val stateAndRef: StateAndRef? = driver(DriverParameters(isDebug = true, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) { + val stateAndRef: StateAndRef? = driver(DriverParameters(isDebug = true, inMemoryDB = false, startNodesInProcess = isQuasarAgentSpecified(), portAllocation = RandomFree, extraCordappPackagesToScan = listOf(MessageState::class.packageName))) { val nodeName = { val nodeHandle = startNode(rpcUsers = listOf(user)).getOrThrow() val nodeName = nodeHandle.nodeInfo.singleIdentity().name diff --git a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/HardRestartTest.kt b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/HardRestartTest.kt index bff99b12e2..91d23dd829 100644 --- a/node/src/integration-test/kotlin/net/corda/node/services/statemachine/HardRestartTest.kt +++ b/node/src/integration-test/kotlin/net/corda/node/services/statemachine/HardRestartTest.kt @@ -61,7 +61,7 @@ class HardRestartTest { @Test fun restartShortPingPongFlowRandomly() { val demoUser = User("demo", "demo", setOf(Permissions.startFlow(), Permissions.all())) - driver(DriverParameters(isDebug = true, startNodesInProcess = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { + driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { val (a, b) = listOf( startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000")) @@ -93,7 +93,7 @@ class HardRestartTest { @Test fun restartLongPingPongFlowRandomly() { val demoUser = User("demo", "demo", setOf(Permissions.startFlow(), Permissions.all())) - driver(DriverParameters(isDebug = true, startNodesInProcess = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { + driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { val (a, b) = listOf( startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000")) @@ -125,7 +125,7 @@ class HardRestartTest { @Test fun softRestartLongPingPongFlowRandomly() { val demoUser = User("demo", "demo", setOf(Permissions.startFlow(), Permissions.all())) - driver(DriverParameters(isDebug = true, startNodesInProcess = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { + driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { val (a, b) = listOf( startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000")) @@ -201,7 +201,7 @@ class HardRestartTest { @Test fun restartRecursiveFlowRandomly() { val demoUser = User("demo", "demo", setOf(Permissions.startFlow(), Permissions.all())) - driver(DriverParameters(isDebug = true, startNodesInProcess = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { + driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, systemProperties = mapOf("log4j.configurationFile" to logConfigFile.toString()))) { val (a, b) = listOf( startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:30000")), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser), customOverrides = mapOf("p2pAddress" to "localhost:40000")) diff --git a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt index bae3a462d3..f04c856f73 100644 --- a/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt +++ b/node/src/integration-test/kotlin/net/corda/services/messaging/P2PMessagingTest.kt @@ -63,7 +63,7 @@ class P2PMessagingTest { } assertThat(participatingNodes).containsOnlyElementsOf(participatingServiceNodes.map { it.services.myInfo }) } - + private fun InProcess.respondWith(message: Any) { internalServices.networkService.addMessageHandler("test.request") { netMessage, _, handler -> val request = netMessage.data.deserialize() diff --git a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt index 80ed1acbf2..9160a43c2d 100644 --- a/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt +++ b/samples/trader-demo/src/integration-test/kotlin/net/corda/traderdemo/TraderDemoTest.kt @@ -34,7 +34,7 @@ class TraderDemoTest { startFlow(), startFlow(), all())) - driver(DriverParameters(startNodesInProcess = true, extraCordappPackagesToScan = listOf("net.corda.finance"))) { + driver(DriverParameters(startNodesInProcess = true, inMemoryDB = false, extraCordappPackagesToScan = listOf("net.corda.finance"))) { val (nodeA, nodeB, bankNode) = listOf( startNode(providedName = DUMMY_BANK_A_NAME, rpcUsers = listOf(demoUser)), startNode(providedName = DUMMY_BANK_B_NAME, rpcUsers = listOf(demoUser)), @@ -76,7 +76,7 @@ class TraderDemoTest { @Test fun `Tudor test`() { - driver(DriverParameters(isDebug = true, startNodesInProcess = false, extraCordappPackagesToScan = listOf("net.corda.finance"))) { + driver(DriverParameters(isDebug = true, startNodesInProcess = false, inMemoryDB = false, extraCordappPackagesToScan = listOf("net.corda.finance"))) { val demoUser = User("demo", "demo", setOf(startFlow(), all())) val bankUser = User("user1", "test", permissions = setOf(all())) val (nodeA, nodeB, bankNode) = listOf( diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt index 189cc0fb61..16e3ec37dc 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/driver/Driver.kt @@ -234,7 +234,8 @@ fun driver(defaultParameters: DriverParameters = DriverParameters(), dsl: Dr jmxPolicy = defaultParameters.jmxPolicy, compatibilityZone = null, networkParameters = defaultParameters.networkParameters, - notaryCustomOverrides = defaultParameters.notaryCustomOverrides + notaryCustomOverrides = defaultParameters.notaryCustomOverrides, + inMemoryDB = defaultParameters.inMemoryDB ), coerce = { it }, dsl = dsl, @@ -267,6 +268,10 @@ fun driver(defaultParameters: DriverParameters = DriverParameters(), dsl: Dr * @property networkParameters The network parameters to be used by all the nodes. [NetworkParameters.notaries] must be * empty as notaries are defined by [notarySpecs]. * @property notaryCustomOverrides Extra settings that need to be passed to the notary. + * @property initialiseSerialization Indicates whether to initialized the serialization subsystem. + * @property inMemoryDB Whether to use in-memory H2 for new nodes rather then on-disk (the node starts quicker, however + * the data is not persisted between node restarts). Has no effect if node is configured + * in any way to use database other than H2. */ @Suppress("unused") data class DriverParameters( @@ -283,7 +288,8 @@ data class DriverParameters( val jmxPolicy: JmxPolicy = JmxPolicy(), val networkParameters: NetworkParameters = testNetworkParameters(notaries = emptyList()), val notaryCustomOverrides: Map = emptyMap(), - val initialiseSerialization: Boolean = true + val initialiseSerialization: Boolean = true, + val inMemoryDB: Boolean = true ) { constructor( isDebug: Boolean, @@ -312,6 +318,7 @@ data class DriverParameters( jmxPolicy, networkParameters, emptyMap(), + true, true ) @@ -328,7 +335,8 @@ data class DriverParameters( extraCordappPackagesToScan: List, jmxPolicy: JmxPolicy, networkParameters: NetworkParameters, - initialiseSerialization: Boolean + initialiseSerialization: Boolean, + inMemoryDB: Boolean ) : this( isDebug, driverDirectory, @@ -343,7 +351,8 @@ data class DriverParameters( jmxPolicy, networkParameters, emptyMap(), - initialiseSerialization + initialiseSerialization, + inMemoryDB ) fun withIsDebug(isDebug: Boolean): DriverParameters = copy(isDebug = isDebug) @@ -360,6 +369,7 @@ data class DriverParameters( fun withJmxPolicy(jmxPolicy: JmxPolicy): DriverParameters = copy(jmxPolicy = jmxPolicy) fun withNetworkParameters(networkParameters: NetworkParameters): DriverParameters = copy(networkParameters = networkParameters) fun withNotaryCustomOverrides(notaryCustomOverrides: Map): DriverParameters = copy(notaryCustomOverrides = notaryCustomOverrides) + fun withInMemoryDB(inMemoryDB: Boolean): DriverParameters = copy(inMemoryDB = inMemoryDB) fun copy( isDebug: Boolean, diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt index c5261b496d..c024f725a3 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/DriverDSLImpl.kt @@ -73,6 +73,7 @@ import java.util.* import java.util.concurrent.Executors import java.util.concurrent.ScheduledExecutorService import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicInteger import kotlin.collections.ArrayList import kotlin.collections.HashMap import kotlin.concurrent.thread @@ -92,7 +93,8 @@ class DriverDSLImpl( val notarySpecs: List, val compatibilityZone: CompatibilityZoneParams?, val networkParameters: NetworkParameters, - val notaryCustomOverrides: Map + val notaryCustomOverrides: Map, + val inMemoryDB: Boolean ) : InternalDriverDSL { private var _executorService: ScheduledExecutorService? = null @@ -111,6 +113,9 @@ class DriverDSLImpl( private lateinit var _notaries: CordaFuture> override val notaryHandles: List get() = _notaries.getOrThrow() + // While starting with inProcess mode, we need to have different names to avoid clashes + private val inMemoryCounter = AtomicInteger() + interface Waitable { @Throws(InterruptedException::class) fun waitFor() @@ -127,6 +132,16 @@ class DriverDSLImpl( private val jolokiaJarPath: String by lazy { resolveJar(".*jolokia-jvm-.*-agent\\.jar$") } + private fun NodeConfig.checkAndOverrideForInMemoryDB(): NodeConfig = this.run { + if (inMemoryDB && corda.dataSourceProperties.getProperty("dataSource.url").startsWith("jdbc:h2:")) { + val jdbcUrl = "jdbc:h2:mem:persistence${inMemoryCounter.getAndIncrement()};DB_CLOSE_ON_EXIT=FALSE;LOCK_TIMEOUT=10000;WRITE_DELAY=100" + corda.dataSourceProperties.setProperty("dataSource.url", jdbcUrl) + NodeConfig(typesafe = typesafe + mapOf("dataSourceProperties" to mapOf("dataSource.url" to jdbcUrl)), corda = corda) + } else { + this + } + } + private fun resolveJar(jarNamePattern: String): String { return try { val cl = ClassLoader.getSystemClassLoader() @@ -234,7 +249,7 @@ class DriverDSLImpl( baseDirectory = baseDirectory(name), allowMissingConfig = true, configOverrides = if (overrides.hasPath("devMode")) overrides else overrides + mapOf("devMode" to true) - )) + )).checkAndOverrideForInMemoryDB() return startNodeInternal(config, webAddress, startInSameProcess, maximumHeapSize, localNetworkMap) } @@ -252,7 +267,7 @@ class DriverDSLImpl( "adminAddress" to portAllocation.nextHostAndPort().toString() ), "devMode" to false) - )) + )).checkAndOverrideForInMemoryDB() val versionInfo = VersionInfo(1, "1", "1", "1") config.corda.certificatesDirectory.createDirectories() @@ -375,7 +390,7 @@ class DriverDSLImpl( configOverrides = rawConfig.toNodeOnly() ) val cordaConfig = typesafe.parseAsNodeConfiguration() - val config = NodeConfig(rawConfig, cordaConfig) + val config = NodeConfig(rawConfig, cordaConfig).checkAndOverrideForInMemoryDB() return startNodeInternal(config, webAddress, null, "512m", localNetworkMap) } @@ -1056,7 +1071,8 @@ fun genericDriver( notarySpecs = defaultParameters.notarySpecs, compatibilityZone = null, networkParameters = defaultParameters.networkParameters, - notaryCustomOverrides = defaultParameters.notaryCustomOverrides + notaryCustomOverrides = defaultParameters.notaryCustomOverrides, + inMemoryDB = defaultParameters.inMemoryDB ) ) val shutdownHook = addShutdownHook(driverDsl::shutdown) @@ -1135,6 +1151,7 @@ fun internalDriver( networkParameters: NetworkParameters = DriverParameters().networkParameters, compatibilityZone: CompatibilityZoneParams? = null, notaryCustomOverrides: Map = DriverParameters().notaryCustomOverrides, + inMemoryDB: Boolean = DriverParameters().inMemoryDB, dsl: DriverDSLImpl.() -> A ): A { return genericDriver( @@ -1152,7 +1169,8 @@ fun internalDriver( jmxPolicy = jmxPolicy, compatibilityZone = compatibilityZone, networkParameters = networkParameters, - notaryCustomOverrides = notaryCustomOverrides + notaryCustomOverrides = notaryCustomOverrides, + inMemoryDB = inMemoryDB ), coerce = { it }, dsl = dsl, diff --git a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/RPCDriver.kt b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/RPCDriver.kt index cc32932736..ba9684fa4f 100644 --- a/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/RPCDriver.kt +++ b/testing/node-driver/src/main/kotlin/net/corda/testing/node/internal/RPCDriver.kt @@ -115,6 +115,7 @@ fun rpcDriver( jmxPolicy: JmxPolicy = JmxPolicy(), networkParameters: NetworkParameters = testNetworkParameters(), notaryCustomOverrides: Map = emptyMap(), + inMemoryDB: Boolean = true, dsl: RPCDriverDSL.() -> A ): A { return genericDriver( @@ -133,7 +134,8 @@ fun rpcDriver( jmxPolicy = jmxPolicy, compatibilityZone = null, networkParameters = networkParameters, - notaryCustomOverrides = notaryCustomOverrides + notaryCustomOverrides = notaryCustomOverrides, + inMemoryDB = inMemoryDB ), externalTrace ), coerce = { it },