Wednesday, May 4, 2011

Tip: How to make use of WorkflowControlClient to control workflows in a workflow service

If you host your WF service in IIS probably you will need a way to suspend, terminate, abandon, etc. a workflow that is running or persisted, other than using AppFabric Dashboard. In order to use WorkflowControlClient correctly, configuration at the workflow service is important. Given the following client code that terminates a workflow:

 WorkflowControlEndpoint endpoint = new WorkflowControlEndpoint()
{
Binding = new BasicHttpBinding(),
Address = new EndpointAddress("http://localhost/WorkflowService/AbsoluteDelayService.xamlx/wce")
};
WorkflowControlClient c = new WorkflowControlClient(endpoint);
if (!String.IsNullOrEmpty(TextBox2.Text))
{
c.Terminate(new Guid(TextBox2.Text));
c.Close();
}
based on the code above, the interesting part is the EndPointAddress that ends with the “wce” word. The “wce” word is actually configured in the workflow service web.config as shown below:
<system.serviceModel>
<serviceHostingEnvironment multipleSiteBindingsEnabled="false" />
<behaviors>
<serviceBehaviors>
<behavior name="behaviour2">
<serviceDebug includeExceptionDetailInFaults="true" />
<serviceMetadata httpGetEnabled="true" />
<sqlWorkflowInstanceStore connectionString="Data Source=(local)\SQL2008R2;Initial Catalog=PersistenceDatabase;Integrated Security=True;Asynchronous Processing=True;"
instanceEncodingOption="GZip" instanceCompletionAction="DeleteAll" instanceLockedExceptionAction="BasicRetry" runnableInstancesDetectionPeriod="00:00:05" hostLockRenewalPeriod="00:00:05" />
<workflowInstanceManagement authorizedWindowsGroup="AS_Administrators" />
<workflowUnhandledException action="Terminate" />
<workflowIdle timeToPersist="00:01:00" timeToUnload="00:00:00" />
<etwTracking profileName="Sample Tracking Profile" />
</behavior>
</serviceBehaviors>
</behaviors>
<bindings>
<basicHttpBinding>
<binding name="httpSecurityOff" closeTimeout="00:10:00"
openTimeout="00:10:00" receiveTimeout="00:10:00" sendTimeout="00:10:00"
allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
maxBufferSize="2147483647" maxBufferPoolSize="2147483647" maxReceivedMessageSize="2147483647"
messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered" useDefaultWebProxy="true">
<readerQuotas maxDepth="32" maxStringContentLength="2147483647" maxArrayLength="2147483647" maxBytesPerRead="2147483647" maxNameTableCharCount="2147483647" />
<security mode="None">
<transport clientCredentialType="None" proxyCredentialType="None" realm="" />
<message clientCredentialType="UserName" algorithmSuite="Default" />
</security>
</binding>
</basicHttpBinding>
</bindings>
<services>
<service name="MustMatchWithXamlxConfigurationName" behaviorConfiguration="behaviour2">
<endpoint address="mex" contract="IMetadataExchange" binding="mexHttpBinding" />
<endpoint address="wce" contract="System.ServiceModel.Activities.IWorkflowInstanceManagement" binding="basicHttpBinding" bindingConfiguration="httpSecurityOff" kind="workflowControlEndpoint" />
<endpoint address="" contract="IService" binding="basicHttpBinding" bindingConfiguration="httpSecurityOff" />
</service>
</services>
</system.serviceModel>

The configuration above shows how the service endpoints should be configured in order for client to access it through the WorkflowControlClient API. Another important thing that one must ensure is that the service name must be the same as the “ConfigurationName” in the Xamlx file.

Capture


If the name is not matching, WCF will throw exception stating the following message:



The message with To 'http://(macinename)/WorkflowService/AbsoluteDelayService.xamlx/wce cannot be processed at the receiver, due to an AddressFilter mismatch at the EndpointDispatcher. Check that the sender and receiver's EndpointAddresses agree.

3 comments:

Michael Goldobin said...

Thank you for the awesome post! It was a final piece in my puzzle. I put it all together here: http://lazyloading.blogspot.com/2011/05/controlling-workflows-with.html

Michael Bakker said...

Thanks a lot for your excellent post. It is the first of many posts, which clearly defines all actions needed to start using the WorkflowControlClient.
I must have saved me many more hours of fruitless attempts and searching the web.

Unknown said...

Thank You! I've spent about 12 hours attempting to solve this issue. I guess my googling was a bit off. I had started my workflow application by hosting outside of IIS. Then when I switched to running under IIS, and using a workflow service (xamlx) I didn't pay attention to the ConfigurationName detail. Very few of the workflowControlEndpoint samples actually use a service.