Contract Tests for APIs which involve session or workflow - pact

Hi I am trying to write Contract Tests for a product purchase workflow. So obviously i cannot call the Checkout API directly without calling Add to Cart API.
But as I have observed the verification hits the paths individually might not be in the same order as listed in the Pact JSON File.
So how should I handle such scnenario which involve session management and workflow(meaning step1 shud be successful only then step2 will be success)
Thanks!

Use provider states to set up the right data in the cart so that when you call checkout, you get the behaviour you want. Here's the documentation from pact.io on provider states.
Each interaction in a pact should be verified in isolation, with no context maintained from the previous interactions. Tests that depend on the outcome of previous tests are brittle and land you back in integration test hell, which is the nasty place you're trying to escape by using pacts.
So how do you test a request that requires data to already exist on the provider? Provider states allow you to set up data on the provider by injecting it straight into the data source before the interaction is run, so that it can make a response that matches what the consumer expects. The name of the provider state is specified in the given clause of an interaction in the consumer, and then used to find the block of code to run in the provider to set up the right data. If you need to stub a downstream system, or return an error response that is difficult to cause in the normal scheme of things (e.g. a 500), this is the place where you can set up stubs.
https://docs.pact.io/documentation/provider_states.html
In your case, this would look like:
Given an item has been added to the cart
upon receiving a request to checkout it will respond with the checkout response....
As an aside, I would also imagine you'd want, given no items have been added to the cart upon receiving a request to checkout it will respond with some other type of response (empty cart? error?)
The provider will need to implement the provider state hook for an item has been added to the cart in the verification code, which will add the item to the cart by inserting it directly into the datasource.

Related

Is it possible to suspend a flow such that it can be resumed with an RPC-call?

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.

Symfony2 invalid form still saves entity on flush

I currently have a form and on save I always make an API call to validate the form information against an external source (eg: is the company a VAT paying company etc.). I also want to store in the database the response I get from the external API, for which I have a post submit subscriber on the form.
In the subscriber, I call the API and set errors on the form where values do not match. That is where I call a service to handle all the business logic and somewhere in there I have
$em->persist($apiResponse);
$em->flush();
to hold onto the API response.
This ends up saving the entity values attached to the form (company) in the database even though these values are actually invalid and the user is returned to the form page saying that.
Please note this happens on edit, and I understand why it happens, because the entity is managed by Doctrine.
I also tried flushing only the entity I am interested in:
$em->persist($apiResponse);
$em->flush($apiResponse);
and this seems to work, but I read this can have an unexpected behavior.
Hence, my question is: what are the solutions for this ?
Thank you, and sorry for the lack of code samples!

Adding correlation id to automatically generated telemetry with App Insights

I'm very new to Application Insights, and I'm thinking of using it for a set of services I plan on implementing with asp.net webapi. I was able to get the basic telemetry up and running very easily (right-clicking on a project on VS, Add Application Insights), but then I hit a block. I plan to have a correlation id set in the request headers for calls to downstream services, and I would like to tag all the telemetry related to one outside call with the same correlation id.
So far I've found that there is a way to configure a TelemetryInitializer, but if I understood correctly, this is run before I get to access the request, meaning I can't check if there is a correlation id that I should attach.
So I guess there might be 2 ways to solve this: 1) if I can somehow actually get access to the request headers before the initializer, that would obviously solver the problem, or 2) somehow get a hold of the TelemetryClient instance that is used to report the automatically generated telemetry.
Perhaps the last resort would be to turn off all of the automatic stuff and do all of it manually, when I could of course control what properties are set on the TelemetryClient. But this would be quite a lot more work, so I'd prefer to find some other solution.
You were rights saying that you should use TelemetryInitializer. All TelemetryInitializers are called when Track method is called on any telemetry item. Autogenerated request telemetry is "tracked" on request OnEnd, you should have all your custom headers available for you at that time.
Please also have a look at OperationId - this is part of the standard context managed by App Inisghts and is used exactly for the purpose of correlating requests with downstream execution. This is created and passed automatically, including traces (if you use trackTrace).
Moreover, we have built-in support in our UX for easily seeing all telemetry for a particular operation - it can be found in "Search->Details-->Related Items-->All telemetry for this operation"

What actions are considered to be idempotent in RESTfull scenarios?

Consider I want to develop a RESTfull WebApi for a Book Store. I'll have an Api to get a book info like: books/1.
I want to create a log whenever someone gets a book info. So, later I can produce a report of which book is seen more through the Api.
As in this scenario I'm getting some information it seems more appropriate to use GET. But as it changes some data, it could be a SET request.
Question: Does some changes like Logging effect on idempotent behavior of an action?
The general pattern is that a GET of a resource should not modify the resource in such a way that a subsequent GET of the same resource gets a different result.
Side-effects such as logging are not part of the data model, so are not generally considered to be related to whether the action is idempotent or not.

WF4 entity status handling, entities batch processing

I have created a simple order manager wf service (state machine) in WF4.
Order (EF entity) properties: Id, IsExport, NumOfProduct, ProductName, Status (waiting, approved, rejected).
State machine states:
1. OrderReceived (validation -> response activity)
2. Waiting (empty)
- Transitions:
update(update order activity) -> waiting state
approve(assign status field, update order and response activities) -> final state
3. Final state.
Correlation key: Order.Id
The implementation rised a few questions.
WF can manage one flow of the order instance, the order flow and the order entity is in one-one relation.
Question is that where and how should I implement the listing of entityes according to a state filter (eg. approved orders or waiting orders). The list should be accessible via WCF service method.
What is the best practise to manage the batch data processing. (eg: Multiple order approval. "Foreach" in the client is not the required sln.)
The state of the order is symbolized by the "state activity persisted instances" and the entity's status field in the db as well.
What is the best practise to decide the state of the entity, listing the active persisted activity instances in the defined state or select the entities from the db (by an activity) according to a state filter parameter?
Any help would be appreciated.
Good questions!
Taking your first and third questions, there are several possible approaches to this. All require that you write a custom WCF service to enumerate the required orders. This would probably not be a WF service; it might be a REST or OData service. How would you implement the service?
You could do it entirely by querying your database through EF. This would have no dependency on WF at all, and is probably the easiest way. Your workflow would update the database record on each state change, and the service would only need to read that value.
You could rely on the tracking mechanism provided by WF, and the extensions that Ron Jacobs refers to in his answer to your question. The tracking infrastructure is described here on MSDN. It is possible to use the tracking object in memory to get the state of active workflows. However, this probably won't work well with IIS/WF services, which are automatically persisted and unloaded when dormant. You would be better off using the tracking facilities to write state records to a database. Your custom service would then just query this tracking database.
Unless you want comprehensive information about the state changes and updates that have occurred through your WF service, suggestion number one should suffice.
As for your second question, that is a little more complicated. Let's say you write a REST service that lists the orders awaiting approval. You write a Web page that displays those orders, and the user can check the orders he wants to approve. Now, the number of workflows that you need to update is the same as the number of orders he approves.
You could, as you mention, call the Web service multiple times—but for a large number of orders that would be an unnecessary overhead.
What's the alternative? You would need to write a custom service method on your non-WF service that takes an array of order ids. That service would have to call your WF service multiple times to update each one. Since the WF service is being called from another service on the same machine, you can use the .Net Named Pipe binding instead of one of the HTTP bindings so that the overhead is much less.
It's worth noting that Entity Framework doesn't support batched updates either. You'd need to write a stored procedure or custom SQL if you wanted the database update to be batched too.
Is all of this worth the effort? Probably! Using WCF and the named pipes binding is pretty standard with WF. You'll need to configure Windows Activation Service for named pipes. Also, if you're not already using AppFabric for Windows Server, have a look into it, because it adds some very good management tools for WF services.
I recently published some new samples to show how you can access the current state of the StateMachine and possible transitions. These might help you.
Windows Workflow Foundation (WF4) - Tracking State Machine Workflow Service
Windows Workflow Foundation (WF4) - Tracking State Machine

Resources