From 909b4dccad78707acaf8d329c8680e044dc3ab7d Mon Sep 17 00:00:00 2001 From: Jose Coll Date: Fri, 25 Nov 2016 17:56:56 +0000 Subject: [PATCH] Updated RPC Tutorial docs and gradle file. --- docs/source/example-code/build.gradle | 39 +++++++++++++++---- docs/source/tutorial-clientrpc-api.rst | 53 +++++++++++++++++++++++++- 2 files changed, 83 insertions(+), 9 deletions(-) diff --git a/docs/source/example-code/build.gradle b/docs/source/example-code/build.gradle index 919631dfa0..c410316a49 100644 --- a/docs/source/example-code/build.gradle +++ b/docs/source/example-code/build.gradle @@ -1,11 +1,6 @@ apply plugin: 'kotlin' apply plugin: 'application' - -buildscript { - repositories { - mavenCentral() - } -} +apply plugin: 'net.corda.plugins.cordformation' repositories { mavenLocal() @@ -49,9 +44,9 @@ dependencies { compile("org.graphstream:gs-ui:1.3") { exclude group: "bouncycastle" } -} -mainClassName = "net.corda.docs.ClientRpcTutorialKt" + runtime "net.corda:corda:$corda_version" +} task getClientRpcTutorial(type: CreateStartScripts) { dependsOn(classes) @@ -70,4 +65,32 @@ applicationDistribution.into("bin") { task integrationTest(type: Test) { testClassesDir = sourceSets.integrationTest.output.classesDir classpath = sourceSets.integrationTest.runtimeClasspath +} + +task deployNodes(type: net.corda.plugins.Cordform, dependsOn: [':install', 'build']) { + directory "./build/nodes" + networkMap "Notary" + node { + name "Notary" + dirName "notary" + nearestCity "London" + advertisedServices = ["corda.notary.validating"] + artemisPort 10002 + webPort 10003 + cordapps = [] + } + node { + name "Alice" + dirName "alice" + nearestCity "London" + advertisedServices = [] + artemisPort 10004 + webPort 10005 + cordapps = [] + rpcUsers = [ + ['user' : "user", + 'password' : "password", + 'permissions' : ["StartFlow.net.corda.flows.CashFlow"]] + ] + } } \ No newline at end of file diff --git a/docs/source/tutorial-clientrpc-api.rst b/docs/source/tutorial-clientrpc-api.rst index 67ef519769..39acf9e470 100644 --- a/docs/source/tutorial-clientrpc-api.rst +++ b/docs/source/tutorial-clientrpc-api.rst @@ -32,9 +32,13 @@ We start generating transactions in a different thread (``generateTransactions`` :start-after: interface CordaRPCOps :end-before: } +.. warning:: This API is evolving and will continue to grow as new functionality and features added to Corda are made +available to RPC clients. + 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. +node will return the current snapshot and future updates done to it. Observables are described in further detail in +:doc:`clientrpc` .. literalinclude:: example-code/src/main/kotlin/net/corda/docs/ClientRpcTutorial.kt :language: kotlin @@ -69,8 +73,11 @@ Finally we have everything in place: we start a couple of nodes, connect to them .. sourcecode:: bash # Build the example + ./gradlew docs/source/example-code:installDist + # Start it + ./docs/source/example-code/build/install/docs/source/example-code/bin/client-rpc-tutorial Print Now let's try to visualise the transaction graph. We will use a graph drawing library called graphstream_ @@ -97,3 +104,47 @@ See more on plugins in :doc:`creating-a-cordapp`. .. warning:: We will be replacing the use of Kryo in RPC with a stable message format and this will mean that this plugin customisation point will either go away completely or change. + +Security +-------- +RPC credentials associated with a Client must match the permission set configured on the server Node. +This refers to both authentication (username and password) and role-based authorisation (the set of flows an +authenticated user is entitled to run). + +In the instructions above the server node permissions are configured programmatically in the driver code: + +.. code-block:: text + + driver(driverDirectory = baseDirectory) { + val user = User("user", "password", permissions = setOf(startProtocolPermission())) + val node = startNode("Alice", rpcUsers = listOf(user)).get() + +When starting a standalone node using a configuration file we must supply the RPC credentials as follows: + +.. code-block:: text + + rpcUsers : [ + { user=user, password=password, permissions=[ StartFlow.net.corda.flows.CashFlow ] } + ] + +When using the gradle Cordformation plugin to configure and deploy a node you must supply the RPC credentials in a similar manner: + +.. code-block:: text + + rpcUsers = [ + ['user' : "user", + 'password' : "password", + 'permissions' : ["StartFlow.net.corda.flows.CashFlow"]] + ] + +You can then deploy and launch the nodes (Notary and Alice) as follows: + +1. Run ``./gradlew docs/source/example-code:deployNodes`` to create a set of configs and installs under ``docs/source/example-code/build/nodes`` +2. Run ``./docs/source/example-code/build/nodes/runnodes`` (or ``runnodes.bat`` on Windows) to open up two new terminals with the two nodes. + +followed by the same commands as before: +3. ./docs/source/example-code/build/install/docs/source/example-code/bin/client-rpc-tutorial Print +4. ./docs/source/example-code/build/install/docs/source/example-code/bin/client-rpc-tutorial Visualise + +See more on security in :doc:`secure-coding-guidelines`, node configuration in :doc:`corda-configuration-files` and +Cordformation in doc:`creating-a-cordapp`