In our current application we are trying to use WCF netMSMQBinding which needs an Operation Contract to be marked as One Way.
We are also trying to use Fitnesse as our test engine, In our test case we need to test the scenario end to end, which means that we can not use One Way Operations, because they will be returned as soon as the message is placed in queue and fitnesse will try to assert the results but in actual message may or may not have been processed yet. So if we use one way operations then we need to wait somehow till its execution is finished.
Approaches tried/Researching on ..
Change OperationDescription at time of hosting by reading
configuration, so that when Hosted in Fitnesse IsOneWay is False,
but in production IsOneWay is True and then user MSMQ binding only
in production and for testing use tcp or netnamedpipe.
We tried to create custom ServiceHost and change
OperationDescription before Service is opened, but in
OperationDescription class IsOneWay is read only property and by
looking at .Net Framework Code, it returns count of Messages. In my
opinion, i have to override CreateDescription operation of Service
Host and have to provide custom implementation. It seems
Create a Monitor Fixture in Fitnesse which would some-how wait till the message is
processed.
Approach 1: Create custom db table which stores MessageId and completed
status and at the end of each message processing enter the
record in that table. So now fitnesse fixture can just poll the
table and wait till the execution is done.
Approach 2: Somehow poll MSMQ and know when a message is processed. We are still
re-searching how to make it work.
Please suggest any pointers for current approaches or any new approach.
I suggest #2 is better. With #1, you're no longer testing the system as it will run in production. I assume you want to test for some business condition after the message is processed. Can you poll for this business condition to be true? I think this is a better approach than 2.1 or 2.2 where you are polling for a technical condition.
Related
I am working on integration tests for my project.
I have containerized RabbitMQ queue, containerized consumer of this queue (using MassTransit) and containerized API that this consumer calls during processing of the message.
My test pushes a message to the queue, it gets picked up by the consumer and here is where my problem comes in - is there a way to check when this consumer inside of container proccesed the message, from my test perspective?
For now I just used Thread.Sleep() for 10 seconds and run my assertions after that.
It works but, obviously, as the number of tests grow this is becoming tedious...
How about using the actual rabbitmq REST API for that? From an integration test, you could use basic authentication, and query the queue endpoint, e. g.
/api/queues/%2F/foo
to query the queue foo on the default virtual host / (url-encoded as %2F). This will give you back a JSON data structure with the same details that you can see via the UI (in fact the UI is using this API as well), like the below (heavily truncated).
{
"messages": 1,
"messages_ready": 1,
"messages_unacknowledged": 0
}
You can poll this endpoint until messages is equal to 0.
Here is how I eventually resolved this:
I didn't mention that I also have Seq server running as I didn't think it would be relevant in my case but turned out it was.
At the end of message consuming method I have put log that I have enriched with custom property that indicates that this log means that message has been processed. Then in my integration test I set Polly policy that asks Seq for this "processing finished" log (with correct message id of course) until it appears (or until set timeout). However, I feel like #Driedas answer is way simpler
Maybe this can help you
https://event-driven.io/en/testing_asynchronous_processes_with_a_little_help_from_dotnet_channels/
Allows for awaiting rabbitmq events from within the tests without doing thread.Sleep
I am trying to create a XAMLX service that I can fire and forget.
But how can I do something like that with a XAMLX? I have no access to the Contract Interface to add the [OneWay] attribute.
I thought that if I did something like
and put the response before the rest of the activities, the service would return at that point but it didn't. It returns only after the whole workflow is completed.
IS it possible to make the service return at that point and than continue with the processing. the other activities would not affect the returned value of the service.
Is it possible to create a fire and forget XAMLX service
Can I somehow make the client fire a normal service as oneWay, if the previous 2 points are not possible?
If you want one-way processing your Receive activity should not have any corresponding SendReply activity.
The reason the response isn't send immediately is the way the workflow scheduler works internally where it waits for the workflow to go idle. Nothing much you can do about the scheduler but if you add a Delay below the SendResponse with a duration of 1 millisecond.
As Ladislav said, remove the SendResponse and you get a one way message.
Not quite sure what you want with fire and forget. If you start a workflow service it will keep on running even if you don't send any more WCF requests to it. Even if it is long running or does other async work. No problems there.
I have a WCF Workflow Service (running on AppFabric) that accepts a Connect receive operation, and then move on to listen to a number of other operations.
When trying to break the workflow from my unit test, by invoking Connect twice, the service won't respond on my second request, but will wait until a timeout occurs.
I am expecting an error message such as this one:
How do I handle "Receive" calls being made out of order?
Operation 'AddQualification|{http://tempuri.org/}IZSalesFunnelService' on service instance with identifier '1984c927-402b-4fbb-acd4-edfe4f0d8fa4' cannot be performed at this time. Please ensure that the operations are performed in the correct order and that the binding in use provides ordered delivery guarantees
Note
The behaviour looks like in this question, but the current workflow does not use any delays.
I suspect you are still being bitten by the same issue as in the other question you are referring to. This is a bug in the workflow runtime scheduler.
I have a simple WCF need - basically clients running in isolation and a server so really client/server intially.
WCF helps us decouple the service layer and practise a SOA approach for scale.
All we are doing on the server (per call/multiple concurrency) is writing to a db and then performing some IO for another system which will have immediate use for - but this might change as (unknown) requirements build.
Speed: We need the service to be literally quick as possible: 1 second is OK - 2 is slow - and some errors need to be sent back immediately.
I was considering using server async patterns, queues (MSMQ), Azure, to allow the service method to queue and return quickly. NB However, some processing might be 'online' in the WCF service (db write) with an immediate return with response/error, others could be offline (IO). Disadvantage: This requires a means to callback the client if there is a show-stopper error and design and development scales accordingly.
i) Although WCF allows for the service I see the technology as providing an interprocess comm channel and perhaps the actual service operations should run in win services. Eg. WCF writes to a db which a long-running service polls and picks up. As the system gets bigger and bigger some operations may be genuine fire and forget long running - which complete or are needed hours after. We can take these out of the immediate loop. This is true decoupling even if it slows us down. A WCF method can't pass to a service unless it is calling another WCF service and can't call a windows service!
From an architectural viewpoint, is it OK to have some operations complete and return, and others pass to a true bus or service (by some mechanism)? Am I over-engineering this?
ii) As all the operations of db and IO will take say 1 or 2 seconds max I feel I might just call the service aysnc from the client and wait for it to return and then marshal back to the client UI. This is also simple. This might prove a wrong decision in the long run but having said that, all service layer ops would be in a seperate dll so that these could be called by another service for later scale. A method call could be marked as immediate or queue for processing, say.
Thoughts?
From an architectural viewpoint, is it
OK to have some operations complete
and return, and others pass to a true
bus or service (by some mechanism)? Am
I over-engineering this?
It is OK, all depends on detailed requirements.
Thought #1
Have operations return unique request ID and one operation that provides status by request ID.
Thought #2
Have operations return result if they are done within X number of seconds or request ID.
Few methods in my WCF service are quite time taking - Generating Reports and Sending E-mails.
According to current requirement, it is required so that Client application just submits the request and then do not wait for the whole process to complete. It will allow user to continue doing other operations in client applications instead of waiting for the whole process to finish.
I am in a doubt over which way to go:
AsyncPattern = true OR
IsOneWay=true
Please guide.
It can be both.
Generally I see no reason for WCF operation to not be asynchronous, other than developer being lazy.
You should not compare them, because they are not comparable.
In short, AsyncPattern=True performs asynchronous invocation, regardless of whether you're returning a value or not.
OneWay works only with void methods, and puts a lock on your thread waiting for the receiver to ack it received the message.
I know this is an old post, but IMO in your scenario you should be using IsOneWay on the basis that you don't care what the server result is. Depending on whether you need to eventually notify the client (e.g. of completion or failure of the server job) then you might also need to look at changing the interface to use SessionMode=required and then using a Duplex binding.
Even if you did want to use asynchronous 2-way communication because your client DID care about the result, there are different concepts:
AsyncPattern=true on the Server - you would do this in order to free up server resources, e.g. if the underlying resource (?SSRS for reporting, Mail API etc) supported asynchronous operations. But this would benefit the server, not the client.
On the client, you can always generate your service reference proxy with "Generate Asynchronous Operations" ticked - in which case your client won't block and the callback will be used when the operation is complete.