mirror of
https://github.com/corda/corda.git
synced 2025-02-15 15:12:46 +00:00
Merge pull request #839 from corda/tudor_merge_14_05_2018
Tudor merge 14 05 2018
This commit is contained in:
commit
274dead627
@ -120,7 +120,9 @@ buildscript {
|
||||
classpath "net.corda.plugins:quasar-utils:$gradle_plugins_version"
|
||||
classpath "net.corda.plugins:cordformation:$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 "org.jetbrains.kotlin:kotlin-noarg:$kotlin_version"
|
||||
classpath "org.jetbrains.dokka:dokka-gradle-plugin:${dokka_version}"
|
||||
|
@ -8,7 +8,7 @@
|
||||
# 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
|
||||
platformVersion=4
|
||||
guavaVersion=21.0
|
||||
|
@ -55,6 +55,10 @@ object Emoji {
|
||||
val CODE_FREE: String = codePointsString(0x1F193)
|
||||
@JvmStatic
|
||||
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 free: String get() = if (emojiMode.get() != null) "$CODE_FREE " 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.
|
||||
val greenTick: String get() = if (emojiMode.get() != null) "$CODE_GREEN_TICK " else "✓"
|
||||
|
@ -10,6 +10,12 @@ Unreleased
|
||||
|
||||
* 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:
|
||||
|
||||
* ``Instant`` and ``Date`` objects are serialised as ISO-8601 formatted strings rather than timestamps
|
||||
|
@ -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``
|
||||
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
|
||||
bugs in the checkpointing process. Also, if ``devMode`` is true, Hibernate will try to automatically create the schema required by Corda
|
||||
or update an existing schema in the SQL database; if ``devMode`` is false, Hibernate will simply validate an existing schema
|
||||
failing on node start if this schema is either not present or not compatible.
|
||||
bugs in the checkpointing process.
|
||||
Also, if ``devMode`` is true, Hibernate will try to automatically create the schema required by Corda
|
||||
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
|
||||
attempt to discover its externally visible IP address first by looking for any public addresses on its network
|
||||
|
@ -95,11 +95,12 @@ class NetworkParametersUpdateTest : IntegrationTest() {
|
||||
compatibilityZone = compatibilityZone,
|
||||
notarySpecs = emptyList(),
|
||||
initialiseSerialization = false,
|
||||
extraCordappPackagesToScan = listOf("net.corda.finance")
|
||||
extraCordappPackagesToScan = listOf("net.corda.finance"),
|
||||
notaryCustomOverrides = mapOf("devMode" to false)
|
||||
) {
|
||||
var (alice, bob) = listOf(
|
||||
startNode(providedName = ALICE_NAME),
|
||||
startNode(providedName = BOB_NAME)
|
||||
startNode(providedName = ALICE_NAME, customOverrides = mapOf("devMode" to false)),
|
||||
startNode(providedName = BOB_NAME, customOverrides = mapOf("devMode" to false))
|
||||
).map { it.getOrThrow() as NodeHandleInternal }
|
||||
|
||||
// Make sure that stopping Bob doesn't remove him from the network map
|
||||
@ -139,7 +140,7 @@ class NetworkParametersUpdateTest : IntegrationTest() {
|
||||
applyNetworkParametersAndStart(NetworkParametersCmd.FlagDay)
|
||||
|
||||
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
|
||||
val networkParameters = (alice.configuration.baseDirectory / NETWORK_PARAMS_FILE_NAME)
|
||||
|
@ -130,17 +130,18 @@ class NodeRegistrationTest : IntegrationTest() {
|
||||
compatibilityZone = compatibilityZone,
|
||||
initialiseSerialization = false,
|
||||
notarySpecs = listOf(NotarySpec(notaryName)),
|
||||
extraCordappPackagesToScan = listOf("net.corda.finance")
|
||||
extraCordappPackagesToScan = listOf("net.corda.finance"),
|
||||
notaryCustomOverrides = mapOf("devMode" to false)
|
||||
) {
|
||||
val (alice, notary) = listOf(
|
||||
startNode(providedName = aliceName),
|
||||
startNode(providedName = aliceName, customOverrides = mapOf("devMode" to false)),
|
||||
defaultNotaryNode
|
||||
).map { it.getOrThrow() as NodeHandleInternal }
|
||||
|
||||
alice.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
|
||||
Thread.sleep(timeoutMillis * 2)
|
||||
|
@ -101,11 +101,12 @@ class NodeRegistrationTest : IntegrationTest() {
|
||||
compatibilityZone = compatibilityZone,
|
||||
initialiseSerialization = false,
|
||||
notarySpecs = listOf(NotarySpec(notaryName)),
|
||||
extraCordappPackagesToScan = listOf("net.corda.finance")
|
||||
extraCordappPackagesToScan = listOf("net.corda.finance"),
|
||||
notaryCustomOverrides = mapOf("devMode" to false)
|
||||
) {
|
||||
val (alice, genevieve) = listOf(
|
||||
startNode(providedName = aliceName),
|
||||
startNode(providedName = genevieveName)
|
||||
startNode(providedName = aliceName, customOverrides = mapOf("devMode" to false)),
|
||||
startNode(providedName = genevieveName, customOverrides = mapOf("devMode" to false))
|
||||
).transpose().getOrThrow()
|
||||
|
||||
assertThat(registrationHandler.idsPolled).containsOnly(
|
||||
|
@ -57,6 +57,7 @@ class NodeArgsParser : AbstractArgsParser<CmdLineOptions>() {
|
||||
.withRequiredArg()
|
||||
.withValuesConvertedBy(object : EnumConverter<UnknownConfigKeysPolicy>(UnknownConfigKeysPolicy::class.java) {})
|
||||
.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 justGenerateNodeInfoArg = optionParser.accepts("just-generate-node-info",
|
||||
@ -80,6 +81,7 @@ class NodeArgsParser : AbstractArgsParser<CmdLineOptions>() {
|
||||
val networkRootTrustStorePath = optionSet.valueOf(networkRootTrustStorePathArg)
|
||||
val networkRootTrustStorePassword = optionSet.valueOf(networkRootTrustStorePasswordArg)
|
||||
val unknownConfigKeysPolicy = optionSet.valueOf(unknownConfigKeysPolicy)
|
||||
val devMode = optionSet.has(devModeArg)
|
||||
|
||||
val registrationConfig = if (isRegistration) {
|
||||
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,
|
||||
justGenerateNodeInfo,
|
||||
bootstrapRaftCluster,
|
||||
unknownConfigKeysPolicy)
|
||||
unknownConfigKeysPolicy,
|
||||
devMode)
|
||||
}
|
||||
}
|
||||
|
||||
@ -115,12 +118,14 @@ data class CmdLineOptions(val baseDirectory: Path,
|
||||
val sshdServer: Boolean,
|
||||
val justGenerateNodeInfo: Boolean,
|
||||
val bootstrapRaftCluster: Boolean,
|
||||
val unknownConfigKeysPolicy: UnknownConfigKeysPolicy) {
|
||||
val unknownConfigKeysPolicy: UnknownConfigKeysPolicy,
|
||||
val devMode: Boolean) {
|
||||
fun loadConfig(): NodeConfiguration {
|
||||
val config = ConfigHelper.loadConfig(
|
||||
baseDirectory,
|
||||
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)
|
||||
if (nodeRegistrationOption != null) {
|
||||
require(!config.devMode) { "registration cannot occur in devMode" }
|
||||
|
@ -23,6 +23,7 @@ import net.corda.core.flows.*
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.identity.PartyAndCertificate
|
||||
import net.corda.core.internal.Emoji
|
||||
import net.corda.core.internal.FlowStateMachine
|
||||
import net.corda.core.internal.VisibleForTesting
|
||||
import net.corda.core.internal.concurrent.map
|
||||
@ -179,8 +180,10 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
|
||||
|
||||
private fun initCertificate() {
|
||||
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()
|
||||
} 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()
|
||||
}
|
||||
@ -205,6 +208,9 @@ abstract class AbstractNode(val configuration: NodeConfiguration,
|
||||
|
||||
open fun start(): StartedNode<AbstractNode> {
|
||||
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 ...")
|
||||
initCertificate()
|
||||
initialiseJVMAgents()
|
||||
|
@ -13,6 +13,7 @@ package net.corda.node.internal
|
||||
import com.codahale.metrics.JmxReporter
|
||||
import net.corda.client.rpc.internal.serialization.kryo.KryoClientSerializationScheme
|
||||
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.thenMatch
|
||||
import net.corda.core.internal.div
|
||||
@ -85,6 +86,13 @@ open class Node(configuration: NodeConfiguration,
|
||||
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 {
|
||||
println(message)
|
||||
println("Corda will now exit...")
|
||||
|
@ -46,6 +46,10 @@ object ConfigHelper {
|
||||
val appConfig = ConfigFactory.parseFile(configFile.toFile(), parseOptions.setAllowMissing(allowMissingConfig))
|
||||
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 environmentOverrides = systemEnvironment().cordaEntriesOnly()
|
||||
val finalConfig = configOverrides
|
||||
@ -56,6 +60,7 @@ object ConfigHelper {
|
||||
.withFallback(configOf("baseDirectory" to baseDirectory.toString()))
|
||||
.withFallback(databaseConfig) //for database integration tests
|
||||
.withFallback(appConfig)
|
||||
.withFallback(devModeConfig) // this needs to be after the appConfig, so it doesn't override the configured devMode
|
||||
.withFallback(defaultConfig)
|
||||
.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) */
|
||||
fun parseToDbSchemaFriendlyName(value: String) =
|
||||
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)
|
||||
}
|
@ -22,7 +22,6 @@ database = {
|
||||
transactionIsolationLevel = "REPEATABLE_READ"
|
||||
exportHibernateJMXStatistics = "false"
|
||||
}
|
||||
devMode = true
|
||||
h2port = 0
|
||||
useTestClock = false
|
||||
verifierType = InMemory
|
||||
|
@ -53,7 +53,8 @@ class NodeArgsParserTest {
|
||||
sshdServer = false,
|
||||
justGenerateNodeInfo = false,
|
||||
bootstrapRaftCluster = false,
|
||||
unknownConfigKeysPolicy = UnknownConfigKeysPolicy.FAIL))
|
||||
unknownConfigKeysPolicy = UnknownConfigKeysPolicy.FAIL,
|
||||
devMode = false))
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -11,7 +11,10 @@
|
||||
package net.corda.node.services.config
|
||||
|
||||
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.toPath
|
||||
import net.corda.core.utilities.NetworkHostAndPort
|
||||
import net.corda.nodeapi.internal.persistence.CordaPersistence.DataSourceConfigTag
|
||||
import net.corda.core.utilities.seconds
|
||||
@ -86,6 +89,59 @@ class NodeConfigurationImplTest {
|
||||
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
|
||||
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())
|
||||
|
1
node/src/test/resources/test-config-DevMode.conf
Normal file
1
node/src/test/resources/test-config-DevMode.conf
Normal file
@ -0,0 +1 @@
|
||||
devMode=true
|
0
node/src/test/resources/test-config-empty.conf
Normal file
0
node/src/test/resources/test-config-empty.conf
Normal file
1
node/src/test/resources/test-config-noDevMode.conf
Normal file
1
node/src/test/resources/test-config-noDevMode.conf
Normal file
@ -0,0 +1 @@
|
||||
devMode=false
|
@ -46,6 +46,7 @@ class BankOfCordaCordform : CordformDefinition() {
|
||||
address("localhost:10003")
|
||||
adminAddress("localhost:10004")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
node {
|
||||
name(BOC_NAME)
|
||||
@ -57,6 +58,7 @@ class BankOfCordaCordform : CordformDefinition() {
|
||||
}
|
||||
webPort(BOC_WEB_PORT)
|
||||
rpcUsers(User("bankUser", "test", setOf(all())))
|
||||
devMode(true)
|
||||
}
|
||||
node {
|
||||
name(BIGCORP_NAME)
|
||||
@ -67,6 +69,7 @@ class BankOfCordaCordform : CordformDefinition() {
|
||||
}
|
||||
webPort(10010)
|
||||
rpcUsers(User("bigCorpUser", "test", setOf(all())))
|
||||
devMode(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ class BFTNotaryCordform : CordformDefinition() {
|
||||
adminAddress("localhost:10103")
|
||||
}
|
||||
rpcUsers(notaryDemoUser)
|
||||
devMode(true)
|
||||
}
|
||||
node {
|
||||
name(BOB_NAME)
|
||||
@ -52,6 +53,7 @@ class BFTNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10006")
|
||||
adminAddress("localhost:10106")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
val clusterAddresses = (0 until clusterSize).map { NetworkHostAndPort("localhost", 11000 + it * 10) }
|
||||
fun notaryNode(replicaId: Int, configure: CordformNode.() -> Unit) = node {
|
||||
@ -65,6 +67,7 @@ class BFTNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10010")
|
||||
adminAddress("localhost:10110")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
notaryNode(1) {
|
||||
p2pPort(10013)
|
||||
@ -72,6 +75,7 @@ class BFTNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10014")
|
||||
adminAddress("localhost:10114")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
notaryNode(2) {
|
||||
p2pPort(10017)
|
||||
@ -79,6 +83,7 @@ class BFTNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10018")
|
||||
adminAddress("localhost:10118")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
notaryNode(3) {
|
||||
p2pPort(10021)
|
||||
@ -86,6 +91,7 @@ class BFTNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10022")
|
||||
adminAddress("localhost:10122")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ class CustomNotaryCordform : CordformDefinition() {
|
||||
adminAddress("localhost:10103")
|
||||
}
|
||||
rpcUsers(notaryDemoUser)
|
||||
devMode(true)
|
||||
}
|
||||
node {
|
||||
name(BOB_NAME)
|
||||
@ -40,6 +41,7 @@ class CustomNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10006")
|
||||
adminAddress("localhost:10106")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
node {
|
||||
name(DUMMY_NOTARY_NAME)
|
||||
@ -49,6 +51,7 @@ class CustomNotaryCordform : CordformDefinition() {
|
||||
adminAddress("localhost:10110")
|
||||
}
|
||||
notary(NotaryConfig(validating = true, custom = true))
|
||||
devMode(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -44,6 +44,7 @@ class RaftNotaryCordform : CordformDefinition() {
|
||||
adminAddress("localhost:10103")
|
||||
}
|
||||
rpcUsers(notaryDemoUser)
|
||||
devMode(true)
|
||||
}
|
||||
node {
|
||||
name(BOB_NAME)
|
||||
@ -52,12 +53,14 @@ class RaftNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10006")
|
||||
adminAddress("localhost:10106")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
fun notaryNode(index: Int, nodePort: Int, clusterPort: Int? = null, configure: CordformNode.() -> Unit) = node {
|
||||
name(notaryNames[index])
|
||||
val clusterAddresses = if (clusterPort != null ) listOf(NetworkHostAndPort("localhost", clusterPort)) else emptyList()
|
||||
notary(NotaryConfig(validating = true, raft = RaftConfig(NetworkHostAndPort("localhost", nodePort), clusterAddresses)))
|
||||
configure()
|
||||
devMode(true)
|
||||
}
|
||||
notaryNode(0, 10008) {
|
||||
p2pPort(10009)
|
||||
@ -65,6 +68,7 @@ class RaftNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10010")
|
||||
adminAddress("localhost:10110")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
notaryNode(1, 10012, 10008) {
|
||||
p2pPort(10013)
|
||||
@ -72,6 +76,7 @@ class RaftNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10014")
|
||||
adminAddress("localhost:10114")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
notaryNode(2, 10016, 10008) {
|
||||
p2pPort(10017)
|
||||
@ -79,6 +84,7 @@ class RaftNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10018")
|
||||
adminAddress("localhost:10118")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -38,6 +38,7 @@ class SingleNotaryCordform : CordformDefinition() {
|
||||
adminAddress("localhost:10103")
|
||||
}
|
||||
rpcUsers(notaryDemoUser)
|
||||
devMode(true)
|
||||
}
|
||||
node {
|
||||
name(BOB_NAME)
|
||||
@ -46,6 +47,7 @@ class SingleNotaryCordform : CordformDefinition() {
|
||||
address("localhost:10006")
|
||||
adminAddress("localhost:10106")
|
||||
}
|
||||
devMode(true)
|
||||
}
|
||||
node {
|
||||
name(DUMMY_NOTARY_NAME)
|
||||
@ -55,6 +57,7 @@ class SingleNotaryCordform : CordformDefinition() {
|
||||
adminAddress("localhost:10110")
|
||||
}
|
||||
notary(NotaryConfig(validating = true))
|
||||
devMode(true)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -176,7 +176,7 @@ data class NodeParameters(
|
||||
*/
|
||||
data class JmxPolicy(val startJmxHttpServer: Boolean = false,
|
||||
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:
|
||||
@ -211,7 +211,8 @@ fun <A> driver(defaultParameters: DriverParameters = DriverParameters(), dsl: Dr
|
||||
extraCordappPackagesToScan = defaultParameters.extraCordappPackagesToScan,
|
||||
jmxPolicy = defaultParameters.jmxPolicy,
|
||||
compatibilityZone = null,
|
||||
networkParameters = defaultParameters.networkParameters
|
||||
networkParameters = defaultParameters.networkParameters,
|
||||
notaryCustomOverrides = defaultParameters.notaryCustomOverrides
|
||||
),
|
||||
coerce = { it },
|
||||
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 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.
|
||||
*/
|
||||
@Suppress("unused")
|
||||
data class DriverParameters(
|
||||
@ -258,8 +260,70 @@ data class DriverParameters(
|
||||
val notarySpecs: List<NotarySpec> = listOf(NotarySpec(DUMMY_NOTARY_NAME)),
|
||||
val extraCordappPackagesToScan: List<String> = emptyList(),
|
||||
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 withDriverDirectory(driverDirectory: Path): DriverParameters = copy(driverDirectory = driverDirectory)
|
||||
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 withJmxPolicy(jmxPolicy: JmxPolicy): DriverParameters = copy(jmxPolicy = jmxPolicy)
|
||||
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()
|
||||
)
|
||||
}
|
||||
|
@ -100,7 +100,8 @@ class DriverDSLImpl(
|
||||
val jmxPolicy: JmxPolicy,
|
||||
val notarySpecs: List<NotarySpec>,
|
||||
val compatibilityZone: CompatibilityZoneParams?,
|
||||
val networkParameters: NetworkParameters
|
||||
val networkParameters: NetworkParameters,
|
||||
val notaryCustomOverrides: Map<String, Any?>
|
||||
) : InternalDriverDSL {
|
||||
private var _executorService: ScheduledExecutorService? = null
|
||||
val executorService get() = _executorService!!
|
||||
@ -224,18 +225,19 @@ class DriverDSLImpl(
|
||||
val webAddress = portAllocation.nextHostAndPort()
|
||||
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 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(
|
||||
baseDirectory = baseDirectory(name),
|
||||
allowMissingConfig = true,
|
||||
configOverrides = 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
|
||||
configOverrides = if (overrides.hasPath("devMode")) overrides else overrides + mapOf("devMode" to true)
|
||||
))
|
||||
return startNodeInternal(config, webAddress, startInSameProcess, maximumHeapSize, localNetworkMap)
|
||||
}
|
||||
@ -432,7 +434,7 @@ class DriverDSLImpl(
|
||||
networkMapAvailability = notaryInfosFuture.map { it.second }
|
||||
|
||||
_notaries = notaryInfosFuture.map { (notaryInfos, localNetworkMap) ->
|
||||
val listOfFutureNodeHandles = startNotaries(localNetworkMap)
|
||||
val listOfFutureNodeHandles = startNotaries(localNetworkMap, notaryCustomOverrides)
|
||||
notaryInfos.zip(listOfFutureNodeHandles) { (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") }
|
||||
}
|
||||
|
||||
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 {
|
||||
when (it.cluster) {
|
||||
null -> startSingleNotary(it, localNetworkMap)
|
||||
null -> startSingleNotary(it, localNetworkMap, customOverrides )
|
||||
is ClusterSpec.Raft,
|
||||
// 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
|
||||
@ -525,13 +527,13 @@ class DriverDSLImpl(
|
||||
// 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 startSingleNotary(spec: NotarySpec, localNetworkMap: LocalNetworkMap?): CordaFuture<List<NodeHandle>> {
|
||||
private fun startSingleNotary(spec: NotarySpec, localNetworkMap: LocalNetworkMap?, customOverrides: Map<String, Any?>): CordaFuture<List<NodeHandle>> {
|
||||
return startRegisteredNode(
|
||||
spec.name,
|
||||
localNetworkMap,
|
||||
spec.rpcUsers,
|
||||
spec.verifierType,
|
||||
customOverrides = NotaryConfig(spec.validating).toConfigMap()
|
||||
customOverrides = NotaryConfig(spec.validating).toConfigMap() + customOverrides
|
||||
).map { listOf(it) }
|
||||
}
|
||||
|
||||
@ -1037,7 +1039,8 @@ fun <DI : DriverDSL, D : InternalDriverDSL, A> genericDriver(
|
||||
jmxPolicy = defaultParameters.jmxPolicy,
|
||||
notarySpecs = defaultParameters.notarySpecs,
|
||||
compatibilityZone = null,
|
||||
networkParameters = defaultParameters.networkParameters
|
||||
networkParameters = defaultParameters.networkParameters,
|
||||
notaryCustomOverrides = defaultParameters.notaryCustomOverrides
|
||||
)
|
||||
)
|
||||
val shutdownHook = addShutdownHook(driverDsl::shutdown)
|
||||
@ -1081,6 +1084,7 @@ fun <A> internalDriver(
|
||||
jmxPolicy: JmxPolicy = DriverParameters().jmxPolicy,
|
||||
networkParameters: NetworkParameters = DriverParameters().networkParameters,
|
||||
compatibilityZone: CompatibilityZoneParams? = null,
|
||||
notaryCustomOverrides: Map<String, Any?> = DriverParameters().notaryCustomOverrides,
|
||||
dsl: DriverDSLImpl.() -> A
|
||||
): A {
|
||||
return genericDriver(
|
||||
@ -1097,7 +1101,8 @@ fun <A> internalDriver(
|
||||
extraCordappPackagesToScan = extraCordappPackagesToScan,
|
||||
jmxPolicy = jmxPolicy,
|
||||
compatibilityZone = compatibilityZone,
|
||||
networkParameters = networkParameters
|
||||
networkParameters = networkParameters,
|
||||
notaryCustomOverrides = notaryCustomOverrides
|
||||
),
|
||||
coerce = { it },
|
||||
dsl = dsl,
|
||||
|
@ -105,6 +105,7 @@ abstract class NodeBasedTest(private val cordappPackages: List<String> = emptyLi
|
||||
"database" to mapOf("runMigration" to "true"),
|
||||
"myLegalName" to legalName.toString(),
|
||||
"p2pAddress" to p2pAddress,
|
||||
"devMode" to true,
|
||||
"rpcSettings.address" to localPort[1].toString(),
|
||||
"rpcSettings.adminAddress" to localPort[2].toString(),
|
||||
"rpcUsers" to rpcUsers.map { it.toConfig().root().unwrapped() }
|
||||
|
@ -126,6 +126,7 @@ fun <A> rpcDriver(
|
||||
externalTrace: Trace? = null,
|
||||
jmxPolicy: JmxPolicy = JmxPolicy(),
|
||||
networkParameters: NetworkParameters = testNetworkParameters(notaries = emptyList()),
|
||||
notaryCustomOverrides: Map<String, Any?> = emptyMap(),
|
||||
dsl: RPCDriverDSL.() -> A
|
||||
): A {
|
||||
return genericDriver(
|
||||
@ -143,7 +144,8 @@ fun <A> rpcDriver(
|
||||
notarySpecs = notarySpecs,
|
||||
jmxPolicy = jmxPolicy,
|
||||
compatibilityZone = null,
|
||||
networkParameters = networkParameters
|
||||
networkParameters = networkParameters,
|
||||
notaryCustomOverrides = notaryCustomOverrides
|
||||
), externalTrace
|
||||
),
|
||||
coerce = { it },
|
||||
|
@ -48,6 +48,7 @@ class NodeConfigTest {
|
||||
val nodeConfig = config.nodeConf()
|
||||
.withValue("baseDirectory", ConfigValueFactory.fromAnyRef(baseDir.toString()))
|
||||
.withFallback(ConfigFactory.parseResources("reference.conf"))
|
||||
.withFallback(ConfigFactory.parseMap(mapOf("devMode" to true)))
|
||||
.resolve()
|
||||
val fullConfig = nodeConfig.parseAsNodeConfiguration()
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user