mirror of
https://github.com/corda/corda.git
synced 2025-06-18 07:08:15 +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:
@ -7,6 +7,7 @@ import net.corda.core.utilities.DUMMY_BANK_A
|
||||
import net.corda.core.utilities.DUMMY_BANK_B
|
||||
import net.corda.core.utilities.DUMMY_NOTARY
|
||||
import net.corda.node.driver.driver
|
||||
import net.corda.node.services.startFlowPermission
|
||||
import net.corda.node.services.transactions.SimpleNotaryService
|
||||
import net.corda.nodeapi.User
|
||||
import org.junit.Test
|
||||
@ -17,11 +18,11 @@ class AttachmentDemoTest {
|
||||
@Test fun `attachment demo using a 10MB zip file`() {
|
||||
val numOfExpectedBytes = 10_000_000
|
||||
driver(dsl = {
|
||||
val demoUser = listOf(User("demo", "demo", setOf("StartFlow.net.corda.flows.FinalityFlow")))
|
||||
val demoUser = listOf(User("demo", "demo", setOf(startFlowPermission<AttachmentDemoFlow>())))
|
||||
val (nodeA, nodeB) = Futures.allAsList(
|
||||
startNode(DUMMY_BANK_A.name, rpcUsers = demoUser),
|
||||
startNode(DUMMY_BANK_B.name, rpcUsers = demoUser),
|
||||
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.Companion.type)))
|
||||
startNode(DUMMY_NOTARY.name, setOf(ServiceInfo(SimpleNotaryService.type)))
|
||||
).getOrThrow()
|
||||
|
||||
val senderThread = CompletableFuture.supplyAsync {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package net.corda.attachmentdemo
|
||||
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import com.google.common.net.HostAndPort
|
||||
import joptsimple.OptionParser
|
||||
import net.corda.client.rpc.CordaRPCClient
|
||||
@ -9,14 +10,14 @@ import net.corda.core.contracts.TransactionForContract
|
||||
import net.corda.core.contracts.TransactionType
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.crypto.SecureHash
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.getOrThrow
|
||||
import net.corda.core.messaging.CordaRPCOps
|
||||
import net.corda.core.messaging.startTrackedFlow
|
||||
import net.corda.core.sizedInputStreamAndHash
|
||||
import net.corda.core.utilities.DUMMY_BANK_B
|
||||
import net.corda.core.utilities.DUMMY_NOTARY
|
||||
import net.corda.core.utilities.DUMMY_NOTARY_KEY
|
||||
import net.corda.core.utilities.Emoji
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.core.utilities.*
|
||||
import net.corda.flows.FinalityFlow
|
||||
import net.corda.node.driver.poll
|
||||
import java.io.InputStream
|
||||
@ -83,26 +84,40 @@ fun sender(rpc: CordaRPCOps, inputStream: InputStream, hash: SecureHash.SHA256)
|
||||
val id = rpc.uploadAttachment(it)
|
||||
require(hash == id) { "Id was '$id' instead of '$hash'" }
|
||||
}
|
||||
require(rpc.attachmentExists(hash))
|
||||
}
|
||||
|
||||
// Create a trivial transaction with an output that describes the attachment, and the attachment itself
|
||||
val ptx = TransactionType.General.Builder(notary = DUMMY_NOTARY)
|
||||
require(rpc.attachmentExists(hash))
|
||||
ptx.addOutputState(AttachmentContract.State(hash))
|
||||
ptx.addAttachment(hash)
|
||||
|
||||
// Sign with the notary key
|
||||
ptx.signWith(DUMMY_NOTARY_KEY)
|
||||
|
||||
// Send the transaction to the other recipient
|
||||
val stx = ptx.toSignedTransaction()
|
||||
println("Sending ${stx.id}")
|
||||
val flowHandle = rpc.startTrackedFlow(::FinalityFlow, stx, setOf(otherSide))
|
||||
val flowHandle = rpc.startTrackedFlow(::AttachmentDemoFlow, otherSide, hash)
|
||||
flowHandle.progress.subscribe(::println)
|
||||
flowHandle.returnValue.getOrThrow()
|
||||
val stx = flowHandle.returnValue.getOrThrow()
|
||||
println("Sent ${stx.id}")
|
||||
}
|
||||
|
||||
@StartableByRPC
|
||||
class AttachmentDemoFlow(val otherSide: Party, val hash: SecureHash.SHA256) : FlowLogic<SignedTransaction>() {
|
||||
|
||||
object SIGNING : ProgressTracker.Step("Signing transaction")
|
||||
|
||||
override val progressTracker: ProgressTracker = ProgressTracker(SIGNING)
|
||||
|
||||
@Suspendable
|
||||
override fun call(): SignedTransaction {
|
||||
// Create a trivial transaction with an output that describes the attachment, and the attachment itself
|
||||
val ptx = TransactionType.General.Builder(notary = DUMMY_NOTARY)
|
||||
ptx.addOutputState(AttachmentContract.State(hash))
|
||||
ptx.addAttachment(hash)
|
||||
|
||||
progressTracker.currentStep = SIGNING
|
||||
// Sign with the notary key
|
||||
ptx.signWith(DUMMY_NOTARY_KEY)
|
||||
|
||||
// Send the transaction to the other recipient
|
||||
val stx = ptx.toSignedTransaction()
|
||||
|
||||
return subFlow(FinalityFlow(stx, setOf(otherSide))).single()
|
||||
}
|
||||
}
|
||||
|
||||
fun recipient(rpc: CordaRPCOps) {
|
||||
println("Waiting to receive transaction ...")
|
||||
val stx = rpc.verifiedTransactions().second.toBlocking().first()
|
||||
|
@ -1,12 +0,0 @@
|
||||
package net.corda.attachmentdemo.plugin
|
||||
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.flows.FinalityFlow
|
||||
|
||||
class AttachmentDemoPlugin : CordaPluginRegistry() {
|
||||
// A list of Flows that are required for this cordapp
|
||||
override val requiredFlows: Map<String, Set<String>> = mapOf(
|
||||
FinalityFlow::class.java.name to setOf(SignedTransaction::class.java.name, setOf(Unit).javaClass.name, setOf(Unit).javaClass.name)
|
||||
)
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
# Register a ServiceLoader service extending from net.corda.core.node.CordaPluginRegistry
|
||||
net.corda.attachmentdemo.plugin.AttachmentDemoPlugin
|
@ -1,17 +1,13 @@
|
||||
package net.corda.bank.plugin
|
||||
|
||||
import net.corda.bank.api.BankOfCordaWebApi
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
import net.corda.core.serialization.OpaqueBytes
|
||||
import net.corda.flows.IssuerFlow
|
||||
import java.util.function.Function
|
||||
|
||||
class BankOfCordaPlugin : CordaPluginRegistry() {
|
||||
// A list of classes that expose web APIs.
|
||||
override val webApis = listOf(Function(::BankOfCordaWebApi))
|
||||
// A list of flow that are required for this cordapp
|
||||
override val requiredFlows: Map<String, Set<String>> = mapOf(IssuerFlow.IssuanceRequester::class.java.name to setOf(Amount::class.java.name, Party::class.java.name, OpaqueBytes::class.java.name, Party::class.java.name))
|
||||
override val servicePlugins = listOf(Function(IssuerFlow.Issuer::Service))
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
import net.corda.core.transactions.FilteredTransaction
|
||||
import net.corda.core.utilities.ProgressTracker
|
||||
import net.corda.core.utilities.unwrap
|
||||
import net.corda.irs.flows.FixingFlow
|
||||
import net.corda.irs.flows.RatesFixFlow
|
||||
import net.corda.node.services.api.AcceptsFileUpload
|
||||
import net.corda.node.utilities.AbstractJDBCHashSet
|
||||
@ -32,12 +31,14 @@ import java.io.InputStream
|
||||
import java.math.BigDecimal
|
||||
import java.security.KeyPair
|
||||
import java.time.Clock
|
||||
import java.time.Duration
|
||||
import java.time.Instant
|
||||
import java.time.LocalDate
|
||||
import java.util.*
|
||||
import java.util.function.Function
|
||||
import javax.annotation.concurrent.ThreadSafe
|
||||
import kotlin.collections.component1
|
||||
import kotlin.collections.component2
|
||||
import kotlin.collections.set
|
||||
|
||||
/**
|
||||
* An interest rates service is an oracle that signs transactions which contain embedded assertions about an interest
|
||||
@ -55,7 +56,6 @@ object NodeInterestRates {
|
||||
* Register the flow that is used with the Fixing integration tests.
|
||||
*/
|
||||
class Plugin : CordaPluginRegistry() {
|
||||
override val requiredFlows = mapOf(Pair(FixingFlow.FixingRoleDecider::class.java.name, setOf(Duration::class.java.name, StateRef::class.java.name)))
|
||||
override val servicePlugins = listOf(Function(::Service))
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ import net.corda.core.contracts.DealState
|
||||
import net.corda.core.identity.AbstractParty
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
import net.corda.core.node.PluginServiceHub
|
||||
import net.corda.core.serialization.SingletonSerializeAsToken
|
||||
@ -37,6 +38,7 @@ object AutoOfferFlow {
|
||||
}
|
||||
|
||||
@InitiatingFlow
|
||||
@StartableByRPC
|
||||
class Requester(val dealToBeOffered: DealState) : FlowLogic<SignedTransaction>() {
|
||||
|
||||
companion object {
|
||||
|
@ -8,6 +8,7 @@ import net.corda.core.crypto.keys
|
||||
import net.corda.core.crypto.toBase58String
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.flows.SchedulableFlow
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.PluginServiceHub
|
||||
import net.corda.core.node.services.ServiceType
|
||||
@ -136,6 +137,7 @@ object FixingFlow {
|
||||
* Fixer role is chosen, then that will be initiated by the [FixingSession] message sent from the other party.
|
||||
*/
|
||||
@InitiatingFlow
|
||||
@SchedulableFlow
|
||||
class FixingRoleDecider(val ref: StateRef, override val progressTracker: ProgressTracker) : FlowLogic<Unit>() {
|
||||
@Suppress("unused") // Used via reflection.
|
||||
constructor(ref: StateRef) : this(ref, tracker())
|
||||
|
@ -4,6 +4,7 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.node.PluginServiceHub
|
||||
@ -44,6 +45,7 @@ object UpdateBusinessDayFlow {
|
||||
|
||||
|
||||
@InitiatingFlow
|
||||
@StartableByRPC
|
||||
class Broadcast(val date: LocalDate, override val progressTracker: ProgressTracker) : FlowLogic<Unit>() {
|
||||
constructor(date: LocalDate) : this(date, tracker())
|
||||
|
||||
|
@ -1,15 +1,9 @@
|
||||
package net.corda.irs.plugin
|
||||
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
import net.corda.irs.api.InterestRateSwapAPI
|
||||
import net.corda.irs.contract.InterestRateSwap
|
||||
import net.corda.irs.flows.AutoOfferFlow
|
||||
import net.corda.irs.flows.FixingFlow
|
||||
import net.corda.irs.flows.UpdateBusinessDayFlow
|
||||
import java.time.Duration
|
||||
import java.time.LocalDate
|
||||
import java.util.function.Function
|
||||
|
||||
class IRSPlugin : CordaPluginRegistry() {
|
||||
@ -18,9 +12,4 @@ class IRSPlugin : CordaPluginRegistry() {
|
||||
"irsdemo" to javaClass.classLoader.getResource("irsweb").toExternalForm()
|
||||
)
|
||||
override val servicePlugins = listOf(Function(FixingFlow::Service))
|
||||
override val requiredFlows: Map<String, Set<String>> = mapOf(
|
||||
AutoOfferFlow.Requester::class.java.name to setOf(InterestRateSwap.State::class.java.name),
|
||||
UpdateBusinessDayFlow.Broadcast::class.java.name to setOf(LocalDate::class.java.name),
|
||||
FixingFlow.FixingRoleDecider::class.java.name to setOf(StateRef::class.java.name, Duration::class.java.name),
|
||||
FixingFlow.Floater::class.java.name to setOf(Party::class.java.name, FixingFlow.FixingSession::class.java.name))
|
||||
}
|
||||
|
@ -1,15 +0,0 @@
|
||||
package net.corda.notarydemo.plugin
|
||||
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
import net.corda.flows.NotaryFlow
|
||||
import net.corda.notarydemo.flows.DummyIssueAndMove
|
||||
|
||||
class NotaryDemoPlugin : CordaPluginRegistry() {
|
||||
// A list of protocols that are required for this cordapp
|
||||
override val requiredFlows = mapOf(
|
||||
NotaryFlow.Client::class.java.name to setOf(SignedTransaction::class.java.name, setOf(Unit).javaClass.name),
|
||||
DummyIssueAndMove::class.java.name to setOf(Party::class.java.name)
|
||||
)
|
||||
}
|
@ -1,2 +0,0 @@
|
||||
# Register a ServiceLoader service extending from net.corda.node.CordaPluginRegistry
|
||||
net.corda.notarydemo.plugin.NotaryDemoPlugin
|
@ -4,6 +4,7 @@ import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.node.PluginServiceHub
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
@ -24,6 +25,7 @@ object IRSTradeFlow {
|
||||
data class OfferMessage(val notary: Party, val dealBeingOffered: IRSState)
|
||||
|
||||
@InitiatingFlow
|
||||
@StartableByRPC
|
||||
class Requester(val swap: SwapData, val otherParty: Party) : FlowLogic<SignedTransaction>() {
|
||||
@Suspendable
|
||||
override fun call(): SignedTransaction {
|
||||
|
@ -14,6 +14,7 @@ import net.corda.core.identity.AnonymousParty
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.node.PluginServiceHub
|
||||
import net.corda.core.node.services.dealsWith
|
||||
import net.corda.core.serialization.CordaSerializable
|
||||
@ -51,6 +52,7 @@ object SimmFlow {
|
||||
* margin using SIMM. If there is an existing state it will update and revalue the portfolio agreement.
|
||||
*/
|
||||
@InitiatingFlow
|
||||
@StartableByRPC
|
||||
class Requester(val otherParty: Party,
|
||||
val valuationDate: LocalDate,
|
||||
val existing: StateAndRef<PortfolioState>?)
|
||||
|
@ -3,6 +3,8 @@ package net.corda.vega.flows
|
||||
import co.paralleluniverse.fibers.Suspendable
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.SchedulableFlow
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.node.services.linearHeadsOfType
|
||||
import net.corda.vega.contracts.PortfolioState
|
||||
import java.time.LocalDate
|
||||
@ -12,6 +14,8 @@ import java.time.LocalDate
|
||||
* requirements
|
||||
*/
|
||||
object SimmRevaluation {
|
||||
@StartableByRPC
|
||||
@SchedulableFlow
|
||||
class Initiator(val curStateRef: StateRef, val valuationDate: LocalDate) : FlowLogic<Unit>() {
|
||||
@Suspendable
|
||||
override fun call(): Unit {
|
||||
|
@ -10,18 +10,14 @@ import com.opengamma.strata.market.curve.CurveName
|
||||
import com.opengamma.strata.market.param.CurrencyParameterSensitivities
|
||||
import com.opengamma.strata.market.param.CurrencyParameterSensitivity
|
||||
import com.opengamma.strata.market.param.TenorDateParameterMetadata
|
||||
import net.corda.core.contracts.StateRef
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
import net.corda.core.serialization.SerializationCustomization
|
||||
import net.corda.vega.analytics.CordaMarketData
|
||||
import net.corda.vega.analytics.InitialMarginTriple
|
||||
import net.corda.vega.api.PortfolioApi
|
||||
import net.corda.vega.contracts.SwapData
|
||||
import net.corda.vega.flows.IRSTradeFlow
|
||||
import net.corda.vega.flows.SimmFlow
|
||||
import net.corda.vega.flows.SimmRevaluation
|
||||
import java.time.LocalDate
|
||||
import java.util.function.Function
|
||||
|
||||
/**
|
||||
@ -32,10 +28,6 @@ import java.util.function.Function
|
||||
object SimmService {
|
||||
class Plugin : CordaPluginRegistry() {
|
||||
override val webApis = listOf(Function(::PortfolioApi))
|
||||
override val requiredFlows: Map<String, Set<String>> = mapOf(
|
||||
SimmFlow.Requester::class.java.name to setOf(Party::class.java.name, LocalDate::class.java.name),
|
||||
SimmRevaluation.Initiator::class.java.name to setOf(StateRef::class.java.name, LocalDate::class.java.name),
|
||||
IRSTradeFlow.Requester::class.java.name to setOf(SwapData::class.java.name, Party::class.java.name))
|
||||
override val staticServeDirs: Map<String, String> = mapOf("simmvaluationdemo" to javaClass.classLoader.getResource("simmvaluationweb").toExternalForm())
|
||||
override val servicePlugins = listOf(Function(SimmFlow::Service), Function(IRSTradeFlow::Service))
|
||||
override fun customizeSerialization(custom: SerializationCustomization): Boolean {
|
||||
|
@ -10,6 +10,7 @@ import net.corda.core.crypto.generateKeyPair
|
||||
import net.corda.core.days
|
||||
import net.corda.core.flows.FlowLogic
|
||||
import net.corda.core.flows.InitiatingFlow
|
||||
import net.corda.core.flows.StartableByRPC
|
||||
import net.corda.core.node.NodeInfo
|
||||
import net.corda.core.seconds
|
||||
import net.corda.core.transactions.SignedTransaction
|
||||
@ -22,6 +23,7 @@ import java.time.Instant
|
||||
import java.util.*
|
||||
|
||||
@InitiatingFlow
|
||||
@StartableByRPC
|
||||
class SellerFlow(val otherParty: Party,
|
||||
val amount: Amount<Currency>,
|
||||
override val progressTracker: ProgressTracker) : FlowLogic<SignedTransaction>() {
|
||||
|
@ -1,16 +1,10 @@
|
||||
package net.corda.traderdemo.plugin
|
||||
|
||||
import net.corda.core.contracts.Amount
|
||||
import net.corda.core.identity.Party
|
||||
import net.corda.core.node.CordaPluginRegistry
|
||||
import net.corda.traderdemo.flow.BuyerFlow
|
||||
import net.corda.traderdemo.flow.SellerFlow
|
||||
import java.util.function.Function
|
||||
|
||||
class TraderDemoPlugin : CordaPluginRegistry() {
|
||||
// A list of Flows that are required for this cordapp
|
||||
override val requiredFlows: Map<String, Set<String>> = mapOf(
|
||||
SellerFlow::class.java.name to setOf(Party::class.java.name, Amount::class.java.name)
|
||||
)
|
||||
override val servicePlugins = listOf(Function(BuyerFlow::Service))
|
||||
}
|
||||
|
Reference in New Issue
Block a user