Workflow 4.0 Activity Designer

In this post i’m going to explain how to make a custom activity better visually. 
First of all I have a custom code activity called RequestManagerAction. It inherits from CodeActivity and overrides its Execute method. (I may do a post on code activities later).


The visual representation of code activity, by default, looks like this:

And by the end of this post it will look like this:

The first step is to create a new peoject for your activity designer. As we want to “design” RequestManagerAction I have created a new project called: RequestManagerActionDesignerLibrary. And inside this I add a new Activity Designer Item from the Workflow – installed templates called RequestManagerActionDesigner.xaml.



the initial view after opening RequestManagerActionDesigner.xaml is a split screen with the Xaml that represents the design in the bottom part of the screen and the actualy visual design in the top part.



In the bottom pane we can see the Xaml. First of all I want to set the Collapsible property to false as I don’t want my designer to be collapsible. 



The 2nd taks is to add an ArgumentToExpressionConverter to my Xaml. This defines the mapping between arguments and expressions and provides the functionality to convert between these objects. Typically, this converter is used declaratively when using an ExpressionTextBox in a custom activity designer.



The next thing I want to do it sort out my layout. As my custom activity has 3 properties:



The main aim of what we are doing here is to show ExpressionTextBoxes for all 3 of these.
I will add a grid of 2 columns and 3 rows for our properties.



You can see that inside this grid we have some (3) collapsed TextBlock sections. I will explain these now.


Each TextBlock is for a property.
The first TextBlock is for the ExpenseRequest property of our custom activity:

You can see the obvious items marked out in the above picture.Note that the position inside the grid defined above is set by the Grid.Row and Grid.Column indexes which are zero(0) based.
You can also see that our expression text box is bound to ModelItem.SubmitExpenseRequest.


SubmitExpenseRequest is a class in my Contracts project that is part of my domain model:



The ModelItem represents the activity that that the designer is currently editing. This object sits between the visual elements that present an activity to the developer and the in-memory representation of the activity.


You can now see that we are well on the way to building our custom design:


I will now go ahead and add the other 2 ExpressionTextBoxes and the relevant properties.



You will notice the little smiley icon in the top left of the designer. To add this, I added the following xaml:


Now I am ready to associate my designer with the actual code activity that is already part of my workflow. If you remember it currently looks like this:

First I will add a reference to the project that my code activity is part of:



Once its referenced we can add an attribute to the top of our codeActivity class (Don’t forget the System.ComponentModel import at the top!):



Once you have built the projects you will see the “RequestManagerAction” code activity in the toolbox. Drag this onto your workflow surface if it’s not already there and you will see that the look of the activity is not just a small yellow box any more. Nice!! 


This is obviously more useful as we don’t need to  use the properties pane to set the properties for our code activity, we can just type them straight into the workflow.

RuSs


Advertisements

Workflow 4.0 – Adding annotations to your workflow tracking profile

Lets say you have a workflow that is running on a DEV / TEST and LIVE server. Lets say, also for the sake of it, that we are using the same AppFabric database for all 3. (yes, this is not the best idea but to explain annotations it helps.)

So what we want to acheive is the show, in AppFabric monitoring, which server we are using. So the monitoring with show either:

  • ServerThatEmittedThis: DEV_Server
  • ServerThatEmittedThis: TEST_Server
  • ServerThatEmittedThis: LIVE_Server
Again, this example is useless in the real world but i’m sure by the end of this post you will be able to imagine some real world uses for this functionality.

So you can see that in my current tracking profile I have added an annotation of my DEV server as follows:

You can see in the pic. “ServerThatEmittedThis: DEV_Server” which will now show up in AppFabric monitoring.

So I will now run the workflow which is hosted in IIS / AppFabric. 

My workflow runs and is persisted into my persistence store. So I click on the Active or Idle Intance in my AppFabric dashboard:
Note I could also navigate to the annotated info if my workflow wasnt using a persistence store by Looking on the dashboard for the WCF Call History section and click on the link in the Completed Calls section.

Once I can see the instance I click to select view tracked events:
Once here, I can see all the events that my workflow has passed through. 
Note that I am using a custom tracking profile that emits less than some of the default profiles. My custom tracking profile named: ExpenseServiceTrackingProfile is shown in the first screen shot of a part of my web.config in this post.

As i placed my annotation in my web.config as a child node to the activityStateQuery named Screen Expense I know to expect to see my annotation in AppFabric at the point where my screen expense activity emitting its tracking record. 


As you can see from the above pic. I have clicked on the Screen expense item and at the bottom you can see a tab called “tracked variables” shown below:

So I know that the workflow (server) emitting this tracking record is from my dev server. 

Rubbish example, but  I hope you get the point.

R

AppFabric Hosting PowerShell Cmdlets

This seems to be the place for the AppFabric Hosting PowerShell Cmdlets:
http://msdn.microsoft.com/en-us/library/ee767662(v=WS.10).aspx


The following shows the current state of my AppFabric. It has nothing persisted.



I start a workflow that I know will persist to my persistence store:



I can then look back at my AppFabric dashboard and see that 1 workflow is persisted and active.

I can then open Windows PowerShell Modules. It calls this from the server menu behind the scenes:
%SystemRoot%\system32\WindowsPowerShell\v1.0\powershell.exe -NoExit -ImportSystemModules


Ok so it’s loaded. Now, just as a simple example we can query for all instances in the default persistence store.

We call “Get-ASAppServiceInstance“.


It returns all the info about my persisted workflow instance.


This is interesting as I have just noticed that I have an extra unnecessary service contract name, a spelling mistake and hence an extra bookmark.


Ok, so I went in, altered the service contract name to get rid of the extra IService ref as it should only have an  IExpenseService ref. I also renamed my bookmark from ManagerActionComplete to ManagerActionCompleted. Then I re-ran my workflow thinking all was ok.

An exception was thrown so obviously I just did something incorrectly.

I re-ran my Get-ASAppServiceInstance“. and saw the following information which of course is very obvious:

The exception is:
ExceptionMessage: A bookmark with the name ‘ManagerActionCompleted|{http://tempuri.org/}IExpenseService’ already exists.

Obviously I just named a bookmark in my workflow to the same name as another one.

I renamed ManagerActionCompleted to ManagerActionCompletedReminder as this bookmark gets resumed after a delay activity expiration time has elapsed.

So Get-ASAppServiceInstance” now shows:


We then wait for the delay time to expire and run Get-ASAppServiceInstance” again and we then see:


Ok so I set off to write myself an investigative blog into  Windows PowerShell Modules for AppFabric and this technology already showed me a couple of issues with my workflow. Nice!!

Again, look at this link for loads of other useful commands:

thanks
RuSs

Why does my workflow die when I add a TransactedReceiveActivity?

dzien dobry,


I dont know the answer to this one but hopefully I will be able to update this post when I find out. 


The issue is this:
When I add a TransactedReceiveScope to a fully functional, persisted workflow monitored by AppFabric the workflow throws an exception.


I have looked at the exception and my trace / log files and can’t find any useful information.


My Workflow looks like this:



And the error is this:



The error text is:
The execution of the InstancePersistenceCommand named {urn:schemas-microsoft-com:System.Activities.Persistence/command}LoadWorkflow was interrupted by an error.

And the stack trace is:
Server stack trace: 
   at System.ServiceModel.Channels.ServiceChannel.HandleReply(ProxyOperationRuntime operation, ProxyRpc& rpc)
   at System.ServiceModel.Channels.ServiceChannel.EndCall(String action, Object[] outs, IAsyncResult result)
   at System.ServiceModel.Channels.ServiceChannelProxy.InvokeEndService(IMethodCallMessage methodCall, ProxyOperationRuntime operation)
   at System.ServiceModel.Channels.ServiceChannelProxy.Invoke(IMessage message)

Exception rethrown at [0]: 
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at WindowsClient.ExpenseServiceRef.IExpenseService.EndGetData(IAsyncResult result)
   at WindowsClient.ExpenseServiceRef.ExpenseServiceClient.WindowsClient.ExpenseServiceRef.IExpenseService.EndGetData(IAsyncResult result) in C:\PROJECTS\TelerealTrillium.Expense.Workflow.Soln\TelerealTrillium.Expense.Workflow.Soln\WindowsClient\Service References\ExpenseServiceRef\Reference.cs:line 532
   at WindowsClient.ExpenseServiceRef.ExpenseServiceClient.EndGetData(IAsyncResult result) in C:\PROJECTS\TelerealTrillium.Expense.Workflow.Soln\TelerealTrillium.Expense.Workflow.Soln\WindowsClient\Service References\ExpenseServiceRef\Reference.cs:line 537
   at WindowsClient.Form1.OnStartCompleted(IAsyncResult asr) in C:\PROJECTS\TelerealTrillium.Expense.Workflow.Soln\TelerealTrillium.Expense.Workflow.Soln\WindowsClient\Form1.cs:line 93

Ill keep hunting for solution and will post back when I find it.


========================== Time passes =========================


Ok so I came back to this little issue after remembering about the MSDTC. 
I realized that my app. updates my persistence store AND my custom expense database inside the TransactedReceiveActivity. (I update my custom expense database using Entity Framework 4.0)


Now my connection strings for these 2 things are different obviously so I am trying to wrap a transaction around some activities that span 2 databases.




So what I did first was enable MSDTC on my local server that hosts my WCF Workflow 4.0.
It was like:

Now its like:
But that still didnt work. Although I did see a one off Transaction Aborted error which I can’t reproduce.
I then went to my remote SQL server that hosts my Persistence store and custom Expense database which is what I should have looked at first really.

I enabled the same open-ish security on the Sql box and it fixed everything!! 





thanks
RuSs

Resetting the AppFabric dashboard whilst in development iterations

Bonjour,


I have found a little bit of t-sql that cleans out the required sql tables that the AppFabric dashboard uses. I have not researched this much but it seems to do the job. 


It is very useful if you are doing constant development iterations and you don’t want loads of instances of your workflow clogging up the AppFabric dashboard.


The t-sql is this:

delete [dbo].[ASWfInstancesTable]
delete [dbo].[ASWfEventsTable]
delete [dbo].[ASWcfEventsTable]
delete [System.Activities.DurableInstancing].[KeysTable]
delete [System.Activities.DurableInstancing].[InstancesTable]

Probably not a god idea to rely on this in anything but a development context.

Please comment if you know any more on this.

thanks
RuSs

Workflow Tracking Profile Editor

Here is a great link on Dennis van der Stelt’s blog about info. about the workflow tracking profile editor. 
http://bloggingabout.net/blogs/dennis/archive/2010/06/08/workflow-tracking-profile-editor.aspx
This tool makes it easy to create a tracking profile. It allows you to load up a WF4 XAMLX file. It then shows the editor and you’re allowed to browse through all (composite) activities. After right-clicking an activity (with a blue circle on it) you can specify what you exactly want to track. It even knows everything about arguments and (scoped) variables so you can use checkboxes to turn them on or off.


Here are some screen shots:






So following on from my other post:
http://russellmccloy.blogspot.com/2010/10/workflow-40-sample-development.html


I will create a simple tracking profile for my workflow.


Currently my workflow is using a default tracking profile that is set by my root web.config:



You can see that it is using the “HealthMonitoring tracking Profile”which seems to be the default one. there are a few others to choose from and to configure these you:

  • right click on your WF in IIS and select “Manage WCF and WF services” and then “Configure…”
  • Click on Monitoring
  • then use the slider to choose what you require.





And you can see that in my web.config that is local to my service that I have no tracking profile:




So I will use the Workflow Tracking Profile Editor to point to my current workflow definition and add a tracking item.


For the purposes of this exercise I have added an int32 variable to my xamlx file called:
TempTrackingExpenseId



I then use an Assign activity to set the variable. I suppose I could track the expenseId that hangs of my custon ExpenseResponse object. I tried that before and I could not get anything to appear in appFabric. So for now i’ll just stick with a simple integer.



I then right click in the blue spot in the Workflow Tracking Profile Editor:


and select “track variables in this activities scope…”:
And for now ill just select every event type for my variable:

I then save my new tracking profile using the Workflow Tracking Profile Editor and insert the resulting Xml into the web.config of my xamlx service.


Now that I have done this I will fire up my workflow using a windows form client as mentioned in my earlier blog:


More on this later… still learning



You can see that I have set a break point on the assign activity that sets the TempTrackingExpenseId variable in my ExpenseService.xamlx workflow:



After I let the debugger run to the end I expect that I have 1 workflow active and persisted in the persistence store and therefore showing on the appFabric dashboard.



So if I click on the Active persisted WF instances I will see the workflow in question.


If I right click and select “view tracked events” I can see all the events / activities that have occurred in my workflow already. 

If I just scroll I may be able to find the event im looking for, and therefore the TempTrackingExpenseId. What if, however, there are hundreds of activities in my workflow?

I can use the query options to find the data I am looking for. So if a user calls me up and tells me that he is waiting on the approval of an expense and the Id of this expense is 116 then I can select:
Tracked workflow variables
Equals
Name: ‘TempTrackingExpenseId’; Value: ‘116’
as shown below:

The result would be as follows:


As you can see, Especially compared to workflow 3.5, this is and could be very useful in keeping up with where your workflows are at.

A great link about tracking:
That’s all for now.

RuSs

Workflow 4.0 – Hosting with AppFabric

Following on from my last post I will attempt to share with you, the steps I took to get my workflow hosted in AppFabric with Persistence and Monitoring enabled.(I will not talk about AppFabric’s caching abilities as I know nothing about these at this point!!)


Ok so from my first post which is here:
http://russellmccloy.blogspot.com/2010/10/workflow-40-sample-development.html

I outlines how I began with workflow 4.0 and a few of the issues I had. I eventually got to a point where I developed a workflow application that, in a very simple way, allowed for the approval of an expense.


what I will now try to talk about is getting that workflow and it’s parts hosted in AppFabric.


To start with, I created the workflow project as follows in this pic:

Workflow project creation
When you create a new WCF Workflow Service Application the settings default to using the visual Studio 2010 development server. If we want to use AppFabric we need to change the project so that it is hosted, first of all in IIS. The following picture shows this:
Visual Studio Project Properties
If you use the “Create Virtual Directory” button, then VS 2010 will, hopefully create the IIS vertual directory for you as shown here:
IIS virtual Directory
Right so we now have a Wcf service in IIS but it’s sort of useless unless we built our own monitoring and hosting tools. Remember that AppFabric gives you loads of stuff out of the box. It also manages hosting and will re-hydrate a workflow from the persistence store when a delay timer expires.

So now what we need to do is install AppFabric.

Once appFabric is installed you need to configure appFabric.



To configure AppFabric click on the following link:


You will get an explanation page:

then the connection setup page for your monitoring and persistence database:

Before you point to the database you will need to run the following scripts that are @:
C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\SQL\en:
SqlWorkflowInstanceStoreSchema.sql
and
SqlWorkflowInstanceStoreLogic.sql


the setup wont work with out these. I think they setup a basic persistence store and appFabric then adds additional functionality to it. Not sure right now.

After you run these 2 scripts successfully on the database of your choice. (You can use any SQL db with any name to store persistence and monitoring data) you can then continue with the AppFabric setup. You may get a warning about Sql agent not being detected as in a runnable state but I checked and mine was running so I think you can assume everything is still ok.



Following this you should get a success message. 


And then a final restart IIS message:

Note: I did not select to setup the caching part of AppFabric.

After this you need to configure the local details for your site / xamlx service hosting in IIS and AppFabric. The setup we have just done relates the overall global setting for our IIS / AppFabric server. We can get more granular at the site level:


Setup monitoring. Accept default as specified earlier and add some trace and message logging as shown in the following pics:



You may get an issue with net.pipe missing. You can add this in the sites advanced settings as shown below:


After this is done we can run our windows client in Visual Studio. The windows client submits expense requests to our workflow.


Before we do this please not that I have neglected to add the c:\MailboxExpenseApproval directory on my server.   This will enable us to see the workflow experience and error and “suspend” its self. Using AppFabric we will be able to add the directory  to the file system and “resume” the workflow. 


So here is the windows client



You can see that after submission we get an error:



It looks like an Smtp error because c:\MailboxExpenseApproval directory on the server is set as the pickupDirectory for sending mail. As it’s not there, we get an error which is good for us right now.


If we look in AppFabric we will see that the workflow is suspended:


We can then add the c:\MailboxExpenseApproval directory and then resume the workflow using AppFabric.Nice!! 


I have then build a web site that is hosted in the same IIS / appFabric as the xamlx service. The website is used to response the the Smtp emails that managers receive asking them to approve expenses. There are links in the emails to point to the approve / reject form:



Once approved the user will see this message:


The persisted instsance of the workflow will then complete and be automatically removed from the persistence store. (Note: you can set some config to keep completed persisted workflow instances if you prefer).

That’s all for now. Will add more later.

RuSs