Merge pull request #839 from corda/tudor_merge_14_05_2018

Tudor merge 14 05 2018
This commit is contained in:
Tudor Malene 2018-05-15 09:52:39 +01:00 committed by GitHub
commit 274dead627
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 312 additions and 42 deletions

View File

@ -120,7 +120,9 @@ buildscript {
classpath "net.corda.plugins:quasar-utils:$gradle_plugins_version" classpath "net.corda.plugins:quasar-utils:$gradle_plugins_version"
classpath "net.corda.plugins:cordformation:$gradle_plugins_version" classpath "net.corda.plugins:cordformation:$gradle_plugins_version"
classpath "net.corda.plugins:cordapp:$gradle_plugins_version" classpath "net.corda.plugins:cordapp:$gradle_plugins_version"
classpath "net.corda.plugins:api-scanner:$gradle_plugins_version" //TODO Anthony- this should be changed back to $gradle_plugins_version when the api-scaner is fixed
// classpath "net.corda.plugins:api-scanner:$gradle_plugins_version"
classpath "net.corda.plugins:api-scanner:4.0.15"
classpath 'com.github.ben-manes:gradle-versions-plugin:0.15.0' classpath 'com.github.ben-manes:gradle-versions-plugin:0.15.0'
classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}" classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}"

View File

@ -8,7 +8,7 @@
# Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited. # Distribution of this file or any portion thereof via any medium without the express permission of R3 is strictly prohibited.
# #
gradlePluginsVersion=4.0.15 gradlePluginsVersion=4.0.19
kotlinVersion=1.2.41 kotlinVersion=1.2.41
platformVersion=4 platformVersion=4
guavaVersion=21.0 guavaVersion=21.0

View File

@ -55,6 +55,10 @@ object Emoji {
val CODE_FREE: String = codePointsString(0x1F193) val CODE_FREE: String = codePointsString(0x1F193)
@JvmStatic @JvmStatic
val CODE_SOON: String = codePointsString(0x1F51C) val CODE_SOON: String = codePointsString(0x1F51C)
@JvmStatic
val CODE_DEVELOPER: String = codePointsString(0x1F469, 0x200D, 0x1F4BB)
@JvmStatic
val CODE_WARNING_SIGN: String = codePointsString(0x26A0, 0xFE0F)
/** /**
@ -75,6 +79,8 @@ object Emoji {
val lightBulb: String get() = if (emojiMode.get() != null) "$CODE_LIGHTBULB " else "" val lightBulb: String get() = if (emojiMode.get() != null) "$CODE_LIGHTBULB " else ""
val free: String get() = if (emojiMode.get() != null) "$CODE_FREE " else "" val free: String get() = if (emojiMode.get() != null) "$CODE_FREE " else ""
val soon: String get() = if (emojiMode.get() != null) "$CODE_SOON " else "" val soon: String get() = if (emojiMode.get() != null) "$CODE_SOON " else ""
val developer: String get() = if (emojiMode.get() != null) "$CODE_DEVELOPER " else ""
val warningSign: String get() = if (emojiMode.get() != null) "$CODE_WARNING_SIGN " else "!"
// These have old/non-emoji symbols with better platform support. // These have old/non-emoji symbols with better platform support.
val greenTick: String get() = if (emojiMode.get() != null) "$CODE_GREEN_TICK " else "" val greenTick: String get() = if (emojiMode.get() != null) "$CODE_GREEN_TICK " else ""

View File

@ -10,6 +10,12 @@ Unreleased
* Node will now gracefully fail to start if ``devMode`` is true and ``compatibilityZoneURL`` is specified. * Node will now gracefully fail to start if ``devMode`` is true and ``compatibilityZoneURL`` is specified.
* Added smart detection logic for the development mode setting and an option to override it from the command line.
* Fixed an error thrown by NodeVaultService upon recording a transaction with a number of inputs greater than the default page size.
* Fixed incorrect computation of ``totalStates`` from ``otherResults`` in ``NodeVaultService``.
* Changes to the JSON/YAML serialisation format from ``JacksonSupport``, which also applies to the node shell: * Changes to the JSON/YAML serialisation format from ``JacksonSupport``, which also applies to the node shell:
* ``Instant`` and ``Date`` objects are serialised as ISO-8601 formatted strings rather than timestamps * ``Instant`` and ``Date`` objects are serialised as ISO-8601 formatted strings rather than timestamps

View File

@ -172,9 +172,12 @@ absolute path to the node's base directory.
:devMode: This flag sets the node to run in development mode. On startup, if the keystore ``<workspace>/certificates/sslkeystore.jks`` :devMode: This flag sets the node to run in development mode. On startup, if the keystore ``<workspace>/certificates/sslkeystore.jks``
does not exist, a developer keystore will be used if ``devMode`` is true. The node will exit if ``devMode`` is false does not exist, a developer keystore will be used if ``devMode`` is true. The node will exit if ``devMode`` is false
and the keystore does not exist. ``devMode`` also turns on background checking of flow checkpoints to shake out any and the keystore does not exist. ``devMode`` also turns on background checking of flow checkpoints to shake out any
bugs in the checkpointing process. Also, if ``devMode`` is true, Hibernate will try to automatically create the schema required by Corda bugs in the checkpointing process.
or update an existing schema in the SQL database; if ``devMode`` is false, Hibernate will simply validate an existing schema Also, if ``devMode`` is true, Hibernate will try to automatically create the schema required by Corda
failing on node start if this schema is either not present or not compatible. or update an existing schema in the SQL database; if ``devMode`` is false, Hibernate will simply validate the existing schema,
failing on node start if the schema is either not present or not compatible.
If no value is specified in the node config file, the node will attempt to detect if it's running on a developer machine and set ``devMode=true`` in that case.
This value can be overridden from the command line using the ``--dev-mode`` option.
:detectPublicIp: This flag toggles the auto IP detection behaviour, it is enabled by default. On startup the node will :detectPublicIp: This flag toggles the auto IP detection behaviour, it is enabled by default. On startup the node will
attempt to discover its externally visible IP address first by looking for any public addresses on its network attempt to discover its externally visible IP address first by looking for any public addresses on its network

View File

@ -95,11 +95,12 @@ class NetworkParametersUpdateTest : IntegrationTest() {
compatibilityZone = compatibilityZone, compatibilityZone = compatibilityZone,
notarySpecs = emptyList(), notarySpecs = emptyList(),
initialiseSerialization = false, initialiseSerialization = false,
extraCordappPackagesToScan = listOf("net.corda.finance") extraCordappPackagesToScan = listOf("net.corda.finance"),
notaryCustomOverrides = mapOf("devMode" to false)
) { ) {
var (alice, bob) = listOf( var (alice, bob) = listOf(
startNode(providedName = ALICE_NAME), startNode(providedName = ALICE_NAME, customOverrides = mapOf("devMode" to false)),
startNode(providedName = BOB_NAME) startNode(providedName = BOB_NAME, customOverrides = mapOf("devMode" to false))
).map { it.getOrThrow() as NodeHandleInternal } ).map { it.getOrThrow() as NodeHandleInternal }
// Make sure that stopping Bob doesn't remove him from the network map // Make sure that stopping Bob doesn't remove him from the network map
@ -139,7 +140,7 @@ class NetworkParametersUpdateTest : IntegrationTest() {
applyNetworkParametersAndStart(NetworkParametersCmd.FlagDay) applyNetworkParametersAndStart(NetworkParametersCmd.FlagDay)
alice.stop() alice.stop()
alice = startNode(providedName = ALICE_NAME).getOrThrow() as NodeHandleInternal alice = startNode(providedName = ALICE_NAME, customOverrides = mapOf("devMode" to false)).getOrThrow() as NodeHandleInternal
// TODO It is also possible to check what version of parameters node runs by writing flow that reads that value from ServiceHub // TODO It is also possible to check what version of parameters node runs by writing flow that reads that value from ServiceHub
val networkParameters = (alice.configuration.baseDirectory / NETWORK_PARAMS_FILE_NAME) val networkParameters = (alice.configuration.baseDirectory / NETWORK_PARAMS_FILE_NAME)

View File

@ -130,17 +130,18 @@ class NodeRegistrationTest : IntegrationTest() {
compatibilityZone = compatibilityZone, compatibilityZone = compatibilityZone,
initialiseSerialization = false, initialiseSerialization = false,
notarySpecs = listOf(NotarySpec(notaryName)), notarySpecs = listOf(NotarySpec(notaryName)),
extraCordappPackagesToScan = listOf("net.corda.finance") extraCordappPackagesToScan = listOf("net.corda.finance"),
notaryCustomOverrides = mapOf("devMode" to false)
) { ) {
val (alice, notary) = listOf( val (alice, notary) = listOf(
startNode(providedName = aliceName), startNode(providedName = aliceName, customOverrides = mapOf("devMode" to false)),
defaultNotaryNode defaultNotaryNode
).map { it.getOrThrow() as NodeHandleInternal } ).map { it.getOrThrow() as NodeHandleInternal }
alice.onlySeesFromNetworkMap(alice, notary) alice.onlySeesFromNetworkMap(alice, notary)
notary.onlySeesFromNetworkMap(alice, notary) notary.onlySeesFromNetworkMap(alice, notary)
val genevieve = startNode(providedName = genevieveName).getOrThrow() as NodeHandleInternal val genevieve = startNode(providedName = genevieveName, customOverrides = mapOf("devMode" to false)).getOrThrow() as NodeHandleInternal
// Wait for the nodes to poll again // Wait for the nodes to poll again
Thread.sleep(timeoutMillis * 2) Thread.sleep(timeoutMillis * 2)

View File

@ -101,11 +101,12 @@ class NodeRegistrationTest : IntegrationTest() {
compatibilityZone = compatibilityZone, compatibilityZone = compatibilityZone,
initialiseSerialization = false, initialiseSerialization = false,
notarySpecs = listOf(NotarySpec(notaryName)), notarySpecs = listOf(NotarySpec(notaryName)),
extraCordappPackagesToScan = listOf("net.corda.finance") extraCordappPackagesToScan = listOf("net.corda.finance"),
notaryCustomOverrides = mapOf("devMode" to false)
) { ) {
val (alice, genevieve) = listOf( val (alice, genevieve) = listOf(
startNode(providedName = aliceName), startNode(providedName = aliceName, customOverrides = mapOf("devMode" to false)),
startNode(providedName = genevieveName) startNode(providedName = genevieveName, customOverrides = mapOf("devMode" to false))
).transpose().getOrThrow() ).transpose().getOrThrow()
assertThat(registrationHandler.idsPolled).containsOnly( assertThat(registrationHandler.idsPolled).containsOnly(

View File

@ -57,6 +57,7 @@ class NodeArgsParser : AbstractArgsParser<CmdLineOptions>() {
.withRequiredArg() .withRequiredArg()
.withValuesConvertedBy(object : EnumConverter<UnknownConfigKeysPolicy>(UnknownConfigKeysPolicy::class.java) {}) .withValuesConvertedBy(object : EnumConverter<UnknownConfigKeysPolicy>(UnknownConfigKeysPolicy::class.java) {})
.defaultsTo(UnknownConfigKeysPolicy.FAIL) .defaultsTo(UnknownConfigKeysPolicy.FAIL)
private val devModeArg = optionParser.accepts("dev-mode", "Run the node in developer mode. Unsafe for production.")
private val isVersionArg = optionParser.accepts("version", "Print the version and exit") private val isVersionArg = optionParser.accepts("version", "Print the version and exit")
private val justGenerateNodeInfoArg = optionParser.accepts("just-generate-node-info", private val justGenerateNodeInfoArg = optionParser.accepts("just-generate-node-info",
@ -80,6 +81,7 @@ class NodeArgsParser : AbstractArgsParser<CmdLineOptions>() {
val networkRootTrustStorePath = optionSet.valueOf(networkRootTrustStorePathArg) val networkRootTrustStorePath = optionSet.valueOf(networkRootTrustStorePathArg)
val networkRootTrustStorePassword = optionSet.valueOf(networkRootTrustStorePasswordArg) val networkRootTrustStorePassword = optionSet.valueOf(networkRootTrustStorePasswordArg)
val unknownConfigKeysPolicy = optionSet.valueOf(unknownConfigKeysPolicy) val unknownConfigKeysPolicy = optionSet.valueOf(unknownConfigKeysPolicy)
val devMode = optionSet.has(devModeArg)
val registrationConfig = if (isRegistration) { val registrationConfig = if (isRegistration) {
requireNotNull(networkRootTrustStorePassword) { "Network root trust store password must be provided in registration mode using --network-root-truststore-password." } requireNotNull(networkRootTrustStorePassword) { "Network root trust store password must be provided in registration mode using --network-root-truststore-password." }
@ -99,7 +101,8 @@ class NodeArgsParser : AbstractArgsParser<CmdLineOptions>() {
sshdServer, sshdServer,
justGenerateNodeInfo, justGenerateNodeInfo,
bootstrapRaftCluster, bootstrapRaftCluster,
unknownConfigKeysPolicy) unknownConfigKeysPolicy,
devMode)
} }
} }
@ -115,12 +118,14 @@ data class CmdLineOptions(val baseDirectory: Path,
val sshdServer: Boolean, val sshdServer: Boolean,
val justGenerateNodeInfo: Boolean, val justGenerateNodeInfo: Boolean,
val bootstrapRaftCluster: Boolean, val bootstrapRaftCluster: Boolean,
val unknownConfigKeysPolicy: UnknownConfigKeysPolicy) { val unknownConfigKeysPolicy: UnknownConfigKeysPolicy,
val devMode: Boolean) {
fun loadConfig(): NodeConfiguration { fun loadConfig(): NodeConfiguration {
val config = ConfigHelper.loadConfig( val config = ConfigHelper.loadConfig(
baseDirectory, baseDirectory,
configFile, configFile,
configOverrides = ConfigFactory.parseMap(mapOf("noLocalShell" to this.noLocalShell)) configOverrides = ConfigFactory.parseMap(mapOf("noLocalShell" to this.noLocalShell) +
if (devMode) mapOf("devMode" to this.devMode) else emptyMap<String, Any>())
).parseAsNodeConfiguration(unknownConfigKeysPolicy::handle) ).parseAsNodeConfiguration(unknownConfigKeysPolicy::handle)
if (nodeRegistrationOption != null) { if (nodeRegistrationOption != null) {
require(!config.devMode) { "registration cannot occur in devMode" } require(!config.devMode) { "registration cannot occur in devMode" }

View File

@ -23,6 +23,7 @@ import net.corda.core.flows.*
import net.corda.core.identity.CordaX500Name import net.corda.core.identity.CordaX500Name
import net.corda.core.identity.Party import net.corda.core.identity.Party
import net.corda.core.identity.PartyAndCertificate import net.corda.core.identity.PartyAndCertificate
import net.corda.core.internal.Emoji
import net.corda.core.internal.FlowStateMachine import net.corda.core.internal.FlowStateMachine
import net.corda.core.internal.VisibleForTesting import net.corda.core.internal.VisibleForTesting
import net.corda.core.internal.concurrent.map import net.corda.core.internal.concurrent.map
@ -179,8 +180,10 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
private fun initCertificate() { private fun initCertificate() {
if (configuration.devMode) { if (configuration.devMode) {
log.warn("Corda node is running in dev mode.") log.warn("The Corda node is running in developer mode. This is not suitable for production usage.")
configuration.configureWithDevSSLCertificate() configuration.configureWithDevSSLCertificate()
} else {
log.info("The Corda node is running in production mode. If this is a developer environment you can set 'devMode=true' in the node.conf file.")
} }
validateKeystore() validateKeystore()
} }
@ -205,6 +208,9 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
open fun start(): StartedNode<AbstractNode> { open fun start(): StartedNode<AbstractNode> {
check(started == null) { "Node has already been started" } check(started == null) { "Node has already been started" }
if (configuration.devMode) {
Emoji.renderIfSupported { Node.printWarning("This node is running in developer mode! ${Emoji.developer} This is not safe for production deployment.") }
}
log.info("Node starting up ...") log.info("Node starting up ...")
initCertificate() initCertificate()
initialiseJVMAgents() initialiseJVMAgents()

View File

@ -13,6 +13,7 @@ package net.corda.node.internal
import com.codahale.metrics.JmxReporter import com.codahale.metrics.JmxReporter
import net.corda.client.rpc.internal.serialization.kryo.KryoClientSerializationScheme import net.corda.client.rpc.internal.serialization.kryo.KryoClientSerializationScheme
import net.corda.core.concurrent.CordaFuture import net.corda.core.concurrent.CordaFuture
import net.corda.core.internal.Emoji
import net.corda.core.internal.concurrent.openFuture import net.corda.core.internal.concurrent.openFuture
import net.corda.core.internal.concurrent.thenMatch import net.corda.core.internal.concurrent.thenMatch
import net.corda.core.internal.div import net.corda.core.internal.div
@ -85,6 +86,13 @@ open class Node(configuration: NodeConfiguration,
LoggerFactory.getLogger(loggerName).info(msg) LoggerFactory.getLogger(loggerName).info(msg)
} }
fun printWarning(message: String) {
Emoji.renderIfSupported {
println("${Emoji.warningSign} ATTENTION: ${message}")
}
staticLog.warn(message)
}
internal fun failStartUp(message: String): Nothing { internal fun failStartUp(message: String): Nothing {
println(message) println(message)
println("Corda will now exit...") println("Corda will now exit...")

View File

@ -46,6 +46,10 @@ object ConfigHelper {
val appConfig = ConfigFactory.parseFile(configFile.toFile(), parseOptions.setAllowMissing(allowMissingConfig)) val appConfig = ConfigFactory.parseFile(configFile.toFile(), parseOptions.setAllowMissing(allowMissingConfig))
val databaseConfig = ConfigFactory.parseResources(System.getProperty("custom.databaseProvider")+".conf", parseOptions.setAllowMissing(true)) val databaseConfig = ConfigFactory.parseResources(System.getProperty("custom.databaseProvider")+".conf", parseOptions.setAllowMissing(true))
// Detect the underlying OS. If mac or windows non-server then we assume we're running in devMode. Unless specified otherwise.
val smartDevMode = CordaSystemUtils.isOsMac() || (CordaSystemUtils.isOsWindows() && !CordaSystemUtils.getOsName().toLowerCase().contains("server"))
val devModeConfig = ConfigFactory.parseMap(mapOf("devMode" to smartDevMode))
val systemOverrides = systemProperties().cordaEntriesOnly() val systemOverrides = systemProperties().cordaEntriesOnly()
val environmentOverrides = systemEnvironment().cordaEntriesOnly() val environmentOverrides = systemEnvironment().cordaEntriesOnly()
val finalConfig = configOverrides val finalConfig = configOverrides
@ -56,6 +60,7 @@ object ConfigHelper {
.withFallback(configOf("baseDirectory" to baseDirectory.toString())) .withFallback(configOf("baseDirectory" to baseDirectory.toString()))
.withFallback(databaseConfig) //for database integration tests .withFallback(databaseConfig) //for database integration tests
.withFallback(appConfig) .withFallback(appConfig)
.withFallback(devModeConfig) // this needs to be after the appConfig, so it doesn't override the configured devMode
.withFallback(defaultConfig) .withFallback(defaultConfig)
.resolve() .resolve()
@ -112,3 +117,15 @@ fun SSLConfiguration.configureDevKeyAndTrustStores(myLegalName: CordaX500Name) {
/** Parse a value to be database schema name friendly and removes the last part if it matches a port ("_" followed by at least 5 digits) */ /** Parse a value to be database schema name friendly and removes the last part if it matches a port ("_" followed by at least 5 digits) */
fun parseToDbSchemaFriendlyName(value: String) = fun parseToDbSchemaFriendlyName(value: String) =
value.replace(" ", "").replace("-", "_").replace(Regex("_\\d{5,}$"),"") value.replace(" ", "").replace("-", "_").replace(Regex("_\\d{5,}$"),"")
/** This is generally covered by commons-lang. */
object CordaSystemUtils {
const val OS_NAME = "os.name"
const val MAC_PREFIX = "Mac"
const val WIN_PREFIX = "Windows"
fun isOsMac() = getOsName().startsWith(MAC_PREFIX)
fun isOsWindows() = getOsName().startsWith(WIN_PREFIX)
fun getOsName() = System.getProperty(OS_NAME)
}

View File

@ -22,7 +22,6 @@ database = {
transactionIsolationLevel = "REPEATABLE_READ" transactionIsolationLevel = "REPEATABLE_READ"
exportHibernateJMXStatistics = "false" exportHibernateJMXStatistics = "false"
} }
devMode = true
h2port = 0 h2port = 0
useTestClock = false useTestClock = false
verifierType = InMemory verifierType = InMemory

View File

@ -53,7 +53,8 @@ class NodeArgsParserTest {
sshdServer = false, sshdServer = false,
justGenerateNodeInfo = false, justGenerateNodeInfo = false,
bootstrapRaftCluster = false, bootstrapRaftCluster = false,
unknownConfigKeysPolicy = UnknownConfigKeysPolicy.FAIL)) unknownConfigKeysPolicy = UnknownConfigKeysPolicy.FAIL,
devMode = false))
} }
@Test @Test

View File

@ -11,7 +11,10 @@
package net.corda.node.services.config package net.corda.node.services.config
import com.zaxxer.hikari.HikariConfig import com.zaxxer.hikari.HikariConfig
import com.typesafe.config.Config
import com.typesafe.config.ConfigFactory
import net.corda.core.internal.div import net.corda.core.internal.div
import net.corda.core.internal.toPath
import net.corda.core.utilities.NetworkHostAndPort import net.corda.core.utilities.NetworkHostAndPort
import net.corda.nodeapi.internal.persistence.CordaPersistence.DataSourceConfigTag import net.corda.nodeapi.internal.persistence.CordaPersistence.DataSourceConfigTag
import net.corda.core.utilities.seconds import net.corda.core.utilities.seconds
@ -86,6 +89,59 @@ class NodeConfigurationImplTest {
assertFalse { testConfiguration.copy(noLocalShell = true, sshd = null).shouldInitCrashShell() } assertFalse { testConfiguration.copy(noLocalShell = true, sshd = null).shouldInitCrashShell() }
} }
@Test
fun `Dev mode is autodetected correctly`() {
val os = System.getProperty("os.name")
setSystemOs("Windows 98")
assertTrue(getConfig("test-config-empty.conf").getBoolean("devMode"))
setSystemOs("Mac Sierra")
assertTrue(getConfig("test-config-empty.conf").getBoolean("devMode"))
setSystemOs("Windows server 2008")
assertFalse(getConfig("test-config-empty.conf").getBoolean("devMode"))
setSystemOs("Linux")
assertFalse(getConfig("test-config-empty.conf").getBoolean("devMode"))
setSystemOs(os)
}
private fun setSystemOs(os: String) {
System.setProperty("os.name", os)
}
@Test
fun `Dev mode is read from the config over the autodetect logic`() {
assertTrue(getConfig("test-config-DevMode.conf").getBoolean("devMode"))
assertFalse(getConfig("test-config-noDevMode.conf").getBoolean("devMode"))
}
@Test
fun `Dev mode is true if overriden`() {
assertTrue(getConfig("test-config-DevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to true))).getBoolean("devMode"))
assertTrue(getConfig("test-config-noDevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to true))).getBoolean("devMode"))
assertTrue(getConfig("test-config-empty.conf", ConfigFactory.parseMap(mapOf("devMode" to true))).getBoolean("devMode"))
}
@Test
fun `Dev mode is false if overriden`() {
assertFalse(getConfig("test-config-DevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to false))).getBoolean("devMode"))
assertFalse(getConfig("test-config-noDevMode.conf", ConfigFactory.parseMap(mapOf("devMode" to false))).getBoolean("devMode"))
assertFalse(getConfig("test-config-empty.conf", ConfigFactory.parseMap(mapOf("devMode" to false))).getBoolean("devMode"))
}
private fun getConfig(cfgName: String, overrides: Config = ConfigFactory.empty()): Config {
val path = this::class.java.classLoader.getResource(cfgName).toPath()
val cfg = ConfigHelper.loadConfig(
baseDirectory = path.parent,
configFile = path,
configOverrides = overrides
)
return cfg
}
@Test @Test
fun `validation has error when compatibilityZoneURL is present and devMode is true`() { fun `validation has error when compatibilityZoneURL is present and devMode is true`() {
val configuration = testConfiguration.copy(devMode = true, compatibilityZoneURL = URI.create("https://r3.com").toURL()) val configuration = testConfiguration.copy(devMode = true, compatibilityZoneURL = URI.create("https://r3.com").toURL())

View File

@ -0,0 +1 @@
devMode=true

View File

@ -0,0 +1 @@
devMode=false

View File

@ -46,6 +46,7 @@ class BankOfCordaCordform : CordformDefinition() {
address("localhost:10003") address("localhost:10003")
adminAddress("localhost:10004") adminAddress("localhost:10004")
} }
devMode(true)
} }
node { node {
name(BOC_NAME) name(BOC_NAME)
@ -57,6 +58,7 @@ class BankOfCordaCordform : CordformDefinition() {
} }
webPort(BOC_WEB_PORT) webPort(BOC_WEB_PORT)
rpcUsers(User("bankUser", "test", setOf(all()))) rpcUsers(User("bankUser", "test", setOf(all())))
devMode(true)
} }
node { node {
name(BIGCORP_NAME) name(BIGCORP_NAME)
@ -67,6 +69,7 @@ class BankOfCordaCordform : CordformDefinition() {
} }
webPort(10010) webPort(10010)
rpcUsers(User("bigCorpUser", "test", setOf(all()))) rpcUsers(User("bigCorpUser", "test", setOf(all())))
devMode(true)
} }
} }

View File

@ -44,6 +44,7 @@ class BFTNotaryCordform : CordformDefinition() {
adminAddress("localhost:10103") adminAddress("localhost:10103")
} }
rpcUsers(notaryDemoUser) rpcUsers(notaryDemoUser)
devMode(true)
} }
node { node {
name(BOB_NAME) name(BOB_NAME)
@ -52,6 +53,7 @@ class BFTNotaryCordform : CordformDefinition() {
address("localhost:10006") address("localhost:10006")
adminAddress("localhost:10106") adminAddress("localhost:10106")
} }
devMode(true)
} }
val clusterAddresses = (0 until clusterSize).map { NetworkHostAndPort("localhost", 11000 + it * 10) } val clusterAddresses = (0 until clusterSize).map { NetworkHostAndPort("localhost", 11000 + it * 10) }
fun notaryNode(replicaId: Int, configure: CordformNode.() -> Unit) = node { fun notaryNode(replicaId: Int, configure: CordformNode.() -> Unit) = node {
@ -65,6 +67,7 @@ class BFTNotaryCordform : CordformDefinition() {
address("localhost:10010") address("localhost:10010")
adminAddress("localhost:10110") adminAddress("localhost:10110")
} }
devMode(true)
} }
notaryNode(1) { notaryNode(1) {
p2pPort(10013) p2pPort(10013)
@ -72,6 +75,7 @@ class BFTNotaryCordform : CordformDefinition() {
address("localhost:10014") address("localhost:10014")
adminAddress("localhost:10114") adminAddress("localhost:10114")
} }
devMode(true)
} }
notaryNode(2) { notaryNode(2) {
p2pPort(10017) p2pPort(10017)
@ -79,6 +83,7 @@ class BFTNotaryCordform : CordformDefinition() {
address("localhost:10018") address("localhost:10018")
adminAddress("localhost:10118") adminAddress("localhost:10118")
} }
devMode(true)
} }
notaryNode(3) { notaryNode(3) {
p2pPort(10021) p2pPort(10021)
@ -86,6 +91,7 @@ class BFTNotaryCordform : CordformDefinition() {
address("localhost:10022") address("localhost:10022")
adminAddress("localhost:10122") adminAddress("localhost:10122")
} }
devMode(true)
} }
} }

View File

@ -32,6 +32,7 @@ class CustomNotaryCordform : CordformDefinition() {
adminAddress("localhost:10103") adminAddress("localhost:10103")
} }
rpcUsers(notaryDemoUser) rpcUsers(notaryDemoUser)
devMode(true)
} }
node { node {
name(BOB_NAME) name(BOB_NAME)
@ -40,6 +41,7 @@ class CustomNotaryCordform : CordformDefinition() {
address("localhost:10006") address("localhost:10006")
adminAddress("localhost:10106") adminAddress("localhost:10106")
} }
devMode(true)
} }
node { node {
name(DUMMY_NOTARY_NAME) name(DUMMY_NOTARY_NAME)
@ -49,6 +51,7 @@ class CustomNotaryCordform : CordformDefinition() {
adminAddress("localhost:10110") adminAddress("localhost:10110")
} }
notary(NotaryConfig(validating = true, custom = true)) notary(NotaryConfig(validating = true, custom = true))
devMode(true)
} }
} }

View File

@ -44,6 +44,7 @@ class RaftNotaryCordform : CordformDefinition() {
adminAddress("localhost:10103") adminAddress("localhost:10103")
} }
rpcUsers(notaryDemoUser) rpcUsers(notaryDemoUser)
devMode(true)
} }
node { node {
name(BOB_NAME) name(BOB_NAME)
@ -52,12 +53,14 @@ class RaftNotaryCordform : CordformDefinition() {
address("localhost:10006") address("localhost:10006")
adminAddress("localhost:10106") adminAddress("localhost:10106")
} }
devMode(true)
} }
fun notaryNode(index: Int, nodePort: Int, clusterPort: Int? = null, configure: CordformNode.() -> Unit) = node { fun notaryNode(index: Int, nodePort: Int, clusterPort: Int? = null, configure: CordformNode.() -> Unit) = node {
name(notaryNames[index]) name(notaryNames[index])
val clusterAddresses = if (clusterPort != null ) listOf(NetworkHostAndPort("localhost", clusterPort)) else emptyList() val clusterAddresses = if (clusterPort != null ) listOf(NetworkHostAndPort("localhost", clusterPort)) else emptyList()
notary(NotaryConfig(validating = true, raft = RaftConfig(NetworkHostAndPort("localhost", nodePort), clusterAddresses))) notary(NotaryConfig(validating = true, raft = RaftConfig(NetworkHostAndPort("localhost", nodePort), clusterAddresses)))
configure() configure()
devMode(true)
} }
notaryNode(0, 10008) { notaryNode(0, 10008) {
p2pPort(10009) p2pPort(10009)
@ -65,6 +68,7 @@ class RaftNotaryCordform : CordformDefinition() {
address("localhost:10010") address("localhost:10010")
adminAddress("localhost:10110") adminAddress("localhost:10110")
} }
devMode(true)
} }
notaryNode(1, 10012, 10008) { notaryNode(1, 10012, 10008) {
p2pPort(10013) p2pPort(10013)
@ -72,6 +76,7 @@ class RaftNotaryCordform : CordformDefinition() {
address("localhost:10014") address("localhost:10014")
adminAddress("localhost:10114") adminAddress("localhost:10114")
} }
devMode(true)
} }
notaryNode(2, 10016, 10008) { notaryNode(2, 10016, 10008) {
p2pPort(10017) p2pPort(10017)
@ -79,6 +84,7 @@ class RaftNotaryCordform : CordformDefinition() {
address("localhost:10018") address("localhost:10018")
adminAddress("localhost:10118") adminAddress("localhost:10118")
} }
devMode(true)
} }
} }

View File

@ -38,6 +38,7 @@ class SingleNotaryCordform : CordformDefinition() {
adminAddress("localhost:10103") adminAddress("localhost:10103")
} }
rpcUsers(notaryDemoUser) rpcUsers(notaryDemoUser)
devMode(true)
} }
node { node {
name(BOB_NAME) name(BOB_NAME)
@ -46,6 +47,7 @@ class SingleNotaryCordform : CordformDefinition() {
address("localhost:10006") address("localhost:10006")
adminAddress("localhost:10106") adminAddress("localhost:10106")
} }
devMode(true)
} }
node { node {
name(DUMMY_NOTARY_NAME) name(DUMMY_NOTARY_NAME)
@ -55,6 +57,7 @@ class SingleNotaryCordform : CordformDefinition() {
adminAddress("localhost:10110") adminAddress("localhost:10110")
} }
notary(NotaryConfig(validating = true)) notary(NotaryConfig(validating = true))
devMode(true)
} }
} }

View File

@ -176,7 +176,7 @@ data class NodeParameters(
*/ */
data class JmxPolicy(val startJmxHttpServer: Boolean = false, data class JmxPolicy(val startJmxHttpServer: Boolean = false,
val jmxHttpServerPortAllocation: PortAllocation? = val jmxHttpServerPortAllocation: PortAllocation? =
if (startJmxHttpServer) PortAllocation.Incremental(7005) else null) if (startJmxHttpServer) PortAllocation.Incremental(7005) else null)
/** /**
* [driver] allows one to start up nodes like this: * [driver] allows one to start up nodes like this:
@ -211,7 +211,8 @@ fun <A> driver(defaultParameters: DriverParameters = DriverParameters(), dsl: Dr
extraCordappPackagesToScan = defaultParameters.extraCordappPackagesToScan, extraCordappPackagesToScan = defaultParameters.extraCordappPackagesToScan,
jmxPolicy = defaultParameters.jmxPolicy, jmxPolicy = defaultParameters.jmxPolicy,
compatibilityZone = null, compatibilityZone = null,
networkParameters = defaultParameters.networkParameters networkParameters = defaultParameters.networkParameters,
notaryCustomOverrides = defaultParameters.notaryCustomOverrides
), ),
coerce = { it }, coerce = { it },
dsl = dsl, dsl = dsl,
@ -243,6 +244,7 @@ fun <A> driver(defaultParameters: DriverParameters = DriverParameters(), dsl: Dr
* @property jmxPolicy Used to specify whether to expose JMX metrics via Jolokia HHTP/JSON. * @property jmxPolicy Used to specify whether to expose JMX metrics via Jolokia HHTP/JSON.
* @property networkParameters The network parameters to be used by all the nodes. [NetworkParameters.notaries] must be * @property networkParameters The network parameters to be used by all the nodes. [NetworkParameters.notaries] must be
* empty as notaries are defined by [notarySpecs]. * empty as notaries are defined by [notarySpecs].
* @property notaryCustomOverrides Extra settings that need to be passed to the notary.
*/ */
@Suppress("unused") @Suppress("unused")
data class DriverParameters( data class DriverParameters(
@ -258,8 +260,70 @@ data class DriverParameters(
val notarySpecs: List<NotarySpec> = listOf(NotarySpec(DUMMY_NOTARY_NAME)), val notarySpecs: List<NotarySpec> = listOf(NotarySpec(DUMMY_NOTARY_NAME)),
val extraCordappPackagesToScan: List<String> = emptyList(), val extraCordappPackagesToScan: List<String> = emptyList(),
val jmxPolicy: JmxPolicy = JmxPolicy(), val jmxPolicy: JmxPolicy = JmxPolicy(),
val networkParameters: NetworkParameters = testNetworkParameters(notaries = emptyList()) val networkParameters: NetworkParameters = testNetworkParameters(notaries = emptyList()),
val notaryCustomOverrides: Map<String, Any?> = emptyMap()
) { ) {
constructor(
isDebug: Boolean,
driverDirectory: Path,
portAllocation: PortAllocation,
debugPortAllocation: PortAllocation,
systemProperties: Map<String, String>,
useTestClock: Boolean,
startNodesInProcess: Boolean,
waitForAllNodesToFinish: Boolean,
notarySpecs: List<NotarySpec>,
extraCordappPackagesToScan: List<String>,
jmxPolicy: JmxPolicy,
networkParameters: NetworkParameters
) : this(
isDebug,
driverDirectory,
portAllocation,
debugPortAllocation,
systemProperties,
useTestClock,
true,
startNodesInProcess,
waitForAllNodesToFinish,
notarySpecs,
extraCordappPackagesToScan,
jmxPolicy,
networkParameters,
emptyMap()
)
constructor(
isDebug: Boolean,
driverDirectory: Path,
portAllocation: PortAllocation,
debugPortAllocation: PortAllocation,
systemProperties: Map<String, String>,
useTestClock: Boolean,
initialiseSerialization: Boolean,
startNodesInProcess: Boolean,
waitForAllNodesToFinish: Boolean,
notarySpecs: List<NotarySpec>,
extraCordappPackagesToScan: List<String>,
jmxPolicy: JmxPolicy,
networkParameters: NetworkParameters
) : this(
isDebug,
driverDirectory,
portAllocation,
debugPortAllocation,
systemProperties,
useTestClock,
initialiseSerialization,
startNodesInProcess,
waitForAllNodesToFinish,
notarySpecs,
extraCordappPackagesToScan,
jmxPolicy,
networkParameters,
emptyMap()
)
fun withIsDebug(isDebug: Boolean): DriverParameters = copy(isDebug = isDebug) fun withIsDebug(isDebug: Boolean): DriverParameters = copy(isDebug = isDebug)
fun withDriverDirectory(driverDirectory: Path): DriverParameters = copy(driverDirectory = driverDirectory) fun withDriverDirectory(driverDirectory: Path): DriverParameters = copy(driverDirectory = driverDirectory)
fun withPortAllocation(portAllocation: PortAllocation): DriverParameters = copy(portAllocation = portAllocation) fun withPortAllocation(portAllocation: PortAllocation): DriverParameters = copy(portAllocation = portAllocation)
@ -273,4 +337,66 @@ data class DriverParameters(
fun withExtraCordappPackagesToScan(extraCordappPackagesToScan: List<String>): DriverParameters = copy(extraCordappPackagesToScan = extraCordappPackagesToScan) fun withExtraCordappPackagesToScan(extraCordappPackagesToScan: List<String>): DriverParameters = copy(extraCordappPackagesToScan = extraCordappPackagesToScan)
fun withJmxPolicy(jmxPolicy: JmxPolicy): DriverParameters = copy(jmxPolicy = jmxPolicy) fun withJmxPolicy(jmxPolicy: JmxPolicy): DriverParameters = copy(jmxPolicy = jmxPolicy)
fun withNetworkParameters(networkParameters: NetworkParameters): DriverParameters = copy(networkParameters = networkParameters) fun withNetworkParameters(networkParameters: NetworkParameters): DriverParameters = copy(networkParameters = networkParameters)
fun withNotaryCustomOverrides(notaryCustomOverrides: Map<String, Any?>): DriverParameters = copy(notaryCustomOverrides = notaryCustomOverrides)
fun copy(
isDebug: Boolean,
driverDirectory: Path,
portAllocation: PortAllocation,
debugPortAllocation: PortAllocation,
systemProperties: Map<String, String>,
useTestClock: Boolean,
startNodesInProcess: Boolean,
waitForAllNodesToFinish: Boolean,
notarySpecs: List<NotarySpec>,
extraCordappPackagesToScan: List<String>,
jmxPolicy: JmxPolicy,
networkParameters: NetworkParameters
) = this.copy(
isDebug,
driverDirectory,
portAllocation,
debugPortAllocation,
systemProperties,
useTestClock,
true,
startNodesInProcess,
waitForAllNodesToFinish,
notarySpecs,
extraCordappPackagesToScan,
jmxPolicy,
networkParameters,
emptyMap()
)
fun copy(
isDebug: Boolean,
driverDirectory: Path,
portAllocation: PortAllocation,
debugPortAllocation: PortAllocation,
systemProperties: Map<String, String>,
useTestClock: Boolean,
initialiseSerialization: Boolean,
startNodesInProcess: Boolean,
waitForAllNodesToFinish: Boolean,
notarySpecs: List<NotarySpec>,
extraCordappPackagesToScan: List<String>,
jmxPolicy: JmxPolicy,
networkParameters: NetworkParameters
) = this.copy(
isDebug,
driverDirectory,
portAllocation,
debugPortAllocation,
systemProperties,
useTestClock,
initialiseSerialization,
startNodesInProcess,
waitForAllNodesToFinish,
notarySpecs,
extraCordappPackagesToScan,
jmxPolicy,
networkParameters,
emptyMap()
)
} }

View File

@ -100,7 +100,8 @@ class DriverDSLImpl(
val jmxPolicy: JmxPolicy, val jmxPolicy: JmxPolicy,
val notarySpecs: List<NotarySpec>, val notarySpecs: List<NotarySpec>,
val compatibilityZone: CompatibilityZoneParams?, val compatibilityZone: CompatibilityZoneParams?,
val networkParameters: NetworkParameters val networkParameters: NetworkParameters,
val notaryCustomOverrides: Map<String, Any?>
) : InternalDriverDSL { ) : InternalDriverDSL {
private var _executorService: ScheduledExecutorService? = null private var _executorService: ScheduledExecutorService? = null
val executorService get() = _executorService!! val executorService get() = _executorService!!
@ -224,18 +225,19 @@ class DriverDSLImpl(
val webAddress = portAllocation.nextHostAndPort() val webAddress = portAllocation.nextHostAndPort()
val users = rpcUsers.map { it.copy(permissions = it.permissions + DRIVER_REQUIRED_PERMISSIONS) } val users = rpcUsers.map { it.copy(permissions = it.permissions + DRIVER_REQUIRED_PERMISSIONS) }
val czUrlConfig = if (compatibilityZone != null) mapOf("compatibilityZoneURL" to compatibilityZone.url.toString()) else emptyMap() val czUrlConfig = if (compatibilityZone != null) mapOf("compatibilityZoneURL" to compatibilityZone.url.toString()) else emptyMap()
val overrides = configOf(
"myLegalName" to name.toString(),
"p2pAddress" to p2pAddress.toString(),
"rpcSettings.address" to rpcAddress.toString(),
"rpcSettings.adminAddress" to rpcAdminAddress.toString(),
"useTestClock" to useTestClock,
"rpcUsers" to if (users.isEmpty()) defaultRpcUserList else users.map { it.toConfig().root().unwrapped() },
"verifierType" to verifierType.name
) + czUrlConfig + customOverrides
val config = NodeConfig(ConfigHelper.loadConfig( val config = NodeConfig(ConfigHelper.loadConfig(
baseDirectory = baseDirectory(name), baseDirectory = baseDirectory(name),
allowMissingConfig = true, allowMissingConfig = true,
configOverrides = configOf( configOverrides = if (overrides.hasPath("devMode")) overrides else overrides + mapOf("devMode" to true)
"myLegalName" to name.toString(),
"p2pAddress" to p2pAddress.toString(),
"rpcSettings.address" to rpcAddress.toString(),
"rpcSettings.adminAddress" to rpcAdminAddress.toString(),
"useTestClock" to useTestClock,
"rpcUsers" to if (users.isEmpty()) defaultRpcUserList else users.map { it.toConfig().root().unwrapped() },
"verifierType" to verifierType.name
) + czUrlConfig + customOverrides
)) ))
return startNodeInternal(config, webAddress, startInSameProcess, maximumHeapSize, localNetworkMap) return startNodeInternal(config, webAddress, startInSameProcess, maximumHeapSize, localNetworkMap)
} }
@ -432,7 +434,7 @@ class DriverDSLImpl(
networkMapAvailability = notaryInfosFuture.map { it.second } networkMapAvailability = notaryInfosFuture.map { it.second }
_notaries = notaryInfosFuture.map { (notaryInfos, localNetworkMap) -> _notaries = notaryInfosFuture.map { (notaryInfos, localNetworkMap) ->
val listOfFutureNodeHandles = startNotaries(localNetworkMap) val listOfFutureNodeHandles = startNotaries(localNetworkMap, notaryCustomOverrides)
notaryInfos.zip(listOfFutureNodeHandles) { (identity, validating), nodeHandlesFuture -> notaryInfos.zip(listOfFutureNodeHandles) { (identity, validating), nodeHandlesFuture ->
NotaryHandle(identity, validating, nodeHandlesFuture) NotaryHandle(identity, validating, nodeHandlesFuture)
} }
@ -508,10 +510,10 @@ class DriverDSLImpl(
return (0 until spec.cluster!!.clusterSize).map { spec.name.copy(organisation = "${spec.name.organisation}-$it") } return (0 until spec.cluster!!.clusterSize).map { spec.name.copy(organisation = "${spec.name.organisation}-$it") }
} }
private fun startNotaries(localNetworkMap: LocalNetworkMap?): List<CordaFuture<List<NodeHandle>>> { private fun startNotaries(localNetworkMap: LocalNetworkMap?, customOverrides: Map<String, Any?>): List<CordaFuture<List<NodeHandle>>> {
return notarySpecs.map { return notarySpecs.map {
when (it.cluster) { when (it.cluster) {
null -> startSingleNotary(it, localNetworkMap) null -> startSingleNotary(it, localNetworkMap, customOverrides )
is ClusterSpec.Raft, is ClusterSpec.Raft,
// DummyCluster is used for testing the notary communication path, and it does not matter // DummyCluster is used for testing the notary communication path, and it does not matter
// which underlying consensus algorithm is used, so we just stick to Raft // which underlying consensus algorithm is used, so we just stick to Raft
@ -525,13 +527,13 @@ class DriverDSLImpl(
// generating the configs for the nodes, probably making use of Any.toConfig() // generating the configs for the nodes, probably making use of Any.toConfig()
private fun NotaryConfig.toConfigMap(): Map<String, Any> = mapOf("notary" to toConfig().root().unwrapped()) private fun NotaryConfig.toConfigMap(): Map<String, Any> = mapOf("notary" to toConfig().root().unwrapped())
private fun startSingleNotary(spec: NotarySpec, localNetworkMap: LocalNetworkMap?): CordaFuture<List<NodeHandle>> { private fun startSingleNotary(spec: NotarySpec, localNetworkMap: LocalNetworkMap?, customOverrides: Map<String, Any?>): CordaFuture<List<NodeHandle>> {
return startRegisteredNode( return startRegisteredNode(
spec.name, spec.name,
localNetworkMap, localNetworkMap,
spec.rpcUsers, spec.rpcUsers,
spec.verifierType, spec.verifierType,
customOverrides = NotaryConfig(spec.validating).toConfigMap() customOverrides = NotaryConfig(spec.validating).toConfigMap() + customOverrides
).map { listOf(it) } ).map { listOf(it) }
} }
@ -1037,7 +1039,8 @@ fun <DI : DriverDSL, D : InternalDriverDSL, A> genericDriver(
jmxPolicy = defaultParameters.jmxPolicy, jmxPolicy = defaultParameters.jmxPolicy,
notarySpecs = defaultParameters.notarySpecs, notarySpecs = defaultParameters.notarySpecs,
compatibilityZone = null, compatibilityZone = null,
networkParameters = defaultParameters.networkParameters networkParameters = defaultParameters.networkParameters,
notaryCustomOverrides = defaultParameters.notaryCustomOverrides
) )
) )
val shutdownHook = addShutdownHook(driverDsl::shutdown) val shutdownHook = addShutdownHook(driverDsl::shutdown)
@ -1081,6 +1084,7 @@ fun <A> internalDriver(
jmxPolicy: JmxPolicy = DriverParameters().jmxPolicy, jmxPolicy: JmxPolicy = DriverParameters().jmxPolicy,
networkParameters: NetworkParameters = DriverParameters().networkParameters, networkParameters: NetworkParameters = DriverParameters().networkParameters,
compatibilityZone: CompatibilityZoneParams? = null, compatibilityZone: CompatibilityZoneParams? = null,
notaryCustomOverrides: Map<String, Any?> = DriverParameters().notaryCustomOverrides,
dsl: DriverDSLImpl.() -> A dsl: DriverDSLImpl.() -> A
): A { ): A {
return genericDriver( return genericDriver(
@ -1097,7 +1101,8 @@ fun <A> internalDriver(
extraCordappPackagesToScan = extraCordappPackagesToScan, extraCordappPackagesToScan = extraCordappPackagesToScan,
jmxPolicy = jmxPolicy, jmxPolicy = jmxPolicy,
compatibilityZone = compatibilityZone, compatibilityZone = compatibilityZone,
networkParameters = networkParameters networkParameters = networkParameters,
notaryCustomOverrides = notaryCustomOverrides
), ),
coerce = { it }, coerce = { it },
dsl = dsl, dsl = dsl,

View File

@ -105,6 +105,7 @@ abstract class NodeBasedTest(private val cordappPackages: List<String> = emptyLi
"database" to mapOf("runMigration" to "true"), "database" to mapOf("runMigration" to "true"),
"myLegalName" to legalName.toString(), "myLegalName" to legalName.toString(),
"p2pAddress" to p2pAddress, "p2pAddress" to p2pAddress,
"devMode" to true,
"rpcSettings.address" to localPort[1].toString(), "rpcSettings.address" to localPort[1].toString(),
"rpcSettings.adminAddress" to localPort[2].toString(), "rpcSettings.adminAddress" to localPort[2].toString(),
"rpcUsers" to rpcUsers.map { it.toConfig().root().unwrapped() } "rpcUsers" to rpcUsers.map { it.toConfig().root().unwrapped() }

View File

@ -126,6 +126,7 @@ fun <A> rpcDriver(
externalTrace: Trace? = null, externalTrace: Trace? = null,
jmxPolicy: JmxPolicy = JmxPolicy(), jmxPolicy: JmxPolicy = JmxPolicy(),
networkParameters: NetworkParameters = testNetworkParameters(notaries = emptyList()), networkParameters: NetworkParameters = testNetworkParameters(notaries = emptyList()),
notaryCustomOverrides: Map<String, Any?> = emptyMap(),
dsl: RPCDriverDSL.() -> A dsl: RPCDriverDSL.() -> A
): A { ): A {
return genericDriver( return genericDriver(
@ -143,7 +144,8 @@ fun <A> rpcDriver(
notarySpecs = notarySpecs, notarySpecs = notarySpecs,
jmxPolicy = jmxPolicy, jmxPolicy = jmxPolicy,
compatibilityZone = null, compatibilityZone = null,
networkParameters = networkParameters networkParameters = networkParameters,
notaryCustomOverrides = notaryCustomOverrides
), externalTrace ), externalTrace
), ),
coerce = { it }, coerce = { it },

View File

@ -48,6 +48,7 @@ class NodeConfigTest {
val nodeConfig = config.nodeConf() val nodeConfig = config.nodeConf()
.withValue("baseDirectory", ConfigValueFactory.fromAnyRef(baseDir.toString())) .withValue("baseDirectory", ConfigValueFactory.fromAnyRef(baseDir.toString()))
.withFallback(ConfigFactory.parseResources("reference.conf")) .withFallback(ConfigFactory.parseResources("reference.conf"))
.withFallback(ConfigFactory.parseMap(mapOf("devMode" to true)))
.resolve() .resolve()
val fullConfig = nodeConfig.parseAsNodeConfiguration() val fullConfig = nodeConfig.parseAsNodeConfiguration()