mirror of
https://github.com/corda/corda.git
synced 2024-12-28 16:58:55 +00:00
Write configuration parameters into node.conf, and then run corda.jar in its own directory.
This commit is contained in:
parent
0b40d732d4
commit
6e38c4a95d
@ -9,6 +9,7 @@ buildscript {
|
|||||||
ext.guava_version = '14.0.1'
|
ext.guava_version = '14.0.1'
|
||||||
ext.slf4j_version = '1.7.22'
|
ext.slf4j_version = '1.7.22'
|
||||||
ext.logback_version = '1.1.3'
|
ext.logback_version = '1.1.3'
|
||||||
|
ext.typesafeconfig_version = '1.3.1'
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@ -50,6 +51,7 @@ dependencies {
|
|||||||
compile "org.slf4j:log4j-over-slf4j:$slf4j_version"
|
compile "org.slf4j:log4j-over-slf4j:$slf4j_version"
|
||||||
compile "org.slf4j:jul-to-slf4j:$slf4j_version"
|
compile "org.slf4j:jul-to-slf4j:$slf4j_version"
|
||||||
compile "ch.qos.logback:logback-classic:$logback_version"
|
compile "ch.qos.logback:logback-classic:$logback_version"
|
||||||
|
compile "com.typesafe:config:$typesafeconfig_version"
|
||||||
compile ":jediterm-terminal-2.5"
|
compile ":jediterm-terminal-2.5"
|
||||||
compile ':pty4j-0.7.2'
|
compile ':pty4j-0.7.2'
|
||||||
|
|
||||||
|
Binary file not shown.
@ -28,9 +28,7 @@ public class R3Pty implements AutoCloseable {
|
|||||||
@Override
|
@Override
|
||||||
public void close() {
|
public void close() {
|
||||||
LOG.info("Closing terminal '{}'", name);
|
LOG.info("Closing terminal '{}'", name);
|
||||||
if (terminal.getTerminalStarter() != null) {
|
terminal.close();
|
||||||
terminal.close();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getName() {
|
public String getName() {
|
||||||
@ -63,7 +61,9 @@ public class R3Pty implements AutoCloseable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Map<String, String> environment = new HashMap<>(envs);
|
Map<String, String> environment = new HashMap<>(envs);
|
||||||
environment.put("TERM", "xterm");
|
if (!UIUtil.isWindows) {
|
||||||
|
environment.put("TERM", "xterm");
|
||||||
|
}
|
||||||
|
|
||||||
TerminalSession session = terminal.createTerminalSession(createTtyConnector(args, environment, workingDir));
|
TerminalSession session = terminal.createTerminalSession(createTtyConnector(args, environment, workingDir));
|
||||||
session.start();
|
session.start();
|
||||||
|
@ -1,14 +1,23 @@
|
|||||||
package net.corda.demobench.model
|
package net.corda.demobench.model
|
||||||
|
|
||||||
class NodeConfig(name: String, p2pPort: Int, artemisPort: Int, webPort: Int) {
|
import com.typesafe.config.Config
|
||||||
|
import com.typesafe.config.ConfigFactory
|
||||||
|
import com.typesafe.config.ConfigValue
|
||||||
|
import com.typesafe.config.ConfigValueFactory
|
||||||
|
|
||||||
private var keyValue: String = toKey(name)
|
class NodeConfig(legalName: String, nearestCity: String, p2pPort: Int, artemisPort: Int, webPort: Int) {
|
||||||
|
|
||||||
|
private var keyValue: String = toKey(legalName)
|
||||||
val key : String
|
val key : String
|
||||||
get() { return keyValue }
|
get() { return keyValue }
|
||||||
|
|
||||||
private var nameValue: String = name
|
private var legalNameValue: String = legalName
|
||||||
val name : String
|
val legalName : String
|
||||||
get() { return nameValue }
|
get() { return legalNameValue }
|
||||||
|
|
||||||
|
private var nearestCityName: String = nearestCity
|
||||||
|
val nearestCity : String
|
||||||
|
get() { return nearestCityName }
|
||||||
|
|
||||||
private var p2pPortValue: Int = p2pPort
|
private var p2pPortValue: Int = p2pPort
|
||||||
val p2pPort : Int
|
val p2pPort : Int
|
||||||
@ -26,4 +35,27 @@ class NodeConfig(name: String, p2pPort: Int, artemisPort: Int, webPort: Int) {
|
|||||||
return value.replace("\\s++", "").toLowerCase()
|
return value.replace("\\s++", "").toLowerCase()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val toFileConfig : Config
|
||||||
|
get() = ConfigFactory.empty()
|
||||||
|
.withValue("myLegalName", valueFor(legalName))
|
||||||
|
.withValue("nearestCity", valueFor(nearestCity))
|
||||||
|
.withValue("extraAdvertisedServiceIds", valueFor(""))
|
||||||
|
.withFallback(ConfigFactory.empty()
|
||||||
|
.withValue("address", addressValueFor(p2pPort))
|
||||||
|
.withValue("legalName", valueFor("Notary"))
|
||||||
|
.atPath("networkMapService")
|
||||||
|
)
|
||||||
|
.withValue("artemisAddress", addressValueFor(artemisPort))
|
||||||
|
.withValue("webAddress", addressValueFor(webPort))
|
||||||
|
.withValue("rpcUsers", valueFor(listOf<String>()))
|
||||||
|
.withValue("useTestClock", valueFor(true))
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> valueFor(any: T): ConfigValue? {
|
||||||
|
return ConfigValueFactory.fromAnyRef(any)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addressValueFor(port: Int): ConfigValue? {
|
||||||
|
return valueFor("localhost:%d".format(port))
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,35 @@
|
|||||||
package net.corda.demobench.model
|
package net.corda.demobench.model
|
||||||
|
|
||||||
import tornadofx.Controller
|
import com.jediterm.terminal.ui.UIUtil
|
||||||
|
import com.typesafe.config.ConfigRenderOptions
|
||||||
|
import java.lang.management.ManagementFactory
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import java.text.SimpleDateFormat
|
||||||
|
import java.util.*
|
||||||
import java.util.concurrent.ConcurrentHashMap
|
import java.util.concurrent.ConcurrentHashMap
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
import net.corda.demobench.pty.R3Pty
|
||||||
|
import tornadofx.Controller
|
||||||
|
|
||||||
class NodeController : Controller() {
|
class NodeController : Controller() {
|
||||||
private val FIRST_PORT = 10000
|
private val FIRST_PORT = 10000
|
||||||
|
|
||||||
|
private val workDir = Paths.get("work", localDir).toAbsolutePath()
|
||||||
|
|
||||||
|
private val javaExe = if (UIUtil.isWindows) "java.exe" else "java"
|
||||||
|
private val javaPath = Paths.get(System.getProperty("java.home"), "bin", javaExe)
|
||||||
|
private val cordaPath = Paths.get("corda", "corda.jar").toAbsolutePath()
|
||||||
|
private val command = arrayOf(javaPath.toString(), "-jar", cordaPath.toString())
|
||||||
|
|
||||||
|
private val renderOptions = ConfigRenderOptions.defaults().setOriginComments(false)
|
||||||
|
|
||||||
private val nodes = ConcurrentHashMap<String, NodeConfig>()
|
private val nodes = ConcurrentHashMap<String, NodeConfig>()
|
||||||
private val port = AtomicInteger(FIRST_PORT)
|
private val port = AtomicInteger(FIRST_PORT)
|
||||||
|
|
||||||
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.p2pPort.value,
|
||||||
nodeData.artemisPort.value,
|
nodeData.artemisPort.value,
|
||||||
nodeData.webPort.value
|
nodeData.webPort.value
|
||||||
@ -28,4 +45,33 @@ class NodeController : Controller() {
|
|||||||
val nextPort: Int
|
val nextPort: Int
|
||||||
get() { return port.andIncrement }
|
get() { return port.andIncrement }
|
||||||
|
|
||||||
|
fun runCorda(pty: R3Pty, config: NodeConfig): Boolean {
|
||||||
|
val nodeDir = workDir.resolve(config.key).toFile()
|
||||||
|
|
||||||
|
if (nodeDir.mkdirs()) {
|
||||||
|
try {
|
||||||
|
// Write this nodes configuration file into its working directory.
|
||||||
|
val confFile = nodeDir.resolve("node.conf")
|
||||||
|
val fileData = config.toFileConfig
|
||||||
|
confFile.writeText(fileData.root().render(renderOptions))
|
||||||
|
|
||||||
|
pty.run(command, System.getenv(), nodeDir.toString())
|
||||||
|
return true
|
||||||
|
} catch (e: Exception) {
|
||||||
|
log.severe("Failed to launch Corda:" + e)
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val localDir: String
|
||||||
|
get() = SimpleDateFormat("yyyyMMddHHmmss")
|
||||||
|
.format(Date(ManagementFactory.getRuntimeMXBean().startTime))
|
||||||
|
|
||||||
|
init {
|
||||||
|
log.info("Working directory: " + workDir)
|
||||||
|
log.info("Java executable: " + javaPath)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,9 +5,10 @@ import javafx.beans.property.SimpleStringProperty
|
|||||||
|
|
||||||
class NodeData {
|
class NodeData {
|
||||||
|
|
||||||
var legalName : SimpleStringProperty = SimpleStringProperty("")
|
var legalName = SimpleStringProperty("")
|
||||||
var p2pPort: SimpleIntegerProperty = SimpleIntegerProperty(0)
|
val nearestCity = SimpleStringProperty("London")
|
||||||
val artemisPort: SimpleIntegerProperty = SimpleIntegerProperty(0)
|
var p2pPort = SimpleIntegerProperty(0)
|
||||||
val webPort: SimpleIntegerProperty = SimpleIntegerProperty(0)
|
val artemisPort = SimpleIntegerProperty(0)
|
||||||
|
val webPort = SimpleIntegerProperty(0)
|
||||||
|
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ import tornadofx.ItemViewModel
|
|||||||
class NodeDataModel : ItemViewModel<NodeData>(NodeData()) {
|
class NodeDataModel : ItemViewModel<NodeData>(NodeData()) {
|
||||||
|
|
||||||
val legalName = bind { item?.legalName }
|
val legalName = bind { item?.legalName }
|
||||||
|
val nearestCity = bind { item?.nearestCity }
|
||||||
val p2pPort = bind { item?.p2pPort }
|
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 }
|
||||||
|
@ -33,6 +33,19 @@ class NodeTabView : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
field("Nearest City") {
|
||||||
|
textfield(model.nearestCity) {
|
||||||
|
minWidth = 200.0
|
||||||
|
maxWidth = 200.0
|
||||||
|
validator {
|
||||||
|
if (it.isNullOrBlank()) {
|
||||||
|
error("Nearest city is required")
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
field("P2P Port") {
|
field("P2P Port") {
|
||||||
textfield(model.p2pPort, NumberStringConverter(INTEGER_FORMAT)) {
|
textfield(model.p2pPort, NumberStringConverter(INTEGER_FORMAT)) {
|
||||||
minWidth = 100.0
|
minWidth = 100.0
|
||||||
@ -99,8 +112,15 @@ class NodeTabView : Fragment() {
|
|||||||
val config = controller.validate(model.item)
|
val config = controller.validate(model.item)
|
||||||
if (config != null) {
|
if (config != null) {
|
||||||
nodeConfigView.isVisible = false
|
nodeConfigView.isVisible = false
|
||||||
nodeTab.text = config.name
|
nodeTab.text = config.legalName
|
||||||
nodeTerminalView.open(config)
|
nodeTerminalView.open(config)
|
||||||
|
|
||||||
|
nodeTab.setOnSelectionChanged {
|
||||||
|
if (nodeTab.isSelected) {
|
||||||
|
// Doesn't work yet
|
||||||
|
nodeTerminalView.refreshTerminal()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ import javafx.scene.layout.Priority
|
|||||||
import javafx.scene.layout.VBox
|
import javafx.scene.layout.VBox
|
||||||
import javax.swing.SwingUtilities
|
import javax.swing.SwingUtilities
|
||||||
import net.corda.demobench.model.NodeConfig
|
import net.corda.demobench.model.NodeConfig
|
||||||
|
import net.corda.demobench.model.NodeController
|
||||||
import net.corda.demobench.pty.R3Pty
|
import net.corda.demobench.pty.R3Pty
|
||||||
import net.corda.demobench.ui.PropertyLabel
|
import net.corda.demobench.ui.PropertyLabel
|
||||||
import tornadofx.Fragment
|
import tornadofx.Fragment
|
||||||
@ -19,6 +20,8 @@ import tornadofx.vgrow
|
|||||||
class NodeTerminalView : Fragment() {
|
class NodeTerminalView : Fragment() {
|
||||||
override val root by fxml<VBox>()
|
override val root by fxml<VBox>()
|
||||||
|
|
||||||
|
private val controller by inject<NodeController>()
|
||||||
|
|
||||||
private val nodeName by fxid<Label>()
|
private val nodeName by fxid<Label>()
|
||||||
private val p2pPort by fxid<PropertyLabel>()
|
private val p2pPort by fxid<PropertyLabel>()
|
||||||
private val states by fxid<PropertyLabel>()
|
private val states by fxid<PropertyLabel>()
|
||||||
@ -31,7 +34,7 @@ class NodeTerminalView : Fragment() {
|
|||||||
var pty : R3Pty? = null
|
var pty : R3Pty? = null
|
||||||
|
|
||||||
fun open(config: NodeConfig) {
|
fun open(config: NodeConfig) {
|
||||||
nodeName.text = config.name
|
nodeName.text = config.legalName
|
||||||
p2pPort.value = config.p2pPort.toString()
|
p2pPort.value = config.p2pPort.toString()
|
||||||
|
|
||||||
val swingTerminal = SwingNode()
|
val swingTerminal = SwingNode()
|
||||||
@ -43,11 +46,11 @@ class NodeTerminalView : Fragment() {
|
|||||||
root.isVisible = true
|
root.isVisible = true
|
||||||
|
|
||||||
SwingUtilities.invokeLater({
|
SwingUtilities.invokeLater({
|
||||||
val r3pty = R3Pty(config.name, TerminalSettingsProvider(), Dimension(160, 80))
|
val r3pty = R3Pty(config.legalName, TerminalSettingsProvider(), Dimension(160, 80))
|
||||||
pty = r3pty
|
pty = r3pty
|
||||||
|
|
||||||
swingTerminal.content = r3pty.terminal
|
swingTerminal.content = r3pty.terminal
|
||||||
r3pty.run("/bin/bash", "--login")
|
controller.runCorda(r3pty, config)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +58,12 @@ class NodeTerminalView : Fragment() {
|
|||||||
pty?.close()
|
pty?.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun refreshTerminal() {
|
||||||
|
SwingUtilities.invokeLater {
|
||||||
|
// TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
init {
|
init {
|
||||||
root.vgrow = Priority.ALWAYS
|
root.vgrow = Priority.ALWAYS
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user