mirror of
https://github.com/corda/corda.git
synced 2025-02-02 01:08:09 +00:00
parent
502d0df630
commit
ce9b6c1f18
@ -348,6 +348,12 @@ abstract class FlowLogic<out T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pair of the current progress step index (as integer) in steps tree of current [progressTracker], and an observable
|
||||
* of its upcoming changes.
|
||||
*
|
||||
* @return Returns null if this flow has no progress tracker.
|
||||
*/
|
||||
fun trackStepsTreeIndex(): DataFeed<Int, Int>? {
|
||||
// TODO this is not threadsafe, needs an atomic get-step-and-subscribe
|
||||
return progressTracker?.let {
|
||||
@ -355,6 +361,12 @@ abstract class FlowLogic<out T> {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a pair of the current steps tree of current [progressTracker] as pairs of zero-based depth and stringified step
|
||||
* label and observable of upcoming changes to the structure.
|
||||
*
|
||||
* @return Returns null if this flow has no progress tracker.
|
||||
*/
|
||||
fun trackStepsTree(): DataFeed<List<Pair<Int,String>>, List<Pair<Int,String>>>? {
|
||||
// TODO this is not threadsafe, needs an atomic get-step-and-subscribe
|
||||
return progressTracker?.let {
|
||||
|
@ -8,13 +8,17 @@ import rx.Observable
|
||||
|
||||
/**
|
||||
* [FlowHandle] is a serialisable handle for the started flow, parameterised by the type of the flow's return value.
|
||||
*
|
||||
* @property id The started state machine's ID.
|
||||
* @property returnValue A [CordaFuture] of the flow's return value.
|
||||
*/
|
||||
@DoNotImplement
|
||||
interface FlowHandle<A> : AutoCloseable {
|
||||
/**
|
||||
* The started state machine's ID.
|
||||
*/
|
||||
val id: StateMachineRunId
|
||||
|
||||
/**
|
||||
* A [CordaFuture] of the flow's return value.
|
||||
*/
|
||||
val returnValue: CordaFuture<A>
|
||||
|
||||
/**
|
||||
@ -25,15 +29,23 @@ interface FlowHandle<A> : AutoCloseable {
|
||||
|
||||
/**
|
||||
* [FlowProgressHandle] is a serialisable handle for the started flow, parameterised by the type of the flow's return value.
|
||||
*
|
||||
* @property progress The stream of progress tracker events.
|
||||
*/
|
||||
interface FlowProgressHandle<A> : FlowHandle<A> {
|
||||
/**
|
||||
* The stream of progress tracker events.
|
||||
*/
|
||||
val progress: Observable<String>
|
||||
|
||||
/**
|
||||
* [DataFeed] of current step in the steps tree, see [ProgressTracker]
|
||||
*/
|
||||
val stepsTreeIndexFeed: DataFeed<Int, Int>?
|
||||
|
||||
/**
|
||||
* [DataFeed] of current steps tree, see [ProgressTracker]
|
||||
*/
|
||||
val stepsTreeFeed: DataFeed<List<Pair<Int, String>>, List<Pair<Int, String>>>?
|
||||
|
||||
/**
|
||||
* Use this function for flows whose returnValue and progress are not going to be used or tracked, so as to free up
|
||||
* server resources.
|
||||
|
@ -99,6 +99,7 @@ class ProgressTracker(vararg steps: Step) {
|
||||
field = value
|
||||
}
|
||||
|
||||
/** The zero-bases index of the current step in a [allStepsLabels] list */
|
||||
var stepsTreeIndex: Int = -1
|
||||
private set(value) {
|
||||
field = value
|
||||
@ -226,6 +227,10 @@ class ProgressTracker(vararg steps: Step) {
|
||||
*/
|
||||
val allSteps: List<Pair<Int, Step>> get() = _allStepsCache
|
||||
|
||||
/**
|
||||
* A list of all steps label in this ProgressTracker and the children, with the indent level provided starting at zero.
|
||||
* Note that UNSTARTED is never counted, and DONE is only counted at the calling level.
|
||||
*/
|
||||
val allStepsLabels: List<Pair<Int, String>> get() = _allStepsLabels()
|
||||
|
||||
private var curChangeSubscription: Subscription? = null
|
||||
@ -245,8 +250,14 @@ class ProgressTracker(vararg steps: Step) {
|
||||
*/
|
||||
val changes: Observable<Change> get() = _changes
|
||||
|
||||
/**
|
||||
* An observable stream of changes to the [allStepsLabels]
|
||||
*/
|
||||
val stepsTreeChanges: Observable<List<Pair<Int,String>>> get() = _stepsTreeChanges
|
||||
|
||||
/**
|
||||
* An observable stream of changes to the [stepsTreeIndex]
|
||||
*/
|
||||
val stepsTreeIndexChanges: Observable<Int> get() = _stepsTreeIndexChanges
|
||||
|
||||
/** Returns true if the progress tracker has ended, either by reaching the [DONE] step or prematurely with an error */
|
||||
|
@ -98,7 +98,7 @@ class ProgressTrackerTest {
|
||||
|
||||
val allSteps = pt.allSteps
|
||||
|
||||
//capture notifications
|
||||
// Capture notifications.
|
||||
val stepsIndexNotifications = LinkedList<Int>()
|
||||
pt.stepsTreeIndexChanges.subscribe {
|
||||
stepsIndexNotifications += it
|
||||
@ -113,7 +113,7 @@ class ProgressTrackerTest {
|
||||
assertEquals(step, allSteps[pt.stepsTreeIndex].second)
|
||||
}
|
||||
|
||||
//travel tree
|
||||
// Travel tree.
|
||||
pt.currentStep = SimpleSteps.ONE
|
||||
assertCurrentStepsTree(0, SimpleSteps.ONE)
|
||||
|
||||
@ -126,7 +126,7 @@ class ProgressTrackerTest {
|
||||
pt.currentStep = SimpleSteps.THREE
|
||||
assertCurrentStepsTree(5, SimpleSteps.THREE)
|
||||
|
||||
//assert no structure changes and proper steps propagation
|
||||
// Assert no structure changes and proper steps propagation.
|
||||
assertThat(stepsIndexNotifications).containsExactlyElementsOf(listOf(0, 1, 3, 5))
|
||||
assertThat(stepsTreeNotification).isEmpty()
|
||||
}
|
||||
@ -135,13 +135,13 @@ class ProgressTrackerTest {
|
||||
fun `structure changes are pushed down when progress trackers are added`() {
|
||||
pt.setChildProgressTracker(SimpleSteps.TWO, pt2)
|
||||
|
||||
//capture notifications
|
||||
// Capture notifications.
|
||||
val stepsIndexNotifications = LinkedList<Int>()
|
||||
pt.stepsTreeIndexChanges.subscribe {
|
||||
stepsIndexNotifications += it
|
||||
}
|
||||
|
||||
//put current state as a first change for simplicity when asserting
|
||||
// Put current state as a first change for simplicity when asserting.
|
||||
val stepsTreeNotification = mutableListOf(pt.allStepsLabels)
|
||||
println(pt.allStepsLabels)
|
||||
pt.stepsTreeChanges.subscribe {
|
||||
@ -164,7 +164,7 @@ class ProgressTrackerTest {
|
||||
|
||||
assertCurrentStepsTree(9, SimpleSteps.FOUR)
|
||||
|
||||
//assert no structure changes and proper steps propagation
|
||||
// Assert no structure changes and proper steps propagation.
|
||||
assertThat(stepsIndexNotifications).containsExactlyElementsOf(listOf(1, 6, 9))
|
||||
assertThat(stepsTreeNotification).hasSize(2) // 1 change + 1 our initial state
|
||||
}
|
||||
@ -173,13 +173,13 @@ class ProgressTrackerTest {
|
||||
fun `structure changes are pushed down when progress trackers are removed`() {
|
||||
pt.setChildProgressTracker(SimpleSteps.TWO, pt2)
|
||||
|
||||
//capture notifications
|
||||
// Capture notifications.
|
||||
val stepsIndexNotifications = LinkedList<Int>()
|
||||
pt.stepsTreeIndexChanges.subscribe {
|
||||
stepsIndexNotifications += it
|
||||
}
|
||||
|
||||
//put current state as a first change for simplicity when asserting
|
||||
// Put current state as a first change for simplicity when asserting.
|
||||
val stepsTreeNotification = mutableListOf(pt.allStepsLabels)
|
||||
pt.stepsTreeChanges.subscribe {
|
||||
stepsTreeNotification += it
|
||||
@ -199,9 +199,9 @@ class ProgressTrackerTest {
|
||||
|
||||
assertCurrentStepsTree(2, BabySteps.UNOS)
|
||||
|
||||
//assert no structure changes and proper steps propagation
|
||||
// Assert no structure changes and proper steps propagation.
|
||||
assertThat(stepsIndexNotifications).containsExactlyElementsOf(listOf(1, 4, 2))
|
||||
assertThat(stepsTreeNotification).hasSize(2) // 1 change + 1 our initial state
|
||||
assertThat(stepsTreeNotification).hasSize(2) // 1 change + 1 our initial state.
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -35,9 +35,9 @@ Shell can also be accessible via SSH. By default SSH server is *disabled*. To en
|
||||
|
||||
Authentication and authorization
|
||||
--------------------------------
|
||||
SSH require user to login first - using the same users as RPC system. In fact, shell serves as a proxy to RPC and communicates
|
||||
with node using RPC calls. This also means that RPC permissions are enforced. No permissions are required to allow the connection
|
||||
and login in.
|
||||
SSH requires users to login first - using the same users as RPC system. In fact, the shell serves as a proxy to RPC and communicates
|
||||
with the node using RPC calls. This also means that RPC permissions are enforced. No permissions are required to allow the connection
|
||||
and log in.
|
||||
Watching flows (``flow watch``) requires ``InvokeRpc.stateMachinesFeed`` while starting flows requires
|
||||
``InvokeRpc.startTrackedFlowDynamic`` and ``InvokeRpc.registeredFlows`` in addition to a permission for a particular flow.
|
||||
|
||||
@ -51,7 +51,7 @@ errors.
|
||||
Connecting
|
||||
----------
|
||||
|
||||
Linux and MacOS computers usually come with SSH client preinstalled. On Windows it usually require extra download.
|
||||
Linux and MacOS computers usually come with SSH client preinstalled. On Windows it usually requires extra download.
|
||||
Usual connection syntax is ``ssh user@host -p 2222`` - where ``user`` is a RPC username, and ``-p`` specifies a port parameters -
|
||||
it's the same as setup in ``node.conf`` file. ``host`` should point to a node hostname, usually ``localhost`` if connecting and
|
||||
running node on the same computer. Password will be asked after establishing connection.
|
||||
|
@ -139,8 +139,8 @@ class SSHServerTest {
|
||||
|
||||
val response = String(Streams.readAll(channel.inputStream))
|
||||
|
||||
//There are ANSI control characters involved, so we want to avoid direct byte to byte matching
|
||||
assertThat(response.lines()).filteredOn( { it.contains("✓") && it.contains("Done")}).hasSize(1)
|
||||
// There are ANSI control characters involved, so we want to avoid direct byte to byte matching.
|
||||
assertThat(response.lines()).filteredOn( { it.contains("Done")}).hasSize(1)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4,7 +4,7 @@ package net.corda.node.shell;
|
||||
|
||||
import net.corda.core.messaging.CordaRPCOps;
|
||||
import net.corda.node.utilities.ANSIProgressRenderer;
|
||||
import net.corda.node.utilities.CRaSHNSIProgressRenderer;
|
||||
import net.corda.node.utilities.CRaSHANSIProgressRenderer;
|
||||
import org.crsh.cli.*;
|
||||
import org.crsh.command.*;
|
||||
import org.crsh.text.*;
|
||||
@ -12,7 +12,6 @@ import org.crsh.text.ui.TableElement;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static net.corda.node.services.messaging.RPCServerKt.CURRENT_RPC_CONTEXT;
|
||||
import static net.corda.node.shell.InteractiveShell.*;
|
||||
|
||||
@Man(
|
||||
@ -49,7 +48,7 @@ public class FlowShellCommand extends InteractiveShellCommand {
|
||||
return;
|
||||
}
|
||||
String inp = input == null ? "" : String.join(" ", input).trim();
|
||||
runFlowByNameFragment(name, inp, out, rpcOps, ansiProgressRenderer != null ? ansiProgressRenderer : new CRaSHNSIProgressRenderer(out) );
|
||||
runFlowByNameFragment(name, inp, out, rpcOps, ansiProgressRenderer != null ? ansiProgressRenderer : new CRaSHANSIProgressRenderer(out) );
|
||||
}
|
||||
|
||||
@Command
|
||||
|
@ -30,7 +30,7 @@ public class RunShellCommand extends InteractiveShellCommand {
|
||||
return null;
|
||||
}
|
||||
|
||||
return InteractiveShell.runRPCFromString(command, out, context);
|
||||
return InteractiveShell.runRPCFromString(command, out, context, ops());
|
||||
}
|
||||
|
||||
private void emitHelp(InvocationContext<Map> context, StringToMethodCallParser<CordaRPCOps> parser) {
|
||||
|
@ -3,7 +3,7 @@ package net.corda.node.shell;
|
||||
// A simple forwarder to the "flow start" command, for easier typing.
|
||||
|
||||
import net.corda.node.utilities.ANSIProgressRenderer;
|
||||
import net.corda.node.utilities.CRaSHNSIProgressRenderer;
|
||||
import net.corda.node.utilities.CRaSHANSIProgressRenderer;
|
||||
import org.crsh.cli.*;
|
||||
|
||||
import java.util.*;
|
||||
@ -14,6 +14,6 @@ public class StartShellCommand extends InteractiveShellCommand {
|
||||
public void main(@Usage("The class name of the flow to run, or an unambiguous substring") @Argument String name,
|
||||
@Usage("The data to pass as input") @Argument(unquote = false) List<String> input) {
|
||||
ANSIProgressRenderer ansiProgressRenderer = ansiProgressRenderer();
|
||||
FlowShellCommand.startFlow(name, input, out, ops(), ansiProgressRenderer != null ? ansiProgressRenderer : new CRaSHNSIProgressRenderer(out));
|
||||
FlowShellCommand.startFlow(name, input, out, ops(), ansiProgressRenderer != null ? ansiProgressRenderer : new CRaSHANSIProgressRenderer(out));
|
||||
}
|
||||
}
|
||||
|
@ -25,7 +25,7 @@ class CordaAuthenticationPlugin(val rpcOps:CordaRPCOps, val userService:RPCUserS
|
||||
|
||||
if (user != null && user.password == credential) {
|
||||
val actor = Actor(Actor.Id(username), userService.id, nodeLegalName)
|
||||
return CordaSSHAuthInfo(true, RPCOpsWithContext(rpcOps, InvocationContext.rpc(actor), RpcPermissions(user.permissions)))
|
||||
return CordaSSHAuthInfo(true, makeRPCOpsWithContext(rpcOps, InvocationContext.rpc(actor), RpcPermissions(user.permissions)))
|
||||
}
|
||||
|
||||
return AuthInfo.UNSUCCESSFUL;
|
||||
|
@ -101,10 +101,10 @@ object InteractiveShell {
|
||||
this.nodeLegalName = configuration.myLegalName
|
||||
this.database = database
|
||||
val dir = configuration.baseDirectory
|
||||
val runSshDeamon = configuration.sshd != null
|
||||
val runSshDaemon = configuration.sshd != null
|
||||
|
||||
val config = Properties()
|
||||
if (runSshDeamon) {
|
||||
if (runSshDaemon) {
|
||||
val sshKeysDir = dir / "sshkey"
|
||||
sshKeysDir.toFile().mkdirs()
|
||||
|
||||
@ -120,7 +120,7 @@ object InteractiveShell {
|
||||
ExternalResolver.INSTANCE.addCommand("start", "An alias for 'flow start'", StartShellCommand::class.java)
|
||||
shell = ShellLifecycle(dir).start(config)
|
||||
|
||||
if (runSshDeamon) {
|
||||
if (runSshDaemon) {
|
||||
Node.printBasicNodeInfo("SSH server listening on port", configuration.sshd!!.port.toString())
|
||||
}
|
||||
}
|
||||
@ -182,7 +182,7 @@ object InteractiveShell {
|
||||
context.refresh()
|
||||
this.config = config
|
||||
start(context)
|
||||
return context.getPlugin(ShellFactory::class.java).create(null, CordaSSHAuthInfo(false, RPCOpsWithContext(rpcOps, net.corda.core.context.InvocationContext.shell(), RpcPermissions.ALL), StdoutANSIProgressRenderer))
|
||||
return context.getPlugin(ShellFactory::class.java).create(null, CordaSSHAuthInfo(false, makeRPCOpsWithContext(rpcOps, net.corda.core.context.InvocationContext.shell(), RpcPermissions.ALL), StdoutANSIProgressRenderer))
|
||||
}
|
||||
}
|
||||
|
||||
@ -236,7 +236,7 @@ object InteractiveShell {
|
||||
try {
|
||||
// Show the progress tracker on the console until the flow completes or is interrupted with a
|
||||
// Ctrl-C keypress.
|
||||
val stateObservable = runFlowFromString({ clazz,args -> rpcOps.startTrackedFlowDynamic (clazz, *args) }, inputData, clazz)
|
||||
val stateObservable = runFlowFromString({ clazz, args -> rpcOps.startTrackedFlowDynamic(clazz, *args) }, inputData, clazz)
|
||||
|
||||
val latch = CountDownLatch(1)
|
||||
ansiProgressRenderer.render(stateObservable, { latch.countDown() })
|
||||
@ -247,7 +247,6 @@ object InteractiveShell {
|
||||
} catch (e: InterruptedException) {
|
||||
// TODO: When the flow framework allows us to kill flows mid-flight, do so here.
|
||||
}
|
||||
|
||||
} catch (e: NoApplicableConstructor) {
|
||||
output.println("No matching constructor found:", Color.red)
|
||||
e.errors.forEach { output.println("- $it", Color.red) }
|
||||
@ -326,7 +325,9 @@ object InteractiveShell {
|
||||
val (stateMachines, stateMachineUpdates) = proxy.stateMachinesFeed()
|
||||
val currentStateMachines = stateMachines.map { StateMachineUpdate.Added(it) }
|
||||
val subscriber = FlowWatchPrintingSubscriber(out)
|
||||
stateMachineUpdates.startWith(currentStateMachines).subscribe(subscriber)
|
||||
database.transaction {
|
||||
stateMachineUpdates.startWith(currentStateMachines).subscribe(subscriber)
|
||||
}
|
||||
var result: Any? = subscriber.future
|
||||
if (result is Future<*>) {
|
||||
if (!result.isDone) {
|
||||
@ -348,7 +349,7 @@ object InteractiveShell {
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun runRPCFromString(input: List<String>, out: RenderPrintWriter, context: InvocationContext<out Any>): Any? {
|
||||
fun runRPCFromString(input: List<String>, out: RenderPrintWriter, context: InvocationContext<out Any>, cordaRPCOps: CordaRPCOps): Any? {
|
||||
val parser = StringToMethodCallParser(CordaRPCOps::class.java, context.attributes["mapper"] as ObjectMapper)
|
||||
|
||||
val cmd = input.joinToString(" ").trim { it <= ' ' }
|
||||
@ -363,7 +364,7 @@ object InteractiveShell {
|
||||
var result: Any? = null
|
||||
try {
|
||||
InputStreamSerializer.invokeContext = context
|
||||
val call = database.transaction { parser.parse(context.attributes["ops"] as CordaRPCOps, cmd) }
|
||||
val call = database.transaction { parser.parse(cordaRPCOps, cmd) }
|
||||
result = call.call()
|
||||
if (result != null && result !is kotlin.Unit && result !is Void) {
|
||||
result = printAndFollowRPCResponse(result, out)
|
||||
|
@ -1,205 +1,45 @@
|
||||
package net.corda.node.shell
|
||||
|
||||
import net.corda.core.concurrent.CordaFuture
|
||||
import net.corda.core.context.InvocationContext
|
||||
import net.corda.core.contracts.ContractState
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.identity.CordaX500Name
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.messaging.*
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.services.AttachmentId
|
||||
import net.corda.core.node.services.NetworkMapCache
|
||||
import net.corda.core.node.services.Vault
|
||||
import net.corda.core.node.services.vault.*
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.getOrThrow
|
||||
import net.corda.node.services.messaging.CURRENT_RPC_CONTEXT
|
||||
import net.corda.node.services.messaging.RpcAuthContext
|
||||
import net.corda.node.services.messaging.RpcPermissions
|
||||
import java.io.InputStream
|
||||
import java.security.PublicKey
|
||||
import java.time.Instant
|
||||
import java.lang.reflect.InvocationTargetException
|
||||
import java.lang.reflect.Proxy
|
||||
import java.util.concurrent.CompletableFuture
|
||||
import java.util.concurrent.Future
|
||||
|
||||
class RPCOpsWithContext(val cordaRPCOps: CordaRPCOps, val invocationContext:InvocationContext, val rpcPermissions: RpcPermissions) : CordaRPCOps {
|
||||
fun makeRPCOpsWithContext(cordaRPCOps: CordaRPCOps, invocationContext:InvocationContext, rpcPermissions: RpcPermissions) : CordaRPCOps {
|
||||
return Proxy.newProxyInstance(CordaRPCOps::class.java.classLoader, arrayOf(CordaRPCOps::class.java), { proxy, method, args ->
|
||||
RPCContextRunner(invocationContext, rpcPermissions) {
|
||||
try {
|
||||
method.invoke(cordaRPCOps, *(args ?: arrayOf()))
|
||||
} catch (e: InvocationTargetException) {
|
||||
// Unpack exception.
|
||||
throw e.targetException
|
||||
}
|
||||
}.get().getOrThrow()
|
||||
}) as CordaRPCOps
|
||||
}
|
||||
|
||||
|
||||
class RPCContextRunner<T>(val invocationContext:InvocationContext, val permissions:RpcPermissions, val block:() -> T) : Thread() {
|
||||
private var result: CompletableFuture<T> = CompletableFuture()
|
||||
override fun run() {
|
||||
CURRENT_RPC_CONTEXT.set(RpcAuthContext(invocationContext, permissions))
|
||||
try {
|
||||
result.complete(block())
|
||||
} catch (e:Throwable) {
|
||||
result.completeExceptionally(e)
|
||||
}
|
||||
private class RPCContextRunner<T>(val invocationContext:InvocationContext, val rpcPermissions: RpcPermissions, val block:() -> T) : Thread() {
|
||||
private var result: CompletableFuture<T> = CompletableFuture()
|
||||
override fun run() {
|
||||
CURRENT_RPC_CONTEXT.set(RpcAuthContext(invocationContext, rpcPermissions))
|
||||
try {
|
||||
result.complete(block())
|
||||
} catch (e:Throwable) {
|
||||
result.completeExceptionally(e)
|
||||
} finally {
|
||||
CURRENT_RPC_CONTEXT.remove()
|
||||
}
|
||||
|
||||
fun get(): Future<T> {
|
||||
start()
|
||||
join()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
override fun uploadAttachmentWithMetadata(jar: InputStream, uploader: String, filename: String): SecureHash {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.uploadAttachmentWithMetadata(jar, uploader, filename) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun queryAttachments(query: AttachmentQueryCriteria, sorting: AttachmentSort?): List<AttachmentId> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.queryAttachments(query, sorting) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T : ContractState> vaultTrackByWithSorting(contractStateType: Class<out T>, criteria: QueryCriteria, sorting: Sort): DataFeed<Vault.Page<T>, Vault.Update<T>> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.vaultTrackByWithSorting(contractStateType, criteria, sorting) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T : ContractState> vaultTrackByWithPagingSpec(contractStateType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): DataFeed<Vault.Page<T>, Vault.Update<T>> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.vaultTrackByWithPagingSpec(contractStateType, criteria, paging) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T : ContractState> vaultTrackByCriteria(contractStateType: Class<out T>, criteria: QueryCriteria): DataFeed<Vault.Page<T>, Vault.Update<T>> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.vaultTrackByCriteria(contractStateType, criteria) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T : ContractState> vaultTrack(contractStateType: Class<out T>): DataFeed<Vault.Page<T>, Vault.Update<T>> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.vaultTrack(contractStateType) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T : ContractState> vaultQueryByWithSorting(contractStateType: Class<out T>, criteria: QueryCriteria, sorting: Sort): Vault.Page<T> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.vaultQueryByWithSorting(contractStateType, criteria, sorting) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T : ContractState> vaultQueryByWithPagingSpec(contractStateType: Class<out T>, criteria: QueryCriteria, paging: PageSpecification): Vault.Page<T> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.vaultQueryByWithPagingSpec(contractStateType, criteria, paging) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T : ContractState> vaultQueryByCriteria(criteria: QueryCriteria, contractStateType: Class<out T>): Vault.Page<T> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.vaultQueryByCriteria(criteria, contractStateType) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T : ContractState> vaultQuery(contractStateType: Class<out T>): Vault.Page<T> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.vaultQuery(contractStateType) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun stateMachinesSnapshot(): List<StateMachineInfo> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions, cordaRPCOps::stateMachinesSnapshot).get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun stateMachinesFeed(): DataFeed<List<StateMachineInfo>, StateMachineUpdate> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions, cordaRPCOps::stateMachinesFeed).get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T : ContractState> vaultQueryBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort, contractStateType: Class<out T>): Vault.Page<T> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.vaultQueryBy(criteria, paging, sorting, contractStateType) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T : ContractState> vaultTrackBy(criteria: QueryCriteria, paging: PageSpecification, sorting: Sort, contractStateType: Class<out T>): DataFeed<Vault.Page<T>, Vault.Update<T>> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.vaultTrackBy(criteria, paging, sorting, contractStateType) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun internalVerifiedTransactionsSnapshot(): List<SignedTransaction> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.internalVerifiedTransactionsSnapshot() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun internalVerifiedTransactionsFeed(): DataFeed<List<SignedTransaction>, SignedTransaction> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.internalVerifiedTransactionsFeed() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun stateMachineRecordedTransactionMappingSnapshot(): List<StateMachineTransactionMapping> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.stateMachineRecordedTransactionMappingSnapshot() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun stateMachineRecordedTransactionMappingFeed(): DataFeed<List<StateMachineTransactionMapping>, StateMachineTransactionMapping> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.stateMachineRecordedTransactionMappingFeed() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun networkMapSnapshot(): List<NodeInfo> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.networkMapSnapshot() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun networkMapFeed(): DataFeed<List<NodeInfo>, NetworkMapCache.MapChange> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.networkMapFeed() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T> startFlowDynamic(logicType: Class<out FlowLogic<T>>, vararg args: Any?): FlowHandle<T> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.startFlowDynamic(logicType, *args) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun <T> startTrackedFlowDynamic(logicType: Class<out FlowLogic<T>>, vararg args: Any?): FlowProgressHandle<T> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.startTrackedFlowDynamic(logicType, *args) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun nodeInfo(): NodeInfo {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.nodeInfo() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun notaryIdentities(): List<Party> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.notaryIdentities() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun addVaultTransactionNote(txnId: SecureHash, txnNote: String) {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.addVaultTransactionNote(txnId, txnNote) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun getVaultTransactionNotes(txnId: SecureHash): Iterable<String> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.getVaultTransactionNotes(txnId) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun attachmentExists(id: SecureHash): Boolean {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.attachmentExists(id) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun openAttachment(id: SecureHash): InputStream {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.openAttachment(id) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun uploadAttachment(jar: InputStream): SecureHash {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.uploadAttachment(jar) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun currentNodeTime(): Instant {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.currentNodeTime() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun waitUntilNetworkReady(): CordaFuture<Void?> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.waitUntilNetworkReady() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun wellKnownPartyFromAnonymous(party: AbstractParty): Party? {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.wellKnownPartyFromAnonymous(party) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun partyFromKey(key: PublicKey): Party? {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.partyFromKey(key) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun wellKnownPartyFromX500Name(x500Name: CordaX500Name): Party? {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.wellKnownPartyFromX500Name(x500Name) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun notaryPartyFromX500Name(x500Name: CordaX500Name): Party? {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.notaryPartyFromX500Name(x500Name) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun partiesFromName(query: String, exactMatch: Boolean): Set<Party> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.partiesFromName(query, exactMatch) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun registeredFlows(): List<String> {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.registeredFlows() }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun nodeInfoFromParty(party: AbstractParty): NodeInfo? {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.nodeInfoFromParty(party) }.get().getOrThrow()
|
||||
}
|
||||
|
||||
override fun clearNetworkMapCache() {
|
||||
return RPCContextRunner(invocationContext, rpcPermissions) { cordaRPCOps.clearNetworkMapCache() }.get().getOrThrow()
|
||||
fun get(): Future<T> {
|
||||
start()
|
||||
join()
|
||||
return result
|
||||
}
|
||||
}
|
@ -169,7 +169,7 @@ abstract class ANSIProgressRenderer {
|
||||
|
||||
}
|
||||
|
||||
class CRaSHNSIProgressRenderer(val renderPrintWriter:RenderPrintWriter) : ANSIProgressRenderer() {
|
||||
class CRaSHANSIProgressRenderer(val renderPrintWriter:RenderPrintWriter) : ANSIProgressRenderer() {
|
||||
|
||||
override fun printLine(line: String) {
|
||||
renderPrintWriter.println(line)
|
||||
@ -181,7 +181,7 @@ class CRaSHNSIProgressRenderer(val renderPrintWriter:RenderPrintWriter) : ANSIPr
|
||||
}
|
||||
|
||||
override fun setup() {
|
||||
//we assume SSH always use ansi
|
||||
// We assume SSH always use ANSI.
|
||||
usingANSI = true
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user