mirror of
https://github.com/corda/corda.git
synced 2025-01-28 15:14:48 +00:00
The first node now becomes the session's Network Map service used by all other nodes. Force nodes to be created one-by-one.
This commit is contained in:
parent
6e38c4a95d
commit
c670ed6bdd
@ -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()
|
||||||
|
}
|
@ -5,47 +5,31 @@ import com.typesafe.config.ConfigFactory
|
|||||||
import com.typesafe.config.ConfigValue
|
import com.typesafe.config.ConfigValue
|
||||||
import com.typesafe.config.ConfigValueFactory
|
import com.typesafe.config.ConfigValueFactory
|
||||||
|
|
||||||
class NodeConfig(legalName: String, nearestCity: String, p2pPort: Int, artemisPort: Int, webPort: Int) {
|
class NodeConfig(legalName: String, artemisPort: Int, nearestCity: String, webPort: Int) : NetworkMapConfig(legalName, artemisPort){
|
||||||
|
|
||||||
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 nearestCityName: String = nearestCity
|
private var nearestCityName: String = nearestCity
|
||||||
val nearestCity : String
|
val nearestCity : String
|
||||||
get() { return nearestCityName }
|
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
|
private var webPortValue: Int = webPort
|
||||||
val webPort : Int
|
val webPort : Int
|
||||||
get() { return webPortValue }
|
get() { return webPortValue }
|
||||||
|
|
||||||
private fun toKey(value: String): String {
|
private var networkMapValue: NetworkMapConfig? = null
|
||||||
return value.replace("\\s++", "").toLowerCase()
|
var networkMap : NetworkMapConfig?
|
||||||
}
|
get() { return networkMapValue }
|
||||||
|
set(value) { networkMapValue = value }
|
||||||
|
|
||||||
val toFileConfig : Config
|
val toFileConfig : Config
|
||||||
get() = ConfigFactory.empty()
|
get() = ConfigFactory.empty()
|
||||||
.withValue("myLegalName", valueFor(legalName))
|
.withValue("myLegalName", valueFor(legalName))
|
||||||
|
.withValue("artemisAddress", addressValueFor(artemisPort))
|
||||||
.withValue("nearestCity", valueFor(nearestCity))
|
.withValue("nearestCity", valueFor(nearestCity))
|
||||||
.withValue("extraAdvertisedServiceIds", valueFor(""))
|
.withValue("extraAdvertisedServiceIds", valueFor(""))
|
||||||
.withFallback(ConfigFactory.empty()
|
.withFallback(optional("networkMapService", networkMap, {
|
||||||
.withValue("address", addressValueFor(p2pPort))
|
c, n -> c.withValue("address", addressValueFor(n.artemisPort))
|
||||||
.withValue("legalName", valueFor("Notary"))
|
.withValue("legalName", valueFor(n.legalName))
|
||||||
.atPath("networkMapService")
|
} ))
|
||||||
)
|
|
||||||
.withValue("artemisAddress", addressValueFor(artemisPort))
|
|
||||||
.withValue("webAddress", addressValueFor(webPort))
|
.withValue("webAddress", addressValueFor(webPort))
|
||||||
.withValue("rpcUsers", valueFor(listOf<String>()))
|
.withValue("rpcUsers", valueFor(listOf<String>()))
|
||||||
.withValue("useTestClock", valueFor(true))
|
.withValue("useTestClock", valueFor(true))
|
||||||
@ -59,3 +43,8 @@ private fun <T> valueFor(any: T): ConfigValue? {
|
|||||||
private fun addressValueFor(port: Int): ConfigValue? {
|
private fun addressValueFor(port: Int): ConfigValue? {
|
||||||
return valueFor("localhost:%d".format(port))
|
return valueFor("localhost:%d".format(port))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun <T> 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)
|
||||||
|
}
|
||||||
|
@ -26,25 +26,44 @@ class NodeController : Controller() {
|
|||||||
private val nodes = ConcurrentHashMap<String, NodeConfig>()
|
private val nodes = ConcurrentHashMap<String, NodeConfig>()
|
||||||
private val port = AtomicInteger(FIRST_PORT)
|
private val port = AtomicInteger(FIRST_PORT)
|
||||||
|
|
||||||
|
private var networkMapConfig: NetworkMapConfig? = null
|
||||||
|
|
||||||
fun validate(nodeData: NodeData): NodeConfig? {
|
fun validate(nodeData: NodeData): NodeConfig? {
|
||||||
val config = NodeConfig(
|
val config = NodeConfig(
|
||||||
nodeData.legalName.value,
|
nodeData.legalName.value,
|
||||||
nodeData.nearestCity.value,
|
|
||||||
nodeData.p2pPort.value,
|
|
||||||
nodeData.artemisPort.value,
|
nodeData.artemisPort.value,
|
||||||
|
nodeData.nearestCity.value,
|
||||||
nodeData.webPort.value
|
nodeData.webPort.value
|
||||||
)
|
)
|
||||||
|
|
||||||
|
log.info("Node key: " + config.key)
|
||||||
|
|
||||||
if (nodes.putIfAbsent(config.key, config) != null) {
|
if (nodes.putIfAbsent(config.key, config) != null) {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// The first node becomes our network map
|
||||||
|
chooseNetworkMap(config)
|
||||||
|
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
val nextPort: Int
|
val nextPort: Int
|
||||||
get() { return port.andIncrement }
|
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 {
|
fun runCorda(pty: R3Pty, config: NodeConfig): Boolean {
|
||||||
val nodeDir = workDir.resolve(config.key).toFile()
|
val nodeDir = workDir.resolve(config.key).toFile()
|
||||||
|
|
||||||
@ -73,5 +92,6 @@ class NodeController : Controller() {
|
|||||||
init {
|
init {
|
||||||
log.info("Working directory: " + workDir)
|
log.info("Working directory: " + workDir)
|
||||||
log.info("Java executable: " + javaPath)
|
log.info("Java executable: " + javaPath)
|
||||||
|
log.info("Corda JAR: " + command[0])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ class NodeData {
|
|||||||
|
|
||||||
var legalName = SimpleStringProperty("")
|
var legalName = SimpleStringProperty("")
|
||||||
val nearestCity = SimpleStringProperty("London")
|
val nearestCity = SimpleStringProperty("London")
|
||||||
var p2pPort = SimpleIntegerProperty(0)
|
|
||||||
val artemisPort = SimpleIntegerProperty(0)
|
val artemisPort = SimpleIntegerProperty(0)
|
||||||
val webPort = SimpleIntegerProperty(0)
|
val webPort = SimpleIntegerProperty(0)
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ class NodeDataModel : ItemViewModel<NodeData>(NodeData()) {
|
|||||||
|
|
||||||
val legalName = bind { item?.legalName }
|
val legalName = bind { item?.legalName }
|
||||||
val nearestCity = bind { item?.nearestCity }
|
val nearestCity = bind { item?.nearestCity }
|
||||||
val p2pPort = bind { item?.p2pPort }
|
|
||||||
val artemisPort = bind { item?.artemisPort }
|
val artemisPort = bind { item?.artemisPort }
|
||||||
val webPort = bind { item?.webPort }
|
val webPort = bind { item?.webPort }
|
||||||
|
|
||||||
|
@ -29,6 +29,9 @@ class DemoBenchView : View("Corda Demo Bench") {
|
|||||||
addNodeButton.setOnAction {
|
addNodeButton.setOnAction {
|
||||||
val nodeTab = createNodeTab()
|
val nodeTab = createNodeTab()
|
||||||
nodeTabPane.selectionModel.select(nodeTab)
|
nodeTabPane.selectionModel.select(nodeTab)
|
||||||
|
|
||||||
|
// Prevent us from creating new nodes until we have created the Network Map
|
||||||
|
addNodeButton.isDisable = true
|
||||||
}
|
}
|
||||||
addNodeButton.fire()
|
addNodeButton.fire()
|
||||||
}
|
}
|
||||||
@ -47,4 +50,7 @@ class DemoBenchView : View("Corda Demo Bench") {
|
|||||||
return nodeTab
|
return nodeTab
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun enableAddNodes() {
|
||||||
|
addNodeButton.isDisable = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ import tornadofx.*
|
|||||||
class NodeTabView : Fragment() {
|
class NodeTabView : Fragment() {
|
||||||
override val root = stackpane {}
|
override val root = stackpane {}
|
||||||
|
|
||||||
|
private val main by inject<DemoBenchView>()
|
||||||
|
|
||||||
private val INTEGER_FORMAT = DecimalFormat()
|
private val INTEGER_FORMAT = DecimalFormat()
|
||||||
private val NOT_NUMBER = Regex("[^\\d]")
|
private val NOT_NUMBER = Regex("[^\\d]")
|
||||||
|
|
||||||
@ -25,8 +27,10 @@ class NodeTabView : Fragment() {
|
|||||||
minWidth = 200.0
|
minWidth = 200.0
|
||||||
maxWidth = 200.0
|
maxWidth = 200.0
|
||||||
validator {
|
validator {
|
||||||
if (it.isNullOrBlank()) {
|
if ((it == null) || it.isBlank()) {
|
||||||
error("Node name is required")
|
error("Node name is required")
|
||||||
|
} else if (controller.exists(it)) {
|
||||||
|
error("Node with this name already exists")
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@ -47,21 +51,6 @@ class NodeTabView : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
field("P2P Port") {
|
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)) {
|
textfield(model.artemisPort, NumberStringConverter(INTEGER_FORMAT)) {
|
||||||
minWidth = 100.0
|
minWidth = 100.0
|
||||||
maxWidth = 100.0
|
maxWidth = 100.0
|
||||||
@ -94,12 +83,12 @@ class NodeTabView : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fieldset("Plugins") {
|
fieldset("Plugins") {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
button("Create Node") {
|
button("Create Node") {
|
||||||
setOnAction() {
|
setOnAction() {
|
||||||
launch()
|
launch()
|
||||||
|
main.enableAddNodes()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -135,7 +124,6 @@ class NodeTabView : Fragment() {
|
|||||||
root.add(nodeConfigView)
|
root.add(nodeConfigView)
|
||||||
root.add(nodeTerminalView)
|
root.add(nodeTerminalView)
|
||||||
|
|
||||||
model.p2pPort.value = controller.nextPort
|
|
||||||
model.artemisPort.value = controller.nextPort
|
model.artemisPort.value = controller.nextPort
|
||||||
model.webPort.value = controller.nextPort
|
model.webPort.value = controller.nextPort
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ class NodeTerminalView : Fragment() {
|
|||||||
|
|
||||||
fun open(config: NodeConfig) {
|
fun open(config: NodeConfig) {
|
||||||
nodeName.text = config.legalName
|
nodeName.text = config.legalName
|
||||||
p2pPort.value = config.p2pPort.toString()
|
p2pPort.value = config.artemisPort.toString()
|
||||||
|
|
||||||
val swingTerminal = SwingNode()
|
val swingTerminal = SwingNode()
|
||||||
swingTerminal.setOnMouseClicked {
|
swingTerminal.setOnMouseClicked {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user