docs: add docs/source/example-code module, tutorial on the Client RPC API

This commit is contained in:
Andras Slemmer 2016-10-04 13:56:31 +01:00
parent 8e471c6768
commit 3b77de67b6
6 changed files with 206 additions and 1 deletions

3
.idea/modules.xml generated
View File

@ -15,6 +15,9 @@
<module fileurl="file://$PROJECT_DIR$/.idea/modules/core/core.iml" filepath="$PROJECT_DIR$/.idea/modules/core/core.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/core/core_main.iml" filepath="$PROJECT_DIR$/.idea/modules/core/core_main.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/core/core_test.iml" filepath="$PROJECT_DIR$/.idea/modules/core/core_test.iml" group="core" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/docs/source/example-code/docs_source_example-code.iml" filepath="$PROJECT_DIR$/.idea/modules/docs/source/example-code/docs_source_example-code.iml" group="docs/source/example-code" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/docs/source/example-code/docs_source_example-code_main.iml" filepath="$PROJECT_DIR$/.idea/modules/docs/source/example-code/docs_source_example-code_main.iml" group="docs/source/example-code" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/docs/source/example-code/docs_source_example-code_test.iml" filepath="$PROJECT_DIR$/.idea/modules/docs/source/example-code/docs_source_example-code_test.iml" group="docs/source/example-code" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/experimental/experimental.iml" filepath="$PROJECT_DIR$/.idea/modules/experimental/experimental.iml" group="experimental" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/experimental/experimental_main.iml" filepath="$PROJECT_DIR$/.idea/modules/experimental/experimental_main.iml" group="experimental" />
<module fileurl="file://$PROJECT_DIR$/.idea/modules/experimental/experimental_test.iml" filepath="$PROJECT_DIR$/.idea/modules/experimental/experimental_test.iml" group="experimental" />

View File

@ -0,0 +1,46 @@
apply plugin: 'kotlin'
apply plugin: 'application'
buildscript {
repositories {
mavenCentral()
}
}
repositories {
mavenLocal()
mavenCentral()
jcenter()
maven {
url 'http://oss.sonatype.org/content/repositories/snapshots'
}
maven {
url 'https://dl.bintray.com/kotlin/exposed'
}
}
dependencies {
compile project(':core')
compile project(':client')
compile "org.graphstream:gs-core:1.3"
compile("org.graphstream:gs-ui:1.3") {
exclude group: "bouncycastle"
}
}
mainClassName = "com.r3corda.docs.ClientRpcTutorialKt"
task getClientRpcTutorial(type: CreateStartScripts) {
dependsOn(classes)
mainClassName = "com.r3corda.docs.ClientRpcTutorialKt"
applicationName = "client-rpc-tutorial"
defaultJvmOpts = []
outputDir = new File(project.buildDir, 'scripts')
classpath = jar.outputs.files + project.configurations.runtime
}
applicationDistribution.into("bin") {
from(getClientRpcTutorial)
fileMode = 0755
}

View File

@ -0,0 +1,73 @@
package com.r3corda.docs
import com.google.common.net.HostAndPort
import com.r3corda.client.CordaRPCClient
import org.graphstream.graph.Edge
import org.graphstream.graph.Node
import org.graphstream.graph.implementations.SingleGraph
import java.nio.file.Paths
import java.util.concurrent.CompletableFuture
/**
* This is example code for the Client RPC API tutorial. The START/END comments are important and used by the documentation!
*/
// START 1
enum class PrintOrVisualise {
Print,
Visualise
}
fun main(args: Array<String>) {
if (args.size < 2) {
throw IllegalArgumentException("Usage: <binary> <node address> [Print|Visualise]")
}
val nodeAddress = HostAndPort.fromString(args[0])
val printOrVisualise = PrintOrVisualise.valueOf(args[1])
val certificatesPath = Paths.get("build/trader-demo/buyer/certificates")
// END 1
// START 2
val client = CordaRPCClient(nodeAddress, certificatesPath)
client.start()
val proxy = client.proxy()
// END 2
// START 3
val (transactions, futureTransactions) = proxy.verifiedTransactions()
// END 3
// START 4
when (printOrVisualise) {
PrintOrVisualise.Print -> {
futureTransactions.startWith(transactions).subscribe { transaction ->
println("NODE ${transaction.id}")
transaction.tx.inputs.forEach { input ->
println("EDGE ${input.txhash} ${transaction.id}")
}
}
CompletableFuture<Unit>().get() // block indefinitely
}
// END 4
// START 5
PrintOrVisualise.Visualise -> {
val graph = SingleGraph("transactions")
transactions.forEach { transaction ->
graph.addNode<Node>("${transaction.id}")
}
transactions.forEach { transaction ->
transaction.tx.inputs.forEach { ref ->
graph.addEdge<Edge>("$ref", "${ref.txhash}", "${transaction.id}")
}
}
futureTransactions.subscribe { transaction ->
graph.addNode<Node>("${transaction.id}")
transaction.tx.inputs.forEach { ref ->
graph.addEdge<Edge>("${ref}", "${ref.txhash}", "${transaction.id}")
}
}
graph.display()
}
}
}
// END 5

View File

@ -47,6 +47,7 @@ Read on to learn:
tutorial-contract
tutorial-contract-clauses
tutorial-test-dsl
tutorial-clientrpc-api
protocol-state-machines
oracles
event-scheduling
@ -74,4 +75,3 @@ Read on to learn:
network-simulator
codestyle
building-the-docs

View File

@ -0,0 +1,82 @@
.. _graphstream: http://graphstream-project.org/
Client RPC API
==============
In this tutorial we will build a simple command line utility that connects to a node and dumps the transaction graph to
the standard output. We will then put some simple visualisation on top.
We start off by connecting to the node itself. For the purposes of the tutorial we will run the Trader demo on some
local port and connect to the Buyer side. We will pass in the address as a command line argument. To connect to the node
we also need to access the certificates of the node, we will access the node's ``certificates`` directory directly.
.. literalinclude:: example-code/src/main/kotlin/com/r3corda/docs/ClientRpcTutorial.kt
:language: kotlin
:start-after: START 1
:end-before: END 1
Now we can connect to the node itself:
.. literalinclude:: example-code/src/main/kotlin/com/r3corda/docs/ClientRpcTutorial.kt
:language: kotlin
:start-after: START 2
:end-before: END 2
``proxy`` now exposes the full RPC interface of the node:
.. literalinclude:: ../../node/src/main/kotlin/com/r3corda/node/services/messaging/CordaRPCOps.kt
:language: kotlin
:start-after: interface CordaRPCOps
:end-before: }
The one we need in order to dump the transaction graph is ``verifiedTransactions``. The type signature tells us that the
RPC will return a list of transactions and an Observable stream. This is a general pattern, we query some data and the
node will return the current snapshot and future updates done to it.
.. literalinclude:: example-code/src/main/kotlin/com/r3corda/docs/ClientRpcTutorial.kt
:language: kotlin
:start-after: START 3
:end-before: END 3
The graph will be defined by nodes and edges between them. Each node represents a transaction and edges represent
output-input relations. For now let's just print ``NODE <txhash>`` for the former and ``EDGE <txhash> <txhash>`` for the
latter.
.. literalinclude:: example-code/src/main/kotlin/com/r3corda/docs/ClientRpcTutorial.kt
:language: kotlin
:start-after: START 4
:end-before: END 4
Now we can start the trader demo as per described in :doc:`running-the-demos`::
# Build the demo
./gradlew installDist
# Start the buyer
./build/install/r3prototyping/bin/trader-demo --role=BUYER
In another terminal we can connect to it with our client::
# Connect to localhost:31337
./docs/source/code/build/install/docs/source/code/bin/client-rpc-tutorial localhost:31337 Print
We should see some ``NODE``-s printed. This is because the buyer self-issues some cash for the demo.
Unless we ran the seller before we shouldn't see any ``EDGE``-s because the cash hasn't been spent yet.
In another terminal we can now start the seller::
# Start sellers in a loop
for i in {0..9} ; do ./build/install/r3prototyping/bin/trader-demo --role=SELLER ; done
We should start seeing new ``NODE``-s and ``EDGE``-s appearing.
Now let's try to visualise the transaction graph. We will use a graph drawing library called graphstream_
.. literalinclude:: example-code/src/main/kotlin/com/r3corda/docs/ClientRpcTutorial.kt
:language: kotlin
:start-after: START 5
:end-before: END 5
If we run the client with ``Visualise`` we should see a simple graph being drawn as new transactions are being created
by the seller runs.
That's it! We saw how to connect to the node and stream data from it.

View File

@ -8,3 +8,4 @@ include 'experimental'
include 'test-utils'
include 'network-simulator'
include 'explorer'
include 'docs/source/example-code'