mirror of
https://github.com/corda/corda.git
synced 2025-02-19 08:57:28 +00:00
Merge pull request #1149 from corda/merges/june-29-10-20
Merges: June 29 at 10:20
This commit is contained in:
commit
9d6a364692
@ -157,6 +157,10 @@ allprojects {
|
|||||||
apply plugin: 'org.owasp.dependencycheck'
|
apply plugin: 'org.owasp.dependencycheck'
|
||||||
apply plugin: 'kotlin-allopen'
|
apply plugin: 'kotlin-allopen'
|
||||||
|
|
||||||
|
// This line works around a serious performance regression in the Kotlin 1.2.50 gradle plugin, it's fixed in 1.2.51
|
||||||
|
// TODO: Remove when we upgrade past Kotlin 1.2.51
|
||||||
|
inspectClassesForKotlinIC.enabled = false
|
||||||
|
|
||||||
allOpen {
|
allOpen {
|
||||||
annotations(
|
annotations(
|
||||||
"javax.persistence.Entity",
|
"javax.persistence.Entity",
|
||||||
|
@ -276,11 +276,13 @@ absolute path to the node's base directory.
|
|||||||
.. note:: This is temporary feature for onboarding network participants that limits their visibility for privacy reasons.
|
.. note:: This is temporary feature for onboarding network participants that limits their visibility for privacy reasons.
|
||||||
|
|
||||||
:tlsCertCrlDistPoint: CRL distribution point (i.e. URL) for the TLS certificate. Default value is NULL, which indicates no CRL availability for the TLS certificate.
|
:tlsCertCrlDistPoint: CRL distribution point (i.e. URL) for the TLS certificate. Default value is NULL, which indicates no CRL availability for the TLS certificate.
|
||||||
Note: If crlCheckSoftFail is FALSE (meaning that there is the strict CRL checking mode) this value needs to be set.
|
|
||||||
|
.. note:: This needs to be set if crlCheckSoftFail is false (i.e. strict CRL checking is on).
|
||||||
|
|
||||||
:tlsCertCrlIssuer: CRL issuer (given in the X500 name format) for the TLS certificate. Default value is NULL,
|
:tlsCertCrlIssuer: CRL issuer (given in the X500 name format) for the TLS certificate. Default value is NULL,
|
||||||
which indicates that the issuer of the TLS certificate is also the issuer of the CRL.
|
which indicates that the issuer of the TLS certificate is also the issuer of the CRL.
|
||||||
Note: If this parameter is set then the tlsCertCrlDistPoint needs to be set as well.
|
|
||||||
|
.. note:: If this parameter is set then `tlsCertCrlDistPoint` needs to be set as well.
|
||||||
|
|
||||||
:flowMonitorPeriodMillis: ``Duration`` of the period suspended flows waiting for IO are logged. Default value is ``60 seconds``.
|
:flowMonitorPeriodMillis: ``Duration`` of the period suspended flows waiting for IO are logged. Default value is ``60 seconds``.
|
||||||
|
|
||||||
@ -369,3 +371,22 @@ This is an example of adding/overriding the keyStore password :
|
|||||||
.. sourcecode:: shell
|
.. sourcecode:: shell
|
||||||
|
|
||||||
java -Dcorda.rpcSettings.ssl.keyStorePassword=mypassword -jar node.jar
|
java -Dcorda.rpcSettings.ssl.keyStorePassword=mypassword -jar node.jar
|
||||||
|
|
||||||
|
CRL Configuration
|
||||||
|
-----------------
|
||||||
|
The Corda Network provides an endpoint serving an empty certificate revocation list for the TLS-level certificates.
|
||||||
|
This is intended for deployments that do not provide a CRL infrastructure but still require a strict CRL mode checking.
|
||||||
|
In such a case use the following URL in `tlsCertCrlDistPoint` option configuration:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
"https://crl.cordaconnect.org/cordatls.crl"
|
||||||
|
|
||||||
|
Together with the above configuration `tlsCertCrlIssuer` option needs to be set to the following value:
|
||||||
|
|
||||||
|
.. sourcecode:: kotlin
|
||||||
|
|
||||||
|
"C=US, L=New York, O=R3 HoldCo LLC, OU=Corda, CN=Corda Root CA"
|
||||||
|
|
||||||
|
This set-up ensures that the TLS-level certificates are embedded with the CRL distribution point referencing the CRL issued by R3.
|
||||||
|
In cases where a proprietary CRL infrastructure is provided those values need to be changed accordingly.
|
||||||
|
@ -22,6 +22,7 @@ import net.corda.demobench.readErrorLines
|
|||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.Path
|
||||||
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
import java.nio.file.StandardCopyOption.REPLACE_EXISTING
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
|
|
||||||
@ -133,7 +134,7 @@ class Explorer internal constructor(private val explorerController: ExplorerCont
|
|||||||
|
|
||||||
class ExplorerController : Controller() {
|
class ExplorerController : Controller() {
|
||||||
private val jvm by inject<JVMConfig>()
|
private val jvm by inject<JVMConfig>()
|
||||||
private val explorerPath = jvm.applicationDir.resolve("explorer").resolve("node-explorer.jar")
|
private val explorerPath: Path = jvm.applicationDir.resolve("explorer").resolve("node-explorer.jar")
|
||||||
|
|
||||||
init {
|
init {
|
||||||
log.info("Explorer JAR: $explorerPath")
|
log.info("Explorer JAR: $explorerPath")
|
||||||
|
@ -31,7 +31,7 @@ class R3Pty(val name: CordaX500Name, settings: SettingsProvider, dimension: Dime
|
|||||||
|
|
||||||
val terminal = JediTermWidget(dimension, settings)
|
val terminal = JediTermWidget(dimension, settings)
|
||||||
|
|
||||||
val isConnected: Boolean get() = terminal.ttyConnector?.isConnected == true
|
val isConnected: Boolean get() = terminal.ttyConnector?.isConnected ?: false
|
||||||
|
|
||||||
override fun close() {
|
override fun close() {
|
||||||
log.info("Closing terminal '{}'", name)
|
log.info("Closing terminal '{}'", name)
|
||||||
@ -75,5 +75,5 @@ class R3Pty(val name: CordaX500Name, settings: SettingsProvider, dimension: Dime
|
|||||||
|
|
||||||
@Suppress("unused")
|
@Suppress("unused")
|
||||||
@Throws(InterruptedException::class)
|
@Throws(InterruptedException::class)
|
||||||
fun waitFor(): Int? = terminal.ttyConnector?.waitFor()
|
fun waitFor(): Int = terminal.ttyConnector?.waitFor() ?: -1
|
||||||
}
|
}
|
||||||
|
@ -22,37 +22,46 @@ import java.util.concurrent.TimeUnit.SECONDS
|
|||||||
class NodeRPC(config: NodeConfigWrapper, start: (NodeConfigWrapper, CordaRPCOps) -> Unit, invoke: (CordaRPCOps) -> Unit) : AutoCloseable {
|
class NodeRPC(config: NodeConfigWrapper, start: (NodeConfigWrapper, CordaRPCOps) -> Unit, invoke: (CordaRPCOps) -> Unit) : AutoCloseable {
|
||||||
private companion object {
|
private companion object {
|
||||||
private val log = contextLogger()
|
private val log = contextLogger()
|
||||||
val oneSecond = SECONDS.toMillis(1)
|
private val oneSecond = SECONDS.toMillis(1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val rpcClient = CordaRPCClient(NetworkHostAndPort("localhost", config.nodeConfig.rpcAddress.port))
|
private val rpcClient = CordaRPCClient(NetworkHostAndPort("localhost", config.nodeConfig.rpcAddress.port))
|
||||||
|
@Volatile
|
||||||
private var rpcConnection: CordaRPCConnection? = null
|
private var rpcConnection: CordaRPCConnection? = null
|
||||||
private val timer = Timer()
|
private val timer = Timer("DemoBench NodeRPC (${config.key})", true)
|
||||||
|
@Volatile
|
||||||
|
private var timerThread: Thread? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
val setupTask = object : TimerTask() {
|
val setupTask = object : TimerTask() {
|
||||||
override fun run() {
|
override fun run() {
|
||||||
try {
|
// Grab the timer's thread so that we know which one to interrupt.
|
||||||
val user = config.nodeConfig.rpcUsers[0]
|
// This looks like the simplest way of getting the thread. (Ugh)
|
||||||
val connection = rpcClient.start(user.username, user.password)
|
timerThread = Thread.currentThread()
|
||||||
rpcConnection = connection
|
|
||||||
val ops = connection.proxy
|
|
||||||
|
|
||||||
// Cancel the "setup" task now that we've created the RPC client.
|
val user = config.nodeConfig.rpcUsers[0]
|
||||||
this.cancel()
|
val ops: CordaRPCOps = try {
|
||||||
|
rpcClient.start(user.username, user.password).let { connection ->
|
||||||
// Run "start-up" task, now that the RPC client is ready.
|
rpcConnection = connection
|
||||||
start(config, ops)
|
connection.proxy
|
||||||
|
}
|
||||||
// Schedule a new task that will refresh the display once per second.
|
|
||||||
timer.schedule(object : TimerTask() {
|
|
||||||
override fun run() {
|
|
||||||
invoke(ops)
|
|
||||||
}
|
|
||||||
}, 0, oneSecond)
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.warn("Node '{}' not ready yet (Error: {})", config.nodeConfig.myLegalName, e.message)
|
log.warn("Node '{}' not ready yet (Error: {})", config.nodeConfig.myLegalName, e.message)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Cancel the "setup" task now that we've created the RPC client.
|
||||||
|
cancel()
|
||||||
|
|
||||||
|
// Run "start-up" task, now that the RPC client is ready.
|
||||||
|
start(config, ops)
|
||||||
|
|
||||||
|
// Schedule a new task that will refresh the display once per second.
|
||||||
|
timer.schedule(object : TimerTask() {
|
||||||
|
override fun run() {
|
||||||
|
invoke(ops)
|
||||||
|
}
|
||||||
|
}, 0, oneSecond)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,9 +72,11 @@ class NodeRPC(config: NodeConfigWrapper, start: (NodeConfigWrapper, CordaRPCOps)
|
|||||||
override fun close() {
|
override fun close() {
|
||||||
timer.cancel()
|
timer.cancel()
|
||||||
try {
|
try {
|
||||||
|
// No need to notify the node because it's also shutting down.
|
||||||
rpcConnection?.forceClose()
|
rpcConnection?.forceClose()
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
log.error("Failed to close RPC connection (Error: {})", e.message)
|
log.error("Failed to close RPC connection (Error: {})", e.message)
|
||||||
}
|
}
|
||||||
|
timerThread?.interrupt()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ class NodeTerminalView : Fragment() {
|
|||||||
override val root by fxml<VBox>()
|
override val root by fxml<VBox>()
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
val pageSpecification = PageSpecification(1, 1)
|
private val pageSpecification = PageSpecification(1, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val nodeController by inject<NodeController>()
|
private val nodeController by inject<NodeController>()
|
||||||
@ -96,7 +96,7 @@ class NodeTerminalView : Fragment() {
|
|||||||
root.children.add(stack)
|
root.children.add(stack)
|
||||||
root.isVisible = true
|
root.isVisible = true
|
||||||
|
|
||||||
SwingUtilities.invokeLater({
|
SwingUtilities.invokeLater {
|
||||||
val r3pty = R3Pty(config.nodeConfig.myLegalName, TerminalSettingsProvider(), Dimension(160, 80), onExit)
|
val r3pty = R3Pty(config.nodeConfig.myLegalName, TerminalSettingsProvider(), Dimension(160, 80), onExit)
|
||||||
pty = r3pty
|
pty = r3pty
|
||||||
|
|
||||||
@ -122,7 +122,7 @@ class NodeTerminalView : Fragment() {
|
|||||||
rpc?.close()
|
rpc?.close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -191,9 +191,9 @@ class NodeTerminalView : Fragment() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun launchRPC(config: NodeConfigWrapper) = NodeRPC(
|
private fun launchRPC(config: NodeConfigWrapper) = NodeRPC(
|
||||||
config = config,
|
config = config,
|
||||||
start = this::initialise,
|
start = ::initialise,
|
||||||
invoke = this::pollCashBalances
|
invoke = ::pollCashBalances
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun initialise(config: NodeConfigWrapper, ops: CordaRPCOps) {
|
private fun initialise(config: NodeConfigWrapper, ops: CordaRPCOps) {
|
||||||
@ -244,8 +244,8 @@ class NodeTerminalView : Fragment() {
|
|||||||
private fun pollCashBalances(ops: CordaRPCOps) {
|
private fun pollCashBalances(ops: CordaRPCOps) {
|
||||||
try {
|
try {
|
||||||
val cashBalances = ops.getCashBalances().entries.joinToString(
|
val cashBalances = ops.getCashBalances().entries.joinToString(
|
||||||
separator = ", ",
|
separator = ", ",
|
||||||
transform = { e -> e.value.toString() }
|
transform = { e -> e.value.toString() }
|
||||||
)
|
)
|
||||||
|
|
||||||
Platform.runLater {
|
Platform.runLater {
|
||||||
@ -262,21 +262,18 @@ class NodeTerminalView : Fragment() {
|
|||||||
header.isDisable = true
|
header.isDisable = true
|
||||||
subscriptions.forEach {
|
subscriptions.forEach {
|
||||||
// Don't allow any exceptions here to halt tab destruction.
|
// Don't allow any exceptions here to halt tab destruction.
|
||||||
try {
|
ignoreExceptions { it.unsubscribe() }
|
||||||
it.unsubscribe()
|
|
||||||
} catch (e: Exception) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
webServer.close()
|
ignoreExceptions { webServer.close() }
|
||||||
explorer.close()
|
ignoreExceptions { explorer.close() }
|
||||||
viewer.close()
|
ignoreExceptions { viewer.close() }
|
||||||
rpc?.close()
|
ignoreExceptions { rpc?.close() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun destroy() {
|
fun destroy() {
|
||||||
if (!isDestroyed) {
|
if (!isDestroyed) {
|
||||||
shutdown()
|
shutdown()
|
||||||
pty?.close()
|
ignoreExceptions { pty?.close() }
|
||||||
isDestroyed = true
|
isDestroyed = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -289,6 +286,10 @@ class NodeTerminalView : Fragment() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun ignoreExceptions(op: () -> Unit) {
|
||||||
|
try { op() } catch (e: Exception) {}
|
||||||
|
}
|
||||||
|
|
||||||
class TerminalSettingsProvider : DefaultSettingsProvider() {
|
class TerminalSettingsProvider : DefaultSettingsProvider() {
|
||||||
override fun getDefaultStyle() = TextStyle(TerminalColor.WHITE, TerminalColor.rgb(50, 50, 50))
|
override fun getDefaultStyle() = TextStyle(TerminalColor.WHITE, TerminalColor.rgb(50, 50, 50))
|
||||||
override fun emulateX11CopyPaste() = true
|
override fun emulateX11CopyPaste() = true
|
||||||
|
Loading…
x
Reference in New Issue
Block a user