In this article, we have explained how to make use of a client proxy to make RPCs for a Corda Node. The RPC client can be written in any JVM compatible language using the CordaRPCClient class. Once connected, you can trigger the vault and the flow, and get results.
Begin with adding a variable for the spring boot version and Corda version that should've been installed locally, including spring classpath dependencies.
buildscript {
ext {
corda_release_group = net.corda"
corda_release_version="4.0"
corda_gradle_plugins_version="4.0.42"
kotlin_version="1.2.71"
junit_version="4.12"
quasarVersion="0.7.10"
spring_boot_version = '2.0.2.RELEASE'
spring_boot_gradle_plugin_version = '2.1.1.RELEASE'
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-releases' }
}
dependencies {
classpath org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath net.corda.plugins:cordapp:$corda_gradle_plugins_version"
classpath net.corda.plugins:cordformation:$corda_gradle_plugins_version"
classpath
net.corda.plugins:quasar-utils:$corda_gradle_plugins_version"
classpath org.springframework.boot:spring-boot-gradle-plugin:$spring_boot_gradle_plugin_version"
}
repositories {
jcenter()
mavenCentral()
maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda' }
//Corda testing node-driver requires gradle-tooling-api
maven { url 'https://repo.gradle.org/gradle/libs-releases-local/' }
//Required for Corda SNPASHOTs
maven { url 'https://ci-artifactory.corda.r3cev.com/artifactory/corda-dev' }
maven { url 'https://jitpack.io' }
}
Add corda and spring dependencies in build.gradle file
dependencies {
compile "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
testCompile "org.jetbrains.kotlin:kotlin-test:$kotlin_version"
testCompile "junit:junit:$junit_version"
// Corda dependencies.
cordaCompile $corda_release_group:corda-core:$corda_release_version"
cordaCompile $corda_release_group:corda-jackson:$corda_release_version"
cordaCompile $corda_release_group:corda-rpc:$corda_release_version"
cordaCompile $corda_release_group:corda-node-api:$corda_release_version"
cordaRuntime "$corda_release_group:corda:$corda_release_version"
testCompile "$corda_release_group:corda-node-driver:$corda_release_version"
cordaRuntime "org.apache.logging.log4j:log4j-slf4j-impl:$log4j_version"
compile("org.springframework.boot:spring-boot-starter-websocket:$spring_boot_version") {
exclude group: "org.springframework.boot", module: "spring-boot-starter-logging"
}
compile "org.apache.logging.log4j:log4j-web:$log4j_version"
}
Add a task for deploying your Node
task deployNodes(type: net.corda.plugins.Cordform, dependsOn: ['jar']) {
nodeDefaults {
projectCordapp {
deploy = false
}
}
signing {
enabled false
}
node {
name O=PartyA,L=London,C=GB"
p2pPort 10005
rpcSettings {
address("localhost:10006")
adminAddress("localhost:10046")
}
rpcUsers = [[ username: "user1", "password": "test", "permissions": ["ALL"]]]
}
}Add Task for Server
Add Task for Server
task runPartyAServer (type: JavaExec ,dependsOn: assemble) {
classpath = sourceSets.main.runtimeClasspath
main ='net.corda.server.ServerKt'
}
The Server
Similar to any other Spring Boot app, we define the main entry point with a SpringApplication instance. The @SpringBootApplication annotation should be added to the class consuming the SpringApplication instance, which in this case is Server.
@SpringBootApplication
open class Starter
fun main(args: Array<String>) {
val app = SpringApplication(Starter::class.java)
app.setBannerMode(Banner.Mode.CONSOLE) app.isWebEnvironment = true
app.run(*args)
}
Connecting to the Node
In corda application, to allow the server to interact with the Corda node a long-lasting connection via RPC needs to be established. We can do this by using CordaRPCConnection and CordaRPCClient .
private const val CORDA_USER_NAME = "config.rpc.username"
private const val CORDA_USER_PASSWORD = "config.rpc.password"
private const val CORDA_NODE_HOST = "config.rpc.host"
private const val CORDA_RPC_PORT = "config.rpc.port"
private const val CORDA__RPC_PORT1 = "configNode1.rpc.port"
@Component
open class NodeRPCConnection (
@Value("\${$CORDA_NODE_HOST}">) private val host: String ,
@Value("\${$CORDA_NODE_HOST}">) private val username : String ,
@Value("\${$CORDA_NODE_HOST}">) private val password : String ,
@Value("\${$CORDA_NODE_HOST}">) private val rpcPort : Int ,
@Value("\${$CORDA_NODE_HOST}">) private val host: rpcPort1 : In
) :AutoCloseable{
lateinit var rpcConnection: CordaRPCConnection
private set
lateinit var proxy: CordaRPCOps
private
@PostConstruct
fun initialiseNodeRPCConnectionDelhi()
{
val rpcAddress = NetworkHostAndPort(host, rpcPort)
val rpcClient = CordaRPCClient(rpcAddress)
println("rpcClient=======" + rpcClient)
val rpcConnection = rpcClient.start(username, password)
proxy = rpcConnection.proxy
}
@PreDestroy
override fun close() {
{
rpcConnection.notifyServerAndClose()
}
Spring API
Rest Controller
@RestController
class CustomController(rpc: NodeRPCConnection) {
private val proxy = rpc.proxy
@GetMapping(value = "/me" , produces =
arrayOf(MediaType.APPLICATION_JSON_VALUE))
/**
Returns the node's name where spring Application running.
**/
private fun me() : ResponseEntity<Map<String,Any>> {
return
ResponseHandler.generateResponse(HttpStatus.OK,true,proxy.nodeInfo().legalIdentities.first().name)
}/**
* Returns all parties registered with the [NetworkMapService].
*/
@GetMapping(value = "/peers", produces =
, produces = arrayOf(MediaType.APPLICATION_JSON_VALUE))
private fun peers() :ResponseEntity<Map<String,Any>> {
var partylist = proxy.networkMapSnapshot().flatMap { it.legalIdentities}
var peers : ArrayList = ArrayList()
for (i in partylist)
{
peers.add(i.name)
}
return ResponseHandler.generateResponse(HttpStatus.OK,true,peers)
}
}
Application Properties
spring.jackson.serialization.fail-on-empty-beans=afalse
config.rpc.username = user1
config.rpc.password = test
config.rpc.host=localhost
config.rpc.port= 10006
We hope this post helps you understand how to develop a Corda application with spring boot. However, there is a lot to learn. We have only covered the basics in this post. We have implemented the CordaRPCConnection and CordaRPCClient. We have planned to write more posts on developing Corda while focusing on explaining more complex features. Also, take a look at our Corda blockchain development services for enterprise as well as public solutions.