mirror of
https://github.com/corda/corda.git
synced 2025-06-13 04:38:19 +00:00
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:
@ -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`
|
||||
|
Reference in New Issue
Block a user