mirror of
https://github.com/corda/corda.git
synced 2025-01-14 16:59:52 +00:00
Display simple statistics about the node on each tab.
This commit is contained in:
parent
51d02e1e45
commit
cd5dde70e0
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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<String>
|
||||
) : 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<String, String>
|
||||
val user: Map<String, String>
|
||||
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))
|
||||
|
@ -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<JVMConfig>()
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
@ -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<VBox>()
|
||||
@ -31,9 +34,10 @@ class NodeTerminalView : Fragment() {
|
||||
private val viewDatabaseButton by fxid<Button>()
|
||||
private val launchExplorerButton by fxid<Button>()
|
||||
|
||||
val explorer = explorerController.explorer()
|
||||
val viewer = DBViewer()
|
||||
var pty : R3Pty? = null
|
||||
private val explorer = explorerController.explorer()
|
||||
private val viewer = DBViewer()
|
||||
private var rpc: NodeRPC? = null
|
||||
private var pty: R3Pty? = null
|
||||
|
||||
fun open(config: NodeConfig) {
|
||||
nodeName.text = config.legalName
|
||||
@ -65,18 +69,38 @@ class NodeTerminalView : Fragment() {
|
||||
* the explorer has exited.
|
||||
*/
|
||||
launchExplorerButton.setOnAction {
|
||||
launchExplorerButton.isDisable= true
|
||||
launchExplorerButton.isDisable = true
|
||||
|
||||
explorer.open(config, onExit = {
|
||||
launchExplorerButton.isDisable = false
|
||||
})
|
||||
}
|
||||
|
||||
rpc = NodeRPC(config, { ops ->
|
||||
try {
|
||||
val verifiedTx = ops.verifiedTransactions()
|
||||
val statesInVault = ops.vaultAndUpdates()
|
||||
val cashBalances = ops.getCashBalances().entries.joinToString(
|
||||
separator = ", ",
|
||||
transform = { e -> "%s %s".format(e.value, e.key.currencyCode) }
|
||||
)
|
||||
|
||||
Platform.runLater {
|
||||
states.value = statesInVault.first.size.toString()
|
||||
transactions.value = verifiedTx.first.size.toString()
|
||||
balance.value = cashBalances
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
log.warning("RPC failed: " + e)
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
fun close() {
|
||||
explorer.close()
|
||||
viewer.close()
|
||||
rpc?.close()
|
||||
pty?.close()
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user