From c670ed6bdd561ddc69b6d61d8868c7b12a832f23 Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Fri, 27 Jan 2017 11:36:46 +0000 Subject: [PATCH] The first node now becomes the session's Network Map service used by all other nodes. Force nodes to be created one-by-one. --- .../corda/demobench/model/NetworkMapConfig.kt | 23 +++++++++++ .../net/corda/demobench/model/NodeConfig.kt | 41 +++++++------------ .../corda/demobench/model/NodeController.kt | 24 ++++++++++- .../net/corda/demobench/model/NodeData.kt | 3 +- .../corda/demobench/model/NodeDataModel.kt | 1 - .../corda/demobench/views/DemoBenchView.kt | 6 +++ .../net/corda/demobench/views/NodeTabView.kt | 24 +++-------- .../corda/demobench/views/NodeTerminalView.kt | 2 +- 8 files changed, 74 insertions(+), 50 deletions(-) create mode 100644 tools/demobench/src/main/kotlin/net/corda/demobench/model/NetworkMapConfig.kt diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NetworkMapConfig.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NetworkMapConfig.kt new file mode 100644 index 0000000000..34c0e47db3 --- /dev/null +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NetworkMapConfig.kt @@ -0,0 +1,23 @@ +package net.corda.demobench.model + +open class NetworkMapConfig(legalName: String, artemisPort: Int) { + + private var keyValue: String = toKey(legalName) + val key : String + get() { return keyValue } + + private var legalNameValue: String = legalName + val legalName : String + get() { return legalNameValue } + + private var artemisPortValue: Int = artemisPort + val artemisPort : Int + get() { return artemisPortValue } + +} + +private val WHITESPACE = Regex("\\s++") + +fun toKey(value: String): String { + return value.replace(WHITESPACE, "").toLowerCase() +} diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeConfig.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeConfig.kt index f25700b2fa..88e14b5393 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeConfig.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeConfig.kt @@ -5,47 +5,31 @@ import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigValue import com.typesafe.config.ConfigValueFactory -class NodeConfig(legalName: String, nearestCity: String, p2pPort: Int, artemisPort: Int, webPort: Int) { - - private var keyValue: String = toKey(legalName) - val key : String - get() { return keyValue } - - private var legalNameValue: String = legalName - val legalName : String - get() { return legalNameValue } +class NodeConfig(legalName: String, artemisPort: Int, nearestCity: String, webPort: Int) : NetworkMapConfig(legalName, artemisPort){ private var nearestCityName: String = nearestCity val nearestCity : String get() { return nearestCityName } - private var p2pPortValue: Int = p2pPort - val p2pPort : Int - get() { return p2pPortValue } - - private var artemisPortValue: Int = artemisPort - val artemisPort : Int - get() { return artemisPortValue } - private var webPortValue: Int = webPort val webPort : Int get() { return webPortValue } - private fun toKey(value: String): String { - return value.replace("\\s++", "").toLowerCase() - } + private var networkMapValue: NetworkMapConfig? = null + var networkMap : NetworkMapConfig? + get() { return networkMapValue } + set(value) { networkMapValue = value } val toFileConfig : Config get() = ConfigFactory.empty() .withValue("myLegalName", valueFor(legalName)) + .withValue("artemisAddress", addressValueFor(artemisPort)) .withValue("nearestCity", valueFor(nearestCity)) .withValue("extraAdvertisedServiceIds", valueFor("")) - .withFallback(ConfigFactory.empty() - .withValue("address", addressValueFor(p2pPort)) - .withValue("legalName", valueFor("Notary")) - .atPath("networkMapService") - ) - .withValue("artemisAddress", addressValueFor(artemisPort)) + .withFallback(optional("networkMapService", networkMap, { + c, n -> c.withValue("address", addressValueFor(n.artemisPort)) + .withValue("legalName", valueFor(n.legalName)) + } )) .withValue("webAddress", addressValueFor(webPort)) .withValue("rpcUsers", valueFor(listOf())) .withValue("useTestClock", valueFor(true)) @@ -59,3 +43,8 @@ private fun valueFor(any: T): ConfigValue? { private fun addressValueFor(port: Int): ConfigValue? { return valueFor("localhost:%d".format(port)) } + +private fun optional(path: String, obj: T?, body: (c: Config, o: T) -> Config): Config { + val config = ConfigFactory.empty() + return if (obj == null) config else body(config, obj).atPath(path) +} diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt index 70fdf0464b..297041fc87 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeController.kt @@ -26,25 +26,44 @@ class NodeController : Controller() { private val nodes = ConcurrentHashMap() private val port = AtomicInteger(FIRST_PORT) + private var networkMapConfig: NetworkMapConfig? = null + fun validate(nodeData: NodeData): NodeConfig? { val config = NodeConfig( nodeData.legalName.value, - nodeData.nearestCity.value, - nodeData.p2pPort.value, nodeData.artemisPort.value, + nodeData.nearestCity.value, nodeData.webPort.value ) + log.info("Node key: " + config.key) + if (nodes.putIfAbsent(config.key, config) != null) { return null } + // The first node becomes our network map + chooseNetworkMap(config) + return config } val nextPort: Int get() { return port.andIncrement } + fun exists(name: String): Boolean { + return nodes.keys.contains(toKey(name)) + } + + fun chooseNetworkMap(config: NodeConfig) { + if (networkMapConfig != null) { + config.networkMap = networkMapConfig + } else { + networkMapConfig = config + log.info("Network map provided by: " + config.legalName) + } + } + fun runCorda(pty: R3Pty, config: NodeConfig): Boolean { val nodeDir = workDir.resolve(config.key).toFile() @@ -73,5 +92,6 @@ class NodeController : Controller() { init { log.info("Working directory: " + workDir) log.info("Java executable: " + javaPath) + log.info("Corda JAR: " + command[0]) } } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeData.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeData.kt index 672cdfc344..4101f288fa 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeData.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeData.kt @@ -7,8 +7,7 @@ class NodeData { var legalName = SimpleStringProperty("") val nearestCity = SimpleStringProperty("London") - var p2pPort = SimpleIntegerProperty(0) val artemisPort = SimpleIntegerProperty(0) val webPort = SimpleIntegerProperty(0) -} \ No newline at end of file +} diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeDataModel.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeDataModel.kt index 9791b468a8..b9504e24f9 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeDataModel.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/NodeDataModel.kt @@ -6,7 +6,6 @@ class NodeDataModel : ItemViewModel(NodeData()) { val legalName = bind { item?.legalName } val nearestCity = bind { item?.nearestCity } - val p2pPort = bind { item?.p2pPort } val artemisPort = bind { item?.artemisPort } val webPort = bind { item?.webPort } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/views/DemoBenchView.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/views/DemoBenchView.kt index aa40180e08..207bffd941 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/views/DemoBenchView.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/views/DemoBenchView.kt @@ -29,6 +29,9 @@ class DemoBenchView : View("Corda Demo Bench") { addNodeButton.setOnAction { val nodeTab = createNodeTab() nodeTabPane.selectionModel.select(nodeTab) + + // Prevent us from creating new nodes until we have created the Network Map + addNodeButton.isDisable = true } addNodeButton.fire() } @@ -47,4 +50,7 @@ class DemoBenchView : View("Corda Demo Bench") { return nodeTab } + fun enableAddNodes() { + addNodeButton.isDisable = false + } } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt index d3996198a5..bbc4c60198 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTabView.kt @@ -10,6 +10,8 @@ import tornadofx.* class NodeTabView : Fragment() { override val root = stackpane {} + private val main by inject() + private val INTEGER_FORMAT = DecimalFormat() private val NOT_NUMBER = Regex("[^\\d]") @@ -25,8 +27,10 @@ class NodeTabView : Fragment() { minWidth = 200.0 maxWidth = 200.0 validator { - if (it.isNullOrBlank()) { + if ((it == null) || it.isBlank()) { error("Node name is required") + } else if (controller.exists(it)) { + error("Node with this name already exists") } else { null } @@ -47,21 +51,6 @@ class NodeTabView : Fragment() { } } field("P2P Port") { - textfield(model.p2pPort, NumberStringConverter(INTEGER_FORMAT)) { - minWidth = 100.0 - maxWidth = 100.0 - validator { - if ((it == null) || it.isEmpty()) { - error("Port number required") - } else if (it.contains(NOT_NUMBER)) { - error("Invalid port number") - } else { - null - } - } - } - } - field("Artemis Port") { textfield(model.artemisPort, NumberStringConverter(INTEGER_FORMAT)) { minWidth = 100.0 maxWidth = 100.0 @@ -94,12 +83,12 @@ class NodeTabView : Fragment() { } fieldset("Plugins") { - } button("Create Node") { setOnAction() { launch() + main.enableAddNodes() } } } @@ -135,7 +124,6 @@ class NodeTabView : Fragment() { root.add(nodeConfigView) root.add(nodeTerminalView) - model.p2pPort.value = controller.nextPort model.artemisPort.value = controller.nextPort model.webPort.value = controller.nextPort } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt index 961f47417c..6ae79b593a 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/views/NodeTerminalView.kt @@ -35,7 +35,7 @@ class NodeTerminalView : Fragment() { fun open(config: NodeConfig) { nodeName.text = config.legalName - p2pPort.value = config.p2pPort.toString() + p2pPort.value = config.artemisPort.toString() val swingTerminal = SwingNode() swingTerminal.setOnMouseClicked {