mirror of
https://github.com/corda/corda.git
synced 2024-12-23 14:52:29 +00:00
Merge pull request #29 from corda/mnesbit-cordapp-types-in-startFlowDynamic
Allow cordapp types to be used in parameters to startFlowDynamic
This commit is contained in:
commit
d353825e71
@ -219,7 +219,7 @@ class CordaRPCClientImpl(private val session: ClientSession,
|
|||||||
val msg: ClientMessage = createMessage(method)
|
val msg: ClientMessage = createMessage(method)
|
||||||
val kryo = if (returnsObservables) maybePrepareForObservables(location, method, msg) else null
|
val kryo = if (returnsObservables) maybePrepareForObservables(location, method, msg) else null
|
||||||
val serializedArgs = try {
|
val serializedArgs = try {
|
||||||
(args ?: emptyArray<Any?>()).serialize()
|
(args ?: emptyArray<Any?>()).serialize(createRPCKryo())
|
||||||
} catch (e: KryoException) {
|
} catch (e: KryoException) {
|
||||||
throw RPCException("Could not serialize RPC arguments", e)
|
throw RPCException("Could not serialize RPC arguments", e)
|
||||||
}
|
}
|
||||||
|
@ -76,6 +76,14 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
|
|||||||
companion object {
|
companion object {
|
||||||
val PRIVATE_KEY_FILE_NAME = "identity-private-key"
|
val PRIVATE_KEY_FILE_NAME = "identity-private-key"
|
||||||
val PUBLIC_IDENTITY_FILE_NAME = "identity-public"
|
val PUBLIC_IDENTITY_FILE_NAME = "identity-public"
|
||||||
|
|
||||||
|
val defaultFlowWhiteList: Map<Class<out FlowLogic<*>>, Set<Class<*>>> = mapOf(
|
||||||
|
CashFlow::class.java to setOf(
|
||||||
|
CashCommand.IssueCash::class.java,
|
||||||
|
CashCommand.PayCash::class.java,
|
||||||
|
CashCommand.ExitCash::class.java
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Persist this, as well as whether the node is registered.
|
// TODO: Persist this, as well as whether the node is registered.
|
||||||
@ -309,14 +317,6 @@ abstract class AbstractNode(open val configuration: NodeConfiguration, val netwo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val defaultFlowWhiteList: Map<Class<out FlowLogic<*>>, Set<Class<*>>> = mapOf(
|
|
||||||
CashFlow::class.java to setOf(
|
|
||||||
CashCommand.IssueCash::class.java,
|
|
||||||
CashCommand.PayCash::class.java,
|
|
||||||
CashCommand.ExitCash::class.java
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun initialiseFlowLogicFactory(): FlowLogicRefFactory {
|
private fun initialiseFlowLogicFactory(): FlowLogicRefFactory {
|
||||||
val flowWhitelist = HashMap<String, Set<String>>()
|
val flowWhitelist = HashMap<String, Set<String>>()
|
||||||
|
|
||||||
|
@ -70,13 +70,14 @@ abstract class RPCDispatcher(val ops: RPCOps, val userService: RPCUserService) {
|
|||||||
|
|
||||||
fun dispatch(msg: ClientRPCRequestMessage) {
|
fun dispatch(msg: ClientRPCRequestMessage) {
|
||||||
val (argsBytes, replyTo, observationsTo, methodName) = msg
|
val (argsBytes, replyTo, observationsTo, methodName) = msg
|
||||||
|
val kryo = createRPCKryo(observableSerializer = if (observationsTo != null) ObservableSerializer(observationsTo) else null)
|
||||||
|
|
||||||
val response: ErrorOr<Any> = ErrorOr.catch {
|
val response: ErrorOr<Any> = ErrorOr.catch {
|
||||||
val method = methodTable[methodName] ?: throw RPCException("Received RPC for unknown method $methodName - possible client/server version skew?")
|
val method = methodTable[methodName] ?: throw RPCException("Received RPC for unknown method $methodName - possible client/server version skew?")
|
||||||
if (method.isAnnotationPresent(RPCReturnsObservables::class.java) && observationsTo == null)
|
if (method.isAnnotationPresent(RPCReturnsObservables::class.java) && observationsTo == null)
|
||||||
throw RPCException("Received RPC without any destination for observations, but the RPC returns observables")
|
throw RPCException("Received RPC without any destination for observations, but the RPC returns observables")
|
||||||
|
|
||||||
val args = argsBytes.deserialize()
|
val args = argsBytes.deserialize(kryo)
|
||||||
|
|
||||||
rpcLog.debug { "-> RPC -> $methodName(${args.joinToString()}) [reply to $replyTo]" }
|
rpcLog.debug { "-> RPC -> $methodName(${args.joinToString()}) [reply to $replyTo]" }
|
||||||
|
|
||||||
@ -88,7 +89,6 @@ abstract class RPCDispatcher(val ops: RPCOps, val userService: RPCUserService) {
|
|||||||
}
|
}
|
||||||
rpcLog.debug { "<- RPC <- $methodName = $response " }
|
rpcLog.debug { "<- RPC <- $methodName = $response " }
|
||||||
|
|
||||||
val kryo = createRPCKryo(observableSerializer = if (observationsTo != null) ObservableSerializer(observationsTo) else null)
|
|
||||||
|
|
||||||
// Serialise, or send back a simple serialised ErrorOr structure if we couldn't do it.
|
// Serialise, or send back a simple serialised ErrorOr structure if we couldn't do it.
|
||||||
val responseBits = try {
|
val responseBits = try {
|
||||||
|
@ -26,6 +26,7 @@ import net.corda.core.serialization.*
|
|||||||
import net.corda.core.transactions.SignedTransaction
|
import net.corda.core.transactions.SignedTransaction
|
||||||
import net.corda.core.transactions.WireTransaction
|
import net.corda.core.transactions.WireTransaction
|
||||||
import net.corda.flows.CashFlowResult
|
import net.corda.flows.CashFlowResult
|
||||||
|
import net.corda.node.internal.AbstractNode
|
||||||
import net.corda.node.services.User
|
import net.corda.node.services.User
|
||||||
import net.i2p.crypto.eddsa.EdDSAPrivateKey
|
import net.i2p.crypto.eddsa.EdDSAPrivateKey
|
||||||
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
import net.i2p.crypto.eddsa.EdDSAPublicKey
|
||||||
@ -106,6 +107,17 @@ open class RPCException(msg: String, cause: Throwable?) : RuntimeException(msg,
|
|||||||
class DeadlineExceeded(rpcName: String) : RPCException("Deadline exceeded on call to $rpcName")
|
class DeadlineExceeded(rpcName: String) : RPCException("Deadline exceeded on call to $rpcName")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object ClassSerializer : Serializer<Class<*>>() {
|
||||||
|
override fun read(kryo: Kryo, input: Input, type: Class<Class<*>>): Class<*> {
|
||||||
|
val className = input.readString()
|
||||||
|
return Class.forName(className)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun write(kryo: Kryo, output: Output, clazz: Class<*>) {
|
||||||
|
output.writeString(clazz.name)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class PermissionException(msg: String) : RuntimeException(msg)
|
class PermissionException(msg: String) : RuntimeException(msg)
|
||||||
|
|
||||||
// The Kryo used for the RPC wire protocol. Every type in the wire protocol is listed here explicitly.
|
// The Kryo used for the RPC wire protocol. Every type in the wire protocol is listed here explicitly.
|
||||||
@ -132,6 +144,8 @@ private class RPCKryo(observableSerializer: Serializer<Observable<Any>>? = null)
|
|||||||
register(WireTransaction::class.java, WireTransactionSerializer)
|
register(WireTransaction::class.java, WireTransactionSerializer)
|
||||||
register(SerializedBytes::class.java, SerializedBytesSerializer)
|
register(SerializedBytes::class.java, SerializedBytesSerializer)
|
||||||
register(Party::class.java)
|
register(Party::class.java)
|
||||||
|
register(Array<Any>(0,{}).javaClass)
|
||||||
|
register(Class::class.java, ClassSerializer)
|
||||||
|
|
||||||
ImmutableListSerializer.registerSerializers(this)
|
ImmutableListSerializer.registerSerializers(this)
|
||||||
ImmutableSetSerializer.registerSerializers(this)
|
ImmutableSetSerializer.registerSerializers(this)
|
||||||
@ -165,6 +179,7 @@ private class RPCKryo(observableSerializer: Serializer<Observable<Any>>? = null)
|
|||||||
register(StateMachineRunId::class.java)
|
register(StateMachineRunId::class.java)
|
||||||
register(StateMachineTransactionMapping::class.java)
|
register(StateMachineTransactionMapping::class.java)
|
||||||
register(UUID::class.java)
|
register(UUID::class.java)
|
||||||
|
register(UniqueIdentifier::class.java)
|
||||||
register(LinkedHashSet::class.java)
|
register(LinkedHashSet::class.java)
|
||||||
register(StateAndRef::class.java)
|
register(StateAndRef::class.java)
|
||||||
register(setOf<Unit>().javaClass) // EmptySet
|
register(setOf<Unit>().javaClass) // EmptySet
|
||||||
@ -210,6 +225,8 @@ private class RPCKryo(observableSerializer: Serializer<Observable<Any>>? = null)
|
|||||||
register(ServiceEntry::class.java)
|
register(ServiceEntry::class.java)
|
||||||
// Exceptions. We don't bother sending the stack traces as the client will fill in its own anyway.
|
// Exceptions. We don't bother sending the stack traces as the client will fill in its own anyway.
|
||||||
register(IllegalArgumentException::class.java)
|
register(IllegalArgumentException::class.java)
|
||||||
|
register(ArrayIndexOutOfBoundsException::class.java)
|
||||||
|
register(IndexOutOfBoundsException::class.java)
|
||||||
// Kryo couldn't serialize Collections.unmodifiableCollection in Throwable correctly, causing null pointer exception when try to access the deserialize object.
|
// Kryo couldn't serialize Collections.unmodifiableCollection in Throwable correctly, causing null pointer exception when try to access the deserialize object.
|
||||||
register(NoSuchElementException::class.java, JavaSerializer())
|
register(NoSuchElementException::class.java, JavaSerializer())
|
||||||
register(RPCException::class.java)
|
register(RPCException::class.java)
|
||||||
@ -219,6 +236,11 @@ private class RPCKryo(observableSerializer: Serializer<Observable<Any>>? = null)
|
|||||||
register(FlowHandle::class.java)
|
register(FlowHandle::class.java)
|
||||||
register(KryoException::class.java)
|
register(KryoException::class.java)
|
||||||
register(StringBuffer::class.java)
|
register(StringBuffer::class.java)
|
||||||
|
for ((_flow, argumentTypes) in AbstractNode.defaultFlowWhiteList) {
|
||||||
|
for (type in argumentTypes) {
|
||||||
|
register(type)
|
||||||
|
}
|
||||||
|
}
|
||||||
pluginRegistries.forEach { it.registerRPCKryoTypes(this) }
|
pluginRegistries.forEach { it.registerRPCKryoTypes(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user