I recently had to make a change to one of out orchestrations on a BizTalk project. The change was that we needed to in a certain case suspend the long running orchestration and raise an event which would be handled by MOM. This would cause an alert to an administrator who would check out what we think could be a potential error condition.
When the administrator had checked everything was ok he/she would use the instance id to find the orchestration via the group hub and resume it.
This is straight forward enough but i also needed to amend the BizUnit tests to handle this condition.
I amended the tests to check for the event being logged, and I then made BizUnit simulate the corrective action with a custom step. The final step was to resume the orchestration.
Because I knew this would be the only functional test running I cheated a little and created a step that would resume all suspended orchestration instances for a given host. This would save me having to parse the event log message to find the instance id or having to listen for a WMI event being fired.
When I did the step to resume the orchestration I experienced some strange and unexpected behaviour.
The first thing the step did was to use the WMI MSBTS_ServiceInstance class to iterate the service instances for a given host the next step was to use the MSBTS_HostQueue and call the ResumeServiceInstancesByID which should resume the instance.
When executed we found the following behaviour:
- The wmi method executed without errors
- The instance when viewed in the group hub was no longer suspended
- The instance seemed to stay in a dehydrated state we waited for upto 20 minutes and it didnt become active
- From the dehydrated state if we suspended then resumed manually through the group hub the instance would complete successfully
The fix was easy enough, basically I changed the resume orchestration call so it used the Microsoft.BizTalk.Operations dll rather than WMI. This worked fine and the code snippet is below.
BizTalkOperations ops = new BizTalkOperations();
CompletionStatus status = ops.ResumeInstance(instanceId);
Trace.WriteLine("Status = " + status.ToString());