From cd5dde70e0e04bdfdfea0e4676cf51059acbb59c Mon Sep 17 00:00:00 2001 From: Chris Rankin Date: Thu, 2 Feb 2017 12:03:12 +0000 Subject: [PATCH] Display simple statistics about the node on each tab. --- tools/demobench/build.gradle | 13 +++++ .../net/corda/demobench/model/Explorer.kt | 5 +- .../net/corda/demobench/model/NodeConfig.kt | 13 ++++- .../corda/demobench/model/NodeController.kt | 8 ++-- .../kotlin/net/corda/demobench/rpc/NodeRPC.kt | 48 +++++++++++++++++++ .../corda/demobench/views/NodeTerminalView.kt | 32 +++++++++++-- 6 files changed, 110 insertions(+), 9 deletions(-) create mode 100644 tools/demobench/src/main/kotlin/net/corda/demobench/rpc/NodeRPC.kt diff --git a/tools/demobench/build.gradle b/tools/demobench/build.gradle index ba3deace9b..cf6a8e56c4 100644 --- a/tools/demobench/build.gradle +++ b/tools/demobench/build.gradle @@ -33,9 +33,13 @@ repositories { mavenLocal() mavenCentral() + jcenter() maven { url 'http://www.sparetimelabs.com/maven2' } + maven { + url 'https://dl.bintray.com/kotlin/exposed' + } } dependencies { @@ -43,12 +47,16 @@ dependencies { compile "no.tornado:tornadofx:$tornadofx_version" compile "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" + // ONLY USING THE RPC CLIENT!? + compile project(':node') + compile "com.h2database:h2:$h2_version" compile "net.java.dev.jna:jna:$jna_version" compile "net.java.dev.jna:jna-platform:$jna_version" compile "com.google.guava:guava:$guava_version" compile "com.sparetimelabs:purejavacomm:$purejavacomm_version" compile "org.slf4j:log4j-over-slf4j:$slf4j_version" + compile "org.slf4j:jcl-over-slf4j:$slf4j_version" compile "org.slf4j:jul-to-slf4j:$slf4j_version" compile "ch.qos.logback:logback-classic:$logback_version" compile "com.typesafe:config:$typesafe_config_version" @@ -58,6 +66,11 @@ dependencies { testCompile group: 'junit', name: 'junit', version: "$junit_version" } +// We don't want the Node to drag these transitive dependencies in either! +configurations.compile.exclude module: 'commons-logging' +configurations.compile.exclude module: 'log4j-slf4j-impl' +configurations.compile.exclude module: 'log4j-core' + jar { manifest { attributes 'Main-Class': mainClassName diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/model/Explorer.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/model/Explorer.kt index 0522a8d778..82f794fe2c 100644 --- a/tools/demobench/src/main/kotlin/net/corda/demobench/model/Explorer.kt +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/model/Explorer.kt @@ -15,7 +15,10 @@ class Explorer(val explorerController: ExplorerController) : AutoCloseable { "--host=localhost", "--port=%d".format(config.artemisPort), "--username=%s".format(config.user["user"]), - "--password=%s".format(config.user["password"]) + "--password=%s".format(config.user["password"]), + "--certificatesDir=%s".format(config.ssl.certificatesDirectory), + "--keyStorePassword=%s".format(config.ssl.keyStorePassword), + "--trustStorePassword=%s".format(config.ssl.trustStorePassword) ) process = p 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 5ed71ce13b..478551a430 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 @@ -4,9 +4,12 @@ import com.typesafe.config.Config import com.typesafe.config.ConfigFactory import com.typesafe.config.ConfigValue import com.typesafe.config.ConfigValueFactory +import net.corda.node.services.config.SSLConfiguration import java.lang.String.join +import java.nio.file.Path class NodeConfig( + baseDir: Path, legalName: String, artemisPort: Int, val nearestCity: String, @@ -15,15 +18,23 @@ class NodeConfig( val extraServices: List ) : NetworkMapConfig(legalName, artemisPort) { + val nodeDir: Path = baseDir.resolve(key) + private var networkMapValue: NetworkMapConfig? = null var networkMap : NetworkMapConfig? - get() { return networkMapValue } + get() = networkMapValue set(value) { networkMapValue = value } private val userMap: Map val user: Map get() = userMap + val ssl: SSLConfiguration = object : SSLConfiguration { + override val certificatesDirectory: Path = nodeDir.resolve("certificates") + override val trustStorePassword: String = "trustpass" + override val keyStorePassword: String = "cordacadevpass" + } + val toFileConfig : Config get() = ConfigFactory.empty() .withValue("myLegalName", valueFor(legalName)) 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 ebf92cb377..cd7c14a876 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 @@ -13,7 +13,7 @@ import tornadofx.Controller class NodeController : Controller() { private val FIRST_PORT = 10000 - private val workDir = Paths.get("work", localDir).toAbsolutePath() + private val baseDir = Paths.get("work", localDir).toAbsolutePath() private val jvm by inject() private val cordaPath = Paths.get("corda", "corda.jar").toAbsolutePath() @@ -28,6 +28,7 @@ class NodeController : Controller() { fun validate(nodeData: NodeData): NodeConfig? { val config = NodeConfig( + baseDir, nodeData.legalName.value.trim(), nodeData.artemisPort.value, nodeData.nearestCity.value.trim(), @@ -37,6 +38,7 @@ class NodeController : Controller() { ) if (nodes.putIfAbsent(config.key, config) != null) { + log.warning("Node with key '" + config.key + "' already exists.") return null } @@ -67,7 +69,7 @@ class NodeController : Controller() { } fun runCorda(pty: R3Pty, config: NodeConfig): Boolean { - val nodeDir = workDir.resolve(config.key).toFile() + val nodeDir = config.nodeDir.toFile() if (nodeDir.mkdirs()) { try { @@ -93,7 +95,7 @@ class NodeController : Controller() { .format(Date(ManagementFactory.getRuntimeMXBean().startTime)) init { - log.info("Working directory: " + workDir) + log.info("Base directory: " + baseDir) log.info("Corda JAR: " + cordaPath) } } diff --git a/tools/demobench/src/main/kotlin/net/corda/demobench/rpc/NodeRPC.kt b/tools/demobench/src/main/kotlin/net/corda/demobench/rpc/NodeRPC.kt new file mode 100644 index 0000000000..39a69b588f --- /dev/null +++ b/tools/demobench/src/main/kotlin/net/corda/demobench/rpc/NodeRPC.kt @@ -0,0 +1,48 @@ +package net.corda.demobench.rpc + +import com.google.common.net.HostAndPort +import java.util.* +import java.util.concurrent.TimeUnit.SECONDS +import net.corda.core.messaging.CordaRPCOps +import net.corda.demobench.model.NodeConfig +import net.corda.node.services.messaging.CordaRPCClient +import org.slf4j.LoggerFactory + +class NodeRPC(config: NodeConfig, invoke: (ops: CordaRPCOps) -> Unit): AutoCloseable { + private val log = LoggerFactory.getLogger(NodeRPC::class.java) + private val ONE_SECOND = SECONDS.toMillis(1) + + private val rpcClient = CordaRPCClient(HostAndPort.fromParts("localhost", config.artemisPort), config.ssl) + private val timer = Timer() + + override fun close() { + timer.cancel() + rpcClient.close() + } + + init { + val setupTask = object : TimerTask() { + override fun run() { + try { + rpcClient.start(config.user.getOrElse("user") { "none" }, config.user.getOrElse("password") { "none" }) + val ops = rpcClient.proxy() + + // Cancel the "setup" task now that we've created the RPC client. + this.cancel() + + // Schedule a new task that will refresh the display once per second. + timer.schedule(object: TimerTask() { + override fun run() { + invoke(ops) + } + }, 0, ONE_SECOND) + } catch (e: Exception) { + log.warn("Node '{}' not ready yet (Error: {})", config.legalName, e.message) + } + } + } + + // Wait 5 seconds for the node to start, and then poll once per second. + timer.schedule(setupTask, 5 * ONE_SECOND, ONE_SECOND) + } +} 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 ddcb24b359..8f36035102 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 @@ -4,6 +4,7 @@ import com.jediterm.terminal.TerminalColor import com.jediterm.terminal.TextStyle import com.jediterm.terminal.ui.settings.DefaultSettingsProvider import java.awt.Dimension +import javafx.application.Platform import javafx.embed.swing.SwingNode import javafx.scene.control.Button import javafx.scene.control.Label @@ -12,9 +13,11 @@ import javafx.scene.layout.VBox import javax.swing.SwingUtilities import net.corda.demobench.model.* import net.corda.demobench.pty.R3Pty +import net.corda.demobench.rpc.NodeRPC import net.corda.demobench.ui.PropertyLabel import tornadofx.Fragment import tornadofx.vgrow +import java.util.* class NodeTerminalView : Fragment() { override val root by fxml() @@ -31,9 +34,10 @@ class NodeTerminalView : Fragment() { private val viewDatabaseButton by fxid