mirror of
https://github.com/corda/corda.git
synced 2024-12-19 21:17:58 +00:00
CORDA-3028: Add Node Diagnostics Info RPC Call (#5271)
* CORDA-3028: Add Node Diagnostics Info RPC Call - Initial commit * CORDA-3028: Add Node Diagnostics Info RPC Call - Changes after code review * CORDA-3028: Add Node Diagnostics Info RPC Call - Additional code review update and documentation * CORDA-3028: Add Node Diagnostics Info RPC Call - Additional changes to documentation * CORDA-3028: Add Node Diagnostics Info RPC Call - Another change to documentation * CORDA-3028: Add Node Diagnostics Info RPC Call - More changes to documentation * CORDA-3028: Add Node Diagnostics Info RPC Call - Comment change
This commit is contained in:
parent
6d3a6a3998
commit
933330bc4c
15
core/src/main/kotlin/net/corda/core/cordapp/CordappInfo.kt
Normal file
15
core/src/main/kotlin/net/corda/core/cordapp/CordappInfo.kt
Normal file
@ -0,0 +1,15 @@
|
||||
package net.corda.core.cordapp
|
||||
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
|
||||
@CordaSerializable
|
||||
data class CordappInfo(val type: String,
|
||||
val name: String,
|
||||
val shortName: String,
|
||||
val minimumPlatformVersion: Int,
|
||||
val targetPlatformVersion: Int,
|
||||
val version: String,
|
||||
val vendor: String,
|
||||
val licence: String,
|
||||
val jarHash: SecureHash.SHA256)
|
@ -12,6 +12,7 @@ import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.NetworkParameters
|
||||
import net.corda.core.node.NodeDiagnosticInfo
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.services.AttachmentId
|
||||
import net.corda.core.node.services.NetworkMapCache
|
||||
@ -280,6 +281,11 @@ interface CordaRPCOps : RPCOps {
|
||||
/** Returns Node's NodeInfo, assuming this will not change while the node is running. */
|
||||
fun nodeInfo(): NodeInfo
|
||||
|
||||
/**
|
||||
* Returns Node's NodeDiagnosticInfo, including the version details as well as the information about installed CorDapps.
|
||||
*/
|
||||
fun nodeDiagnosticInfo(): NodeDiagnosticInfo
|
||||
|
||||
/**
|
||||
* Returns network's notary identities, assuming this will not change while the node is running.
|
||||
*
|
||||
|
@ -0,0 +1,11 @@
|
||||
package net.corda.core.node
|
||||
|
||||
import net.corda.core.cordapp.CordappInfo
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
|
||||
@CordaSerializable
|
||||
data class NodeDiagnosticInfo(val version: String,
|
||||
val revision: String,
|
||||
val platformVersion: Int,
|
||||
val vendor: String,
|
||||
val cordapps: List<CordappInfo>)
|
@ -17,8 +17,10 @@ The key RPC operations exposed by the node are:
|
||||
* Start one of the node's registered flows
|
||||
* ``CordaRPCOps.startTrackedFlowDynamic``
|
||||
* As above, but also returns a progress handle for the flow
|
||||
* ``CordaRPCOps.nodeDiagnosticInfo``
|
||||
* Returns diagnostic information about the node, including the version and CorDapp details
|
||||
* ``CordaRPCOps.nodeInfo``
|
||||
* Returns information about the node
|
||||
* Returns the network map entry of the node, including its address and identity details as well as the platform version information
|
||||
* ``CordaRPCOps.currentNodeTime``
|
||||
* Returns the current time according to the node's clock
|
||||
* ``CordaRPCOps.partyFromKey/CordaRPCOps.wellKnownPartyFromX500Name``
|
||||
|
@ -242,3 +242,40 @@ If the above holds, Corda components will benefit from the following:
|
||||
* A timely recovery from deletion or corruption of configuration files (e.g., ``node.conf``, ``node-info`` files, etc.), database drivers, CorDapps binaries and configuration, and certificate directories, provided backups are available to restore from.
|
||||
|
||||
.. warning:: Private keys used to sign transactions should be preserved with the utmost care. The recommendation is to keep at least two separate copies on a storage not connected to the Internet.
|
||||
|
||||
Checking node version and installed CorDapps
|
||||
--------------------------------------------
|
||||
|
||||
A ``nodeDiagnosticInfo`` RPC call can be made to obtain version information about the Corda platform running on the node. The returned ``NodeDiagnosticInfo`` object also includes information about the CorDapps installed on the node.
|
||||
The RPC call is also available as the ``run nodeDiagnosticInfo`` command executable from the Corda shell that can be accessed via the local terminal, SSH, or as the standalone shell.
|
||||
|
||||
Example
|
||||
+++++++
|
||||
|
||||
Here is a sample output displayed by the ``run nodeDiagnosticInfo`` command executed from the Corda shell:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
version: "|corda_version|"
|
||||
revision: "d7e4a0050049be357999f57f69d8bca41a2b8274"
|
||||
platformVersion: 4
|
||||
vendor: "Corda Open Source"
|
||||
cordapps:
|
||||
- type: "Contract CorDapp"
|
||||
name: "corda-finance-contracts-|corda_version|"
|
||||
shortName: "Corda Finance Demo"
|
||||
minimumPlatformVersion: 1
|
||||
targetPlatformVersion: 4
|
||||
version: "1"
|
||||
vendor: "R3"
|
||||
licence: "Open Source (Apache 2)"
|
||||
jarHash: "570EEB9DF4B43680586F3BE663F9C5844518BC2E410EAF9904E8DEE930B7E45C"
|
||||
- type: "Workflow CorDapp"
|
||||
name: "corda-finance-workflows-|corda_version|"
|
||||
shortName: "Corda Finance Demo"
|
||||
minimumPlatformVersion: 1
|
||||
targetPlatformVersion: 4
|
||||
version: "1"
|
||||
vendor: "R3"
|
||||
licence: "Open Source (Apache 2)"
|
||||
jarHash: "6EA4E0B36010F1DD27B5677F3686B4713BA40C316804A4188DCA20F477FDB23F"
|
||||
|
@ -0,0 +1,46 @@
|
||||
package net.corda.node
|
||||
|
||||
import net.corda.core.internal.PLATFORM_VERSION
|
||||
import net.corda.testing.driver.DriverParameters
|
||||
import net.corda.testing.driver.driver
|
||||
import net.corda.testing.node.internal.FINANCE_CONTRACTS_CORDAPP
|
||||
import net.corda.testing.node.internal.FINANCE_WORKFLOWS_CORDAPP
|
||||
import org.junit.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class NodeRPCTests {
|
||||
private val CORDA_VERSION_REGEX = "\\d+(\\.\\d+)?(-\\w+)?".toRegex() // e.g. "5.0-SNAPSHOT"
|
||||
private val CORDA_VENDOR = "Corda Open Source"
|
||||
private val CORDAPPS = listOf(FINANCE_CONTRACTS_CORDAPP, FINANCE_WORKFLOWS_CORDAPP)
|
||||
private val CORDAPP_TYPES = setOf("Contract CorDapp", "Workflow CorDapp")
|
||||
private val CORDAPP_CONTRACTS_NAME_REGEX = "corda-finance-contracts-$CORDA_VERSION_REGEX".toRegex()
|
||||
private val CORDAPP_WORKFLOWS_NAME_REGEX = "corda-finance-workflows-$CORDA_VERSION_REGEX".toRegex()
|
||||
private val CORDAPP_SHORT_NAME = "Corda Finance Demo"
|
||||
private val CORDAPP_VENDOR = "R3"
|
||||
private val CORDAPP_LICENCE = "Open Source (Apache 2)"
|
||||
private val HEXADECIMAL_REGEX = "[0-9a-fA-F]+".toRegex()
|
||||
|
||||
@Test
|
||||
fun `run nodeDiagnosticInfo`() {
|
||||
driver(DriverParameters(notarySpecs = emptyList(), cordappsForAllNodes = CORDAPPS)) {
|
||||
val nodeDiagnosticInfo = startNode().get().rpc.nodeDiagnosticInfo()
|
||||
assertTrue(nodeDiagnosticInfo.version.matches(CORDA_VERSION_REGEX))
|
||||
assertTrue(nodeDiagnosticInfo.revision.matches(HEXADECIMAL_REGEX))
|
||||
assertEquals(PLATFORM_VERSION, nodeDiagnosticInfo.platformVersion)
|
||||
assertEquals(CORDA_VENDOR, nodeDiagnosticInfo.vendor)
|
||||
assertEquals(CORDAPPS.size, nodeDiagnosticInfo.cordapps.size)
|
||||
assertEquals(CORDAPP_TYPES, nodeDiagnosticInfo.cordapps.map { it.type }.toSet())
|
||||
assertTrue(nodeDiagnosticInfo.cordapps.any { it.name.matches(CORDAPP_CONTRACTS_NAME_REGEX) })
|
||||
assertTrue(nodeDiagnosticInfo.cordapps.any { it.name.matches(CORDAPP_WORKFLOWS_NAME_REGEX) })
|
||||
val cordappInfo = nodeDiagnosticInfo.cordapps.first()
|
||||
assertEquals(CORDAPP_SHORT_NAME, cordappInfo.shortName)
|
||||
assertTrue(cordappInfo.version.all { it.isDigit() })
|
||||
assertEquals(CORDAPP_VENDOR, cordappInfo.vendor)
|
||||
assertEquals(CORDAPP_LICENCE, cordappInfo.licence)
|
||||
assertTrue(cordappInfo.minimumPlatformVersion <= PLATFORM_VERSION)
|
||||
assertTrue(cordappInfo.targetPlatformVersion <= PLATFORM_VERSION)
|
||||
assertTrue(cordappInfo.jarHash.toString().matches(HEXADECIMAL_REGEX))
|
||||
}
|
||||
}
|
||||
}
|
@ -1,11 +1,14 @@
|
||||
package net.corda.node.internal
|
||||
|
||||
import net.corda.client.rpc.notUsed
|
||||
import net.corda.common.logging.CordaVersion
|
||||
import net.corda.core.CordaRuntimeException
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.context.InvocationContext
|
||||
import net.corda.core.context.InvocationOrigin
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.cordapp.Cordapp
|
||||
import net.corda.core.cordapp.CordappInfo
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.flows.FlowInitiator
|
||||
import net.corda.core.flows.FlowLogic
|
||||
@ -21,6 +24,7 @@ import net.corda.core.internal.messaging.InternalCordaRPCOps
|
||||
import net.corda.core.internal.sign
|
||||
import net.corda.core.messaging.*
|
||||
import net.corda.core.node.NetworkParameters
|
||||
import net.corda.core.node.NodeDiagnosticInfo
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.services.AttachmentId
|
||||
import net.corda.core.node.services.NetworkMapCache
|
||||
@ -165,6 +169,32 @@ internal class CordaRPCOpsImpl(
|
||||
return services.myInfo
|
||||
}
|
||||
|
||||
override fun nodeDiagnosticInfo(): NodeDiagnosticInfo {
|
||||
return NodeDiagnosticInfo(
|
||||
version = CordaVersion.releaseVersion,
|
||||
revision = CordaVersion.revision,
|
||||
platformVersion = CordaVersion.platformVersion,
|
||||
vendor = CordaVersion.vendor,
|
||||
cordapps = services.cordappProvider.cordapps
|
||||
.filter { !it.jarPath.toString().endsWith("corda-core-${CordaVersion.releaseVersion}.jar") }
|
||||
.map { CordappInfo(
|
||||
type = when (it.info) {
|
||||
is Cordapp.Info.Contract -> "Contract CorDapp"
|
||||
is Cordapp.Info.Workflow -> "Workflow CorDapp"
|
||||
else -> "CorDapp"
|
||||
},
|
||||
name = it.name,
|
||||
shortName = it.info.shortName,
|
||||
minimumPlatformVersion = it.minimumPlatformVersion,
|
||||
targetPlatformVersion = it.targetPlatformVersion,
|
||||
version = it.info.version,
|
||||
vendor = it.info.vendor,
|
||||
licence = it.info.licence,
|
||||
jarHash = it.jarHash)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
override fun notaryIdentities(): List<Party> {
|
||||
return services.networkMapCache.notaryIdentities
|
||||
}
|
||||
@ -373,4 +403,4 @@ internal class CordaRPCOpsImpl(
|
||||
private inline fun <reified TARGET> Class<*>.checkIsA() {
|
||||
require(TARGET::class.java.isAssignableFrom(this)) { "$name is not a ${TARGET::class.java.name}" }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user