Sunday, January 20, 2013

Workflow Versioning - Part 2

Continue from the previous post Workflow Versioning - Part 1.

Today I want to share how to host workflow with multiple version in IIS/WAS by using Windows Service Host Factory.

First, create a workflow and name it as v1 and one more different workflow as v2. For example, in my case I name it as VersionWFv1 and VersionWFv2.


Note: this is a different way of creating multiple workflow version compare to my previous post for the part 1. In part 1, I sign the assembly WorkflowVersioning.Workflows.dll into 2 different version but same assembly name. If you had followed the part 1 and created the 2 assemblies with different version, it is difficult to host them in IIS as I read some article found from the google search that we need to do custom service routing to locate the correct version of workflow service. And I found one article in MSDN, in .net 4.5, we save all the hassle and it is now very easy to have different version of workflow running side by side.

Today, I create 2 workflow xaml (class) with different name to differentiate the version. I find that when we sign a same assembly name with different versions, it is also difficult to trace back previous implementation since we had compiled it into dll. In today part 2, I create new class base on an existing class with different name, it is easier to look back the previous implementation, and also we can rollback changes easily.

Back to the topic, how to host 2 different workflow version with Windows Service Host Factory?

We cannot use the original Windows Service Host Factory because the existing implementation does not support service versioning with config file, also the service name is set base on the class name by default. We need to extend it to support hosting same service name but is reference from different classes. For my case, I would like to host the 2 different workflow with the same service name call "VersionWF" (see below yellow highlight), but 2 different classes (blue highlight) which tell the version difference.

The following sample code is sourced from Serena. We need the following assembly reference to extend the Workflow Service Host Factory.
System.Activities
System.ServiceModel
System.ServiceModel.Activities
System.ServiceModel.Activation


public class CustomServiceHostFactory : WorkflowServiceHostFactory
{
    protected override WorkflowServiceHost CreateWorkflowServiceHost(Activity activity, Uri[] baseAddresses)
    {
        // Current workflow service.
        WorkflowService current = new WorkflowService
        {
            Name = "VersionWF",
            Body = new VersionWFv2(),
            DefinitionIdentity = new WorkflowIdentity
            {
                Name = "VersionWF v2",
                Version = new Version(2, 0, 0, 0)
            }
        };

        // Older version.
        WorkflowService version1 = new WorkflowService
        {
            Name = "VersionWF",
            Body = new VersionWFv1()
        };

        // Create WorkflowServiceHost
        WorkflowServiceHost host =
            new WorkflowServiceHost(current, baseAddresses);
        host.SupportedVersions.Add(version1);

        return host;
    }
}


Take note that the workflow service version 1 does not have DefinitionIdentity. If you already had an existing instance in the persistence store, you cannot define the definition identity for version 1 because you never define the definition identity in the first time, if you define it now, you would get an error.

Now, we use the extended service host factory by defining it in the config file. Below is my complete configuration:


<system.serviceModel>
  <serviceHostingEnvironment multipleSiteBindingsEnabled="true">
    <serviceActivations>
      <add factory="WorkflowVersioning.Hosts.CustomServiceHostFactory"
                       relativeAddress="./VersionWF.svc" service="WorkflowVersioning.Workflows.VersionWF"/>
         </serviceActivations>
  </serviceHostingEnvironment>
  <services>
    <service name="VersionWF"
    behaviorConfiguration="WorkflowServiceBehavior">

      <endpoint name="basicHttpWorkflowService"
          address=""
          binding="basicHttpBinding"
          contract="IService" />

      <endpoint address="mex" binding="mexHttpBinding" contract="IMetadataExchange" />

    </service>
  </services>
  <behaviors>
    <serviceBehaviors>
      <behavior name="WorkflowServiceBehavior">
        <serviceMetadata httpGetEnabled="true" />
        <serviceDebug includeExceptionDetailInFaults="true" />
        <serviceTimeouts transactionTimeout="00:10:00"/>
        <serviceThrottling maxConcurrentCalls="1000000"
                            maxConcurrentInstances="1000000"
                            maxConcurrentSessions="1000000" />
        <sqlWorkflowInstanceStore connectionStringName="WorkflowInstanceStore"
          hostLockRenewalPeriod="00:00:30" runnableInstancesDetectionPeriod="00:00:05"
          instanceEncodingOption="GZip" instanceCompletionAction="DeleteNothing"
          instanceLockedExceptionAction="AggressiveRetry" />
        <dataContractSerializer maxItemsInObjectGraph="2147483647" />
      </behavior>
    </serviceBehaviors>
  </behaviors>
</system.serviceModel>


That's all about it. Here are the source if you wish to read more about it: MSDN






No comments:

Post a Comment

Send Transactional SMS with API

This post cover how to send transactional SMS using the Alibaba Cloud Short Message Service API. Transactional SMS usually come with One Tim...