Introducing InitiatedBy annotation to be used on initiated flows to simplify flow registration.

This removes the need to do manual registration using the PluginServiceHub. As a result CordaPluginRegistry.servicePlugins is no longer needed. For oracles and services there is a CorDappService annotation.

I've also fixed the InitiatingFlow annotation such that client flows can be customised (sub-typed) without it breaking the flow sessions.
This commit is contained in:
Shams Asari
2017-05-19 16:14:48 +01:00
parent e117ab7703
commit 329e5ff17b
66 changed files with 892 additions and 760 deletions

View File

@ -16,6 +16,7 @@ import net.corda.node.services.transactions.SimpleNotaryService
import net.corda.nodeapi.User
import net.corda.testing.BOC
import net.corda.testing.node.NodeBasedTest
import net.corda.traderdemo.flow.BuyerFlow
import net.corda.traderdemo.flow.SellerFlow
import org.assertj.core.api.Assertions.assertThat
import org.junit.Test
@ -36,6 +37,8 @@ class TraderDemoTest : NodeBasedTest() {
startNode(DUMMY_NOTARY.name, advertisedServices = setOf(ServiceInfo(SimpleNotaryService.type)))
).getOrThrow()
nodeA.registerInitiatedFlow(BuyerFlow::class.java)
val (nodeARpc, nodeBRpc) = listOf(nodeA, nodeB).map {
val client = CordaRPCClient(it.configuration.rpcAddress!!)
client.start(demoUser[0].username, demoUser[0].password).proxy
@ -57,12 +60,8 @@ class TraderDemoTest : NodeBasedTest() {
val executor = Executors.newScheduledThreadPool(1)
poll(executor, "A to be notified of the commercial paper", pollInterval = 100.millis) {
val actualPaper = listOf(clientA.commercialPaperCount, clientB.commercialPaperCount)
if (actualPaper == expectedPaper) {
Unit
} else {
null
}
}.get()
if (actualPaper == expectedPaper) Unit else null
}.getOrThrow()
executor.shutdown()
assertThat(clientA.dollarCashBalance).isEqualTo(95.DOLLARS)
assertThat(clientB.dollarCashBalance).isEqualTo(5.DOLLARS)

View File

@ -4,36 +4,24 @@ import co.paralleluniverse.fibers.Suspendable
import net.corda.contracts.CommercialPaper
import net.corda.core.contracts.Amount
import net.corda.core.contracts.TransactionGraphSearch
import net.corda.core.identity.Party
import net.corda.core.div
import net.corda.core.flows.FlowLogic
import net.corda.core.flows.InitiatedBy
import net.corda.core.identity.Party
import net.corda.core.node.NodeInfo
import net.corda.core.node.PluginServiceHub
import net.corda.core.serialization.SingletonSerializeAsToken
import net.corda.core.transactions.SignedTransaction
import net.corda.core.utilities.Emoji
import net.corda.core.utilities.ProgressTracker
import net.corda.core.utilities.unwrap
import net.corda.flows.TwoPartyTradeFlow
import java.nio.file.Paths
import java.util.*
class BuyerFlow(val otherParty: Party,
private val attachmentsDirectory: String,
override val progressTracker: ProgressTracker = ProgressTracker(STARTING_BUY)) : FlowLogic<Unit>() {
@InitiatedBy(SellerFlow::class)
class BuyerFlow(val otherParty: Party) : FlowLogic<Unit>() {
object STARTING_BUY : ProgressTracker.Step("Seller connected, purchasing commercial paper asset")
class Service(services: PluginServiceHub) : SingletonSerializeAsToken() {
init {
// Buyer will fetch the attachment from the seller automatically when it resolves the transaction.
// For demo purposes just extract attachment jars when saved to disk, so the user can explore them.
val attachmentsPath = (services.storageService.attachments).let {
it.automaticallyExtractAttachments = true
it.storePath
}
services.registerServiceFlow(SellerFlow::class.java) { BuyerFlow(it, attachmentsPath.toString()) }
}
}
override val progressTracker: ProgressTracker = ProgressTracker(STARTING_BUY)
@Suspendable
override fun call() {
@ -72,8 +60,15 @@ class BuyerFlow(val otherParty: Party,
followInputsOfType = CommercialPaper.State::class.java)
val cpIssuance = search.call().single()
// Buyer will fetch the attachment from the seller automatically when it resolves the transaction.
// For demo purposes just extract attachment jars when saved to disk, so the user can explore them.
val attachmentsPath = (serviceHub.storageService.attachments).let {
it.automaticallyExtractAttachments = true
it.storePath
}
cpIssuance.attachments.first().let {
val p = Paths.get(attachmentsDirectory, "$it.jar")
val p = attachmentsPath / "$it.jar"
println("""
The issuance of the commercial paper came with an attachment. You can find it expanded in this directory:

View File

@ -1,10 +0,0 @@
package net.corda.traderdemo.plugin
import net.corda.core.identity.Party
import net.corda.core.node.CordaPluginRegistry
import net.corda.traderdemo.flow.BuyerFlow
import java.util.function.Function
class TraderDemoPlugin : CordaPluginRegistry() {
override val servicePlugins = listOf(Function(BuyerFlow::Service))
}

View File

@ -1,2 +0,0 @@
# Register a ServiceLoader service extending from net.corda.core.node.CordaPluginRegistry
net.corda.traderdemo.plugin.TraderDemoPlugin