I have a situation where I have an #InitiatingFlow, called ProposeMemberFlow, and a corresponding #InitiatedBy ProposeMemberFlowResponder. I would like include in my integration test something that tests that the responder has one of the transaction output states post the FinalityFlow sub flow having been kicked off by the initiating flow.
I naively called waitForLedgerCommit in the responding flow, post responding to the CollectSignaturesFlow, but I'm finding that the initiating flow finishes before the responding flow does - presumably the latter is waiting for the vault update.
I'm integration testing through a CordaService - is "the corda way" to use expectEvents to wait for VaultUpdates so that I then know when it's safe to test against the CordaService? Much like here?
Thanks
I haven't heard of integration testing via a CordaService. Generally, you would write integration tests using the node driver.
Here's an example: https://github.com/corda/cordapp-template-kotlin/blob/release-V2/cordapp/src/integrationTest/kotlin/com/template/DriverBasedTest.kt
This piece of code starts a set of nodes, then uses RPC to check some conditions of the node.
In your case, you'd want to use the following set of RPC operations in the node driver:
CordaRPCOps.startFlowDynamic on node A's RPC handle to run the ProposeMemberFlow
CordaRPCOps.vaultQueryBy on node B's RPC handle to check that the correct state has been written to the vault
Another option would be to use the mock network (e.g. https://github.com/corda/cordapp-example/blob/release-V2/kotlin-source/src/test/kotlin/com/example/flow/IOUFlowTests.kt). You could argue that this isn't an integration test, since you are running mock nodes instead of real nodes. However, the mock nodes are just another implementation of the AbstractNode interface, and should behave like normal nodes for the purposes of testing.
Related
I need to call one service from the other so I want to be sure it's ready before I use it. In my case, both microservices are running in the same database.
In the startup script, I would like to wait until the dependency is operational and abort if it isn't ready after a specified time. So this leads to the questions:
How do I detect whether another microservice is started?
What is the best approach to wait for another microservice to start.
If it doesn't start what is the right way to abort starting the current microservice.
Thanks.
Looks like it's actually easy. I set up the "provides" and "dependencies" in the respective foxx manifests. This prevents the dependent service from being mounted before the "provider" is ready to accept requests.
There is a bank which creates a contract which is then accepted by the lender and the borrower. After signing the contract the lender provides fund to the borrower. The bank then creates an obligation state based on the data received by calling an external service automatically.
And Now
1) In API Layer, I am calling first flow which creates one state.
2) In API layer itself, On success of first flow , I am calling the http request to external service and get the data.
3) Now I pass the http response to the the second flow for creating the other state.
Can you please let me know if there is any issue with this approach.
Requirment is I want to trigger the first flow manually, but calling external service and initiating the second flow should happen automatically
I had referred the link given below.
Making asynchronous HTTP calls from flows
You'll make calls to an external service during the running of flows.
The best place to get started would be looking at the CorDapp samples here. In particular, take a look at the Accessing External Data section
I am trying to implement the following use-case in Corda:
FlowA has been invoked on PartyA via startFlowDynamic. FlowA creates a partially signed transaction and invokes FlowB on PartyB via sendAndReceive. A human user shall now review and manually approve this transaction. Ideally FlowB should suspend after receiving the transaction. I would like to be able to query for suspended instances of FlowB via RPC, and present those (or rather some representation of the transaction therein) to the user in my UI. Then, after the user actions his approval, I would like to resume FlowB via RPC, which would then sign the transaction and return it to FlowA on PartyA.
I noticed that I can inspect suspended flows to some degree via CordaRPCOps.stateMachineAndUpdates and I read the tutorial on progress tracking, but it doesn't quite suffice for my case. I also read that interacting with people from flows is listed as a future feature, I just wondered if there isn't already some way to accomplish this ?
See the Negotiation Cordapp sample for an example of how this would work in practice here.
Corda doesn't currently support suspending a flow for user interaction.
However, you can support this kind of workflow as follows. Suppose you're writing a CorDapp for loan applications. You could have an initial flow that agrees the creation of a loanApplicationstate between two parties. From there, the approver can inspect the loan application, and either kick off an approve flow that creates a transaction to transform the loanApplication into an approvedLoan state, or kick off a reject flow to consume the loanApplication state without issuing an approvedLoan state.
Equally, you could add a status field to the loan state, specifying whether the loan is approved or not. Initially, the loan state would have the field set to unapproved. Then the approver could kick off one of two flows to update the loan state, to either have an approved or a rejected status.
I'm not sure if this is a "recommended approach" but I implemented a Quasar compatible AsynchListenableFuture in my flow as someone else had described here.
I needed to suspend a flow and wait for the production of a state from another flow (in response to a user interaction). It seems to work, but suspect it could be regarded as rather off-piste(?!).
Splitting the activities into atomic flows invoked directly by UI interaction is fine, but I needed a sort of "monitoring" flow to wait for an external (e.g. user) event before determining which sub flow to initiate next, and this needed to happen automatically and from within a flow already invoked prior to the the user interaction - the flow logic is then conditional on a state change which may arise from a user interaction or an incoming transaction from another node. In my case, this high level monitoring flow detects the consumption of a known state on the node, then invokes a subflow in response. The high level flow waits on the AsynchListenableFuture as described in the answer referenced above. I created a composite VaultQuery on an attribute of states of contract state types of interest (e.g custom field X = Y), and converted the returned observable (returned from trackBy.future) to a Quasar compatible AsynchListenableFuture. When the state is consumed by a transaction created by a flow triggered by the external action, the future returns and the automatic event (in my case the creation of an other transaction with another party) is executed.
I'm only experimenting / evaluating Corda, not sure how robust this approach would be in production reality, but it seems to work OK, hope this helps in some way.
Some form of higher level workflow flows in Corda, which can wait on external events and conditionally invoke other flows depending on the external action would be of real interest in my context.
Is there anyway to let rebus publish all message synchronously so that I can assert on some value after all message have been processed?
Or what is the best way to do an integration test:
Publish event
handle by saga, send command
Handle command, publish another event
Saga marked as completed
the another event handler update the database
assert or database
Thanks
Regards
Yin
For testing a single saga and its behavior you should take a look at the blog post I wrote, Unit testing sagas with Rebus, which is an example on how SagaFixture and FakeBus can be used - I think it supports everything you're mentioning that you want to test.
If you're interested in testing more complicated scenarios, possibly involving other handlers and longer message correspondences etc, you might benefit from some strategic use of ManualResetEvent - Rebus has several integration tests that start up a bus and do some stuff, doing a resetEvent.Set() when the scenario is over - this way, the test can do a resetEvent.WaitOne(timeout) to block while the test is running and continue immediately when it's over.
Team:
I need to invoke a WF activity (XAML) from a WF service (XAMLX) asynchronously. I am already referencing the Microsoft.Activities.Extensions framework and I'm running on the Platform Update 1 for the state machine -- so if the solution is already in one of those libraries I'm ready!
Now, I need to invoke that activity (XAML) asynchronously -- but it has an output parameter that needs to set a variable in the service (XAMLX). Can somebody please provide me a solution to this?
Thanks!
* UPDATE *
Now I can post pictures, * I think *, because I have enough reputation! Let me put a couple out here and try to better explain my problem. The first picture is the WF Service that has the two entry points for the workflow -- the second is the workflow itself.
This workflow is an orchestration mechanism that constantly restarts itself, and has some failover mechanisms (e.g. exit on error threshold and soft exit) so that we can manage our queue of durable transactions using WF!
Now, we had this workflow working great when it was all one WF Service because we could call the service, get a response back and send the value of that response back into another entry point in a trigger to issue a soft exit. However, a new requirement has arrisen asking us to make the workflow itself a WF activity in another project and have the Receive/Send-Reply sequences in the WF Service Application project.
However, we need to be able to startup this workflow and forget about it -- then let it know somehow that a soft exit is necessary later on down the road -- but since WF executes on a single thread this has become a bit challenging at best.
Strictly speaking in XAML activities Parallel and ParallelForEach are how you perform asynchrony.
The workflow scheduler only uses a single thread (much like UI) so any activity that is running will typically be running on the same thread, unless it implements AsyncCodeActivity, in which case you are simply handing back the scheduler thread to the runtime while waiting for a callback from whichever async code your AsyncCodeActivity implementation is calling.
Therefore are you sure this is what you want to achieve? Do you mean you want to run it after you have sent your initial response? In this case place your activity after the Send Reply.
Please provide more info if these suggestions don't answer your question./
Update:
The original requirement posed (separating implementation from the service Receive/Send activities) may actually be solved by hosting the target activity as a service. See the following link
http://blog.petegoo.com/index.php/2011/09/02/building-an-enterprise-workflow-system-with-wf4/