Introducing StartableByRPC and SchedulableFlow annotations, needed by flows started via RPC and schedulable flows respectively.

CordaPluginRegistry.requiredFlows is no longer needed as a result.
This commit is contained in:
Shams Asari
2017-05-10 11:28:25 +01:00
parent b155764023
commit 48f58b6dbc
52 changed files with 401 additions and 434 deletions

View File

@ -3,13 +3,13 @@
Client RPC API tutorial
=======================
In this tutorial we will build a simple command line utility that
connects to a node, creates some Cash transactions and meanwhile dumps
the transaction graph to the standard output. We will then put some
simple visualisation on top. For an explanation on how the RPC works
see :doc:`clientrpc`.
In this tutorial we will build a simple command line utility that connects to a node, creates some Cash transactions and
meanwhile dumps the transaction graph to the standard output. We will then put some simple visualisation on top. For an
explanation on how the RPC works see :doc:`clientrpc`.
We start off by connecting to the node itself. For the purposes of the tutorial we will use the Driver to start up a notary and a node that issues/exits and moves Cash around for herself. To authenticate we will use the certificates of the nodes directly.
We start off by connecting to the node itself. For the purposes of the tutorial we will use the Driver to start up a notary
and a node that issues/exits and moves Cash around for herself. To authenticate we will use the certificates of the nodes
directly.
Note how we configure the node to create a user that has permission to start the CashFlow.
@ -25,14 +25,16 @@ Now we can connect to the node itself using a valid RPC login. We login using th
:start-after: START 2
:end-before: END 2
We start generating transactions in a different thread (``generateTransactions`` to be defined later) using ``proxy``, which exposes the full RPC interface of the node:
We start generating transactions in a different thread (``generateTransactions`` to be defined later) using ``proxy``,
which exposes the full RPC interface of the node:
.. literalinclude:: ../../core/src/main/kotlin/net/corda/core/messaging/CordaRPCOps.kt
:language: kotlin
: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.
.. 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
@ -61,13 +63,19 @@ Now we just need to create the transactions themselves!
:start-after: START 6
:end-before: END 6
We utilise several RPC functions here to query things like the notaries in the node cluster or our own vault. These RPC functions also return ``Observable`` objects so that the node can send us updated values. However, we don't need updates here and so we mark these observables as ``notUsed``. (As a rule, you should always either subscribe to an ``Observable`` or mark it as not used. Failing to do this will leak resources in the node.)
We utilise several RPC functions here to query things like the notaries in the node cluster or our own vault. These RPC
functions also return ``Observable`` objects so that the node can send us updated values. However, we don't need updates
here and so we mark these observables as ``notUsed``. (As a rule, you should always either subscribe to an ``Observable``
or mark it as not used. Failing to do this will leak resources in the node.)
Then in a loop we generate randomly either an Issue, a Pay or an Exit transaction.
The RPC we need to initiate a Cash transaction is ``startFlowDynamic`` which may start an arbitrary flow, given sufficient permissions to do so. We won't use this function directly, but rather a type-safe wrapper around it ``startFlow`` that type-checks the arguments for us.
The RPC we need to initiate a Cash transaction is ``startFlowDynamic`` which may start an arbitrary flow, given sufficient
permissions to do so. We won't use this function directly, but rather a type-safe wrapper around it ``startFlow`` that
type-checks the arguments for us.
Finally we have everything in place: we start a couple of nodes, connect to them, and start creating transactions while listening on successfully created ones, which are dumped to the console. We just need to run it!:
Finally we have everything in place: we start a couple of nodes, connect to them, and start creating transactions while
listening on successfully created ones, which are dumped to the console. We just need to run it!:
.. code-block:: text
@ -106,9 +114,10 @@ RPC credentials associated with a Client must match the permission set configure
This refers to both authentication (username and password) and role-based authorisation (a permissioned set of RPC operations an
authenticated user is entitled to run).
.. note:: Permissions are represented as *String's* to allow RPC implementations to add their own permissioning.
Currently the only permission type defined is *StartFlow*, which defines a list of whitelisted flows an authenticated use may execute.
An administrator user (or a developer) may also be assigned the ``ALL`` permission, which grants access to any flow.
.. note:: Permissions are represented as *String's* to allow RPC implementations to add their own permissioning. Currently
the only permission type defined is *StartFlow*, which defines a list of whitelisted flows an authenticated use may
execute. An administrator user (or a developer) may also be assigned the ``ALL`` permission, which grants access to
any flow.
In the instructions above the server node permissions are configured programmatically in the driver code:
@ -126,7 +135,8 @@ When starting a standalone node using a configuration file we must supply the RP
{ username=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:
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
@ -148,5 +158,8 @@ You can then deploy and launch the nodes (Notary and Alice) as follows:
./docs/source/example-code/build/install/docs/source/example-code/bin/client-rpc-tutorial Print
./docs/source/example-code/build/install/docs/source/example-code/bin/client-rpc-tutorial Visualise
With regards to the start flow RPCs, there is an extra layer of security whereby the flow to be executed has to be
annotated with ``@StartableByRPC``. Flows without this annotation cannot execute using RPC.
See more on security in :doc:`secure-coding-guidelines`, node configuration in :doc:`corda-configuration-file` and
Cordformation in :doc:`creating-a-cordapp`