Transformation routines finished

Posted by Philipp Liegl on July 2, 2010 in Uncategorized

News from the engine room:

We are happy to announce that the transformer for deriving Microsoft Windows Workflow artifacts from local choreographies is finished. We are currently integrating the transformation routines in the BSopt designer.

Self hosting workflows again with Workflow Foundation 4 Beta 1

Posted by mtopf on August 8, 2009 in Uncategorized

Hi, my name is Mario and one of my responsibilities in the Bsopt project is to generate workflows out of a global choreography handed down to me from other layers of the system. Just recently Microsoft has released the first public beta of the upcoming Dot Net Framework 4 and one of the many new features in it is the reintroduction of the Windows Workflow Foundation (”WF”) which basically is a complete rewrite residing in new dedicated assemblies and namespaces. Of course I had a look into the new technology and into the possibilities for our project! This post will be about a very specific problem you might face when creating applications with “self hosted workflows” – executables which are listening on one or more endpoints for incoming messages and might create new workflow instances for specific messages received. Self hosting a workflow by itself is quite a straightforward task as the creators of the Dot Net Framework 3.5 started including a WorkflowServiceHost class to manage all the gritty details for you. Be aware though: Workflow Foundation Versions 3.5 and 4 each got their own WorkflowServiceHost class which must not be confused with each other:

class WorkflowServiceHost

WF 3.5

WF 4





System.WorkflowServices (in System.WorkflowServices.dll)

System.ServiceModel.Activities (in System.ServiceModel.Activities.dll)

In both versions the code for self hosting workflows which will be created when receiving an incoming message is straight forward:

using (WorkflowServiceHost sh = new
WriteLine(ConsoleColor.Cyan, “Now selfhosting a workflow service. Press enter to quit.”);

There might be occasions when this approach is not enough though. The above code example would only work if the workflow used here would start with a Receive activity. If workflows need to do something else before listening for incoming messages we have to start instances ourselves. In WF 3.5 it was done this way:

AutoResetEvent are = new

using (WorkflowServiceHost sh = new
WorkflowRuntimeBehavior wfBehavior = sh.Description.Behaviors.Find<System.ServiceModel.Description.WorkflowRuntimeBehavior>();
WorkflowRuntime runtime = wfBehavior.WorkflowRuntime;
WorkflowInstance instance = runtime.CreateWorkflow(workflowType);
runtime.WorkflowCompleted += (sender, e) => { WriteLine(ConsoleColor.Cyan, “Workflow completed.”);are.Set();};
runtime.WorkflowAborted += (sender, e) => { WriteLine(ConsoleColor.Red, “Workflow aborted.”); are.Set(); };
WriteLine(ConsoleColor.Cyan, “Now hosting sender service.”);

The WorkflowServiceHost itself was not exposing the WorkflowRuntime class. Fortunately we were able to retrieve a WorkflowRuntimeBehavior instance from the service host’s Description property. Using this instance we were able to retrieve the actual WorkflowRuntime used by the service host and finally create and start a new WorkflowInstance for our workflow. Note that this is also a nice way to manipulate the services exposed by the WorkflowRuntime but it can also be done declaratively. So with WF4 and its dedicated WorkflowServiceHost can we do just the same? Unfortunately it’s not that easy. The problem is, that in Workflow Foundation 4 there no longer is a central runtime instance and we’re not given any workflow runtime behavior. Thus for quite some time I didn’t know how to reproduce the WF 3.5 behavior with WF 4. Then when reading through the very recommended WF 4 Migration Guidance documents, especially the file “WF4 Workflow Services Guidance.docx” I noticed how to regain control again:

We use the notion of a control endpoint: a web service endpoint that we add to WorkflowServiceHost, which can control the execution of the underlying workflow instance. This is a regular endpoint that can receive messages from external callers, or can be called locally by the client itself. The following code snippet shows how this is done. The code relies on the IWorkflowControlService interface, which is available in the Conversations solution which accompanies this paper.

System.ServiceModel.Activities.WorkflowServiceHost host = new System.ServiceModel.Activities.WorkflowServiceHost( /* omitted for brevity */);

// Add control endpoint to start client WorkflowControlEndpoint localEndpoint = new WorkflowControlEndpoint(); host.AddServiceEndpoint(localEndpoint);

host.Open(); IWorkflowControlService client = new ChannelFactory<IWorkflowControlService>(localEndpoint.Binding, localEndpoint.Address).CreateChannel();


That’s it! The dedicated WorkflowControlEndpoint exposes functionality for us to create new workflows, run those and actually much more. Unfortunately the IWorkflowControlService interface is not publicly exposed in the Dot Net Framework and the Conversations solution has not - at time of this writing - been released to the public. Fortunately we’re not dependent on this source code as we can just generate this interface ourselves! As a Dot Net Reflector instance was opened at the time I was reading this I just looked at the WorkflowServiceHost class to see which functionality it was exposing.
Easy enough I found out that the default base URI for this endpoint is “net.local://workflowControlServiceEndpoint” and that the interface I was looking for basically was internal interface System.ServiceModel.Activities.IWorkflowControlServiceInternal. By copy pasting this data into my code I had just what I wanted and I finally was able to start self hosted workflows again in WF4!
Note that in my opinion the proper way to do this would be to declare the WorkflowControlEndpoint with a known local endpoint address, make sure to publish metadata for the exposed service and infer the interface e.g. using Visual Studio’s Add Service Reference functionality but I didn’t try this approach myself after what I got was working out.

To spare you the work of inferring the workflow control interface I’ll end my post by pasting the code for you to use in your own self hosted WF4 services!

[ServiceContract(Name = “IWorkflowControlService”, Namespace = “http://schemas.datacontract.org/2008/10/WorkflowServices”),




// Methods

[OperationContract(Name = “Abandon”)]

void Abandon(Guid instanceId, string reason);

[OperationContract(Name = “Abandon”, AsyncPattern = true)]

IAsyncResult BeginAbandon(Guid instanceId, string reason, AsyncCallback callback, object state);

[OperationContract(Name = “Cancel”, AsyncPattern = true)]

IAsyncResult BeginCancel(Guid instanceId, AsyncCallback callback, object state);

[OperationContract(Name = “Create”, AsyncPattern = true)]

IAsyncResult BeginCreate(IDictionary<string, object> inputs, AsyncCallback callback, object state);

[OperationContract(Name = “CreateWithInstanceId”, AsyncPattern = true)]

IAsyncResult BeginCreateWithInstanceId(IDictionary<string, object> inputs, Guid instanceId, AsyncCallback callback, object state);

[OperationContract(Name = “Run”, AsyncPattern = true)]

IAsyncResult BeginRun(Guid instanceId, AsyncCallback callback, object state);

[OperationContract(Name = “Suspend”, AsyncPattern = true)]

IAsyncResult BeginSuspend(Guid instanceId, string reason, AsyncCallback callback, object state);

[OperationContract(Name = “Terminate”, AsyncPattern = true)]

IAsyncResult BeginTerminate(Guid instanceId, string reason, AsyncCallback callback, object state);

[OperationContract(Name = “TransactedCancel”, AsyncPattern = true)]

IAsyncResult BeginTransactedCancel(Guid instanceId, AsyncCallback callback, object state);

[OperationContract(Name = “TransactedCreate”, AsyncPattern = true)]

IAsyncResult BeginTransactedCreate(IDictionary<string, object> inputs, AsyncCallback callback, object state);

[OperationContract(Name = “TransactedCreateWithInstanceId”, AsyncPattern = true)]

IAsyncResult BeginTransactedCreateWithInstanceId(IDictionary<string, object> inputs, Guid instanceId, AsyncCallback callback, object state);

[OperationContract(Name = “TransactedRun”, AsyncPattern = true)]

IAsyncResult BeginTransactedRun(Guid instanceId, AsyncCallback callback, object state);

[OperationContract(AsyncPattern = true, Name = “TransactedSuspend”)]

IAsyncResult BeginTransactedSuspend(Guid instanceId, string reason, AsyncCallback callback, object state);

[OperationContract(AsyncPattern = true, Name = “TransactedTerminate”)]

IAsyncResult BeginTransactedTerminate(Guid instanceId, string reason, AsyncCallback callback, object state);

[OperationContract(AsyncPattern = true, Name = “TransactedUnsuspend”)]

IAsyncResult BeginTransactedUnsuspend(Guid instanceId, AsyncCallback callback, object state);

[OperationContract(Name = “Unsuspend”, AsyncPattern = true)]

IAsyncResult BeginUnsuspend(Guid instanceId, AsyncCallback callback, object state);

[OperationContract(Name = “Cancel”)]

void Cancel(Guid instanceId);

[OperationContract(Name = “Create”)]

Guid Create(IDictionary<string, object> inputs);

[OperationContract(Name = “CreateWithInstanceId”)]

void CreateWithInstanceId(IDictionary<string, object> inputs, Guid instanceId);

void EndAbandon(IAsyncResult result);

void EndCancel(IAsyncResult result);

Guid EndCreate(IAsyncResult result);

void EndCreateWithInstanceId(IAsyncResult result);

void EndRun(IAsyncResult result);

void EndSuspend(IAsyncResult result);

void EndTerminate(IAsyncResult result);

void EndTransactedCancel(IAsyncResult result);

Guid EndTransactedCreate(IAsyncResult result);

void EndTransactedCreateWithInstanceId(IAsyncResult result);

void EndTransactedRun(IAsyncResult result);

void EndTransactedSuspend(IAsyncResult result);

void EndTransactedTerminate(IAsyncResult result);

void EndTransactedUnsuspend(IAsyncResult result);

void EndUnsuspend(IAsyncResult result);

[OperationContract(Name = “Run”)]

void Run(Guid instanceId);

[OperationContract(Name = “Suspend”)]

void Suspend(Guid instanceId, string reason);

[OperationContract(Name = “Terminate”)]

void Terminate(Guid instanceId, string reason);

[TransactionFlow(TransactionFlowOption.Allowed), OperationContract(Name = “TransactedCancel”)]

void TransactedCancel(Guid instanceId);

[TransactionFlow(TransactionFlowOption.Allowed), OperationContract(Name = “TransactedCreate”)]

Guid TransactedCreate(IDictionary<string, object> inputs);

[TransactionFlow(TransactionFlowOption.Allowed), OperationContract(Name = “TransactedCreateWithInstanceId”)]

void TransactedCreateWithInstanceId(IDictionary<string, object> inputs, Guid instanceId);

[OperationContract(Name = “TransactedRun”), TransactionFlow(TransactionFlowOption.Allowed)]

void TransactedRun(Guid instanceId);

[TransactionFlow(TransactionFlowOption.Allowed), OperationContract(Name = “TransactedSuspend”)]

void TransactedSuspend(Guid instanceId, string reason);

[OperationContract(Name = “TransactedTerminate”), TransactionFlow(TransactionFlowOption.Allowed)]

void TransactedTerminate(Guid instanceId, string reason);

[TransactionFlow(TransactionFlowOption.Allowed), OperationContract(Name = “TransactedUnsuspend”)]

void TransactedUnsuspend(Guid instanceId);

[OperationContract(Name = “Unsuspend”)]

void Unsuspend(Guid instanceId);


New master’s theses topics

Posted by Philipp Liegl on March 3, 2009 in Uncategorized

For students interested in writing their master’s thesis in the context of the BSopt project we have assembled a list of possible topcis.

Academic papers added

Posted by Philipp Liegl on August 24, 2008 in Uncategorized

New academic papers related to the research work conducted in the BSopt project have been added.

  • бизнес, бизнес идеи, бизнес планы
  • бизнес
  • бизнес идеи, идеи для бизнеса бизнес идеи, бизнес, идеи для бизнеса, идеи бизнеса бизнес-план, бизнес-планы работа дома, надомная работа, работа на дому работа дома, работа на дому, надомная работа