Thursday, 19 April 2007

WWF - Persisting WorkFlow

Why Persist?
The workflow host, which could be anything from a console application to a full fledged service application like MOSS, is not expected to maintain the state of the workflow instance in memory all the time. This is simply to save server resources and make them available. This considers the fact that workflows could be running for days.

Persisting - The common path
To save/persist/dehydrate/stream/serialize (yes, all denote the same idea conceptually) workflows, you usually use a workflow persistence service object such as the SqlWorkflowPersistenceService. This object could either be consumed directly within your own hosting application codebase or set up via a config file.In either of the case, you could ask for an automatic save when the workflow is 'idle' using the UnloadOnIdle entry.

What needs to be noted here is that all objects used by our workflow should be serializable in order for the host to persist the workflow (and the related objects) OK. An exception is guaranteed otherwise.

When does the save happen?
The workflow runtime appears to persist the workflow on these scenarios ('persist points') :
Against an activity, when it gets completed. (Check out the PersistOnCloseAttribute declared against Activities.)
When the workflow is completed or idle (delays, event waits)
When the workflow is forcefully unloaded.

Writing Custom Persistence Layer

Overriding a few functions by descending from the WorkflowPersistenceService class makes it easy to write a custom persistence class. Further, this new class could be made active against the workflow via the config file. But, most of us should be happy with the out of box SqlWorkflowPersistenceService which does seem to do the job good.

Persistence under MOSS
MOSS as a host has its own persisting service which uses the SPWinOePersistenceService object by default. [haven't tried forcing a different persistence object via the config though]. Waiting for external actions which include delays, waiting for events to fire etc causes the workflow to be persisted/saved to DB. The workflow appears to be serialized to the WorkFlow table (check out the InstanceData column) in the Content DB for the site.

Wednesday, 18 April 2007

Sharepoint - Integrating MOSS+WWF+ASPX - Part 3

Exposing our WWF workflow to MOSS
There are two more bits we need to do in the WWF workflow application to make it available to MOSS. We need to declare the feature and the workflow xml.

MOSS introduced features for the developers to create site items/functionality which can later be linked with sharepoint collectons/sites. Within this XML file, you would also tell which XML would contain the feature specific details - in our case workflow.xml.

Describes stuff about our workflow to sharepoint, including name, description , id etc. This also defines the pages which would be used for workflow Instantiation, association and modification. We shall have a look at an example of Instantiation later in a different blog entry. Modification of workflow (say you would to add more reviewers) at runtime needs a few extra steps and this is when the modification page comes into effect.

Defining Custom Pages for Task Initiation
For ease, all of these three pages needs to derive from Microsoft.Sharepoint.WebControls.LayoutsPageBase with sharepoint master pages (~/_layouts/application.master) being used in the ASPX definition. MOSS provides a lot many master pages which give the consistent look and feel of standard MOSS pages. The content placeholders within the masterpages would need to be filled in by us to define the various entries for the page. Since the master pages would not be usually available at the developer machine, designing these pages is not the easiest of task. Did try copying the pages locally to my machine, but VS.NET does not want to pick these, no matter what.

What we would want to do within the initialisation page is to serialize all the user entered stuff and call a Web.Site.WorkflowManager.StartWorkflow with the serialized data. Its this data which the OnWorkFlowActivated event in the WWF workflow would contain (refer to part 2 of this series)

The important points to note here would be the layouts page, the master page , calls to sharepoint functions and the way the page data transfer data to WWF via MOSS.

We have on more VS.NET task remaining, which is creating the task updating page. This page would be used by users to approve/reject tasks. This works a bit different from the three pages listed above; exploits ContentTypes. Next Blog.

Thursday, 5 April 2007

Sharepoint - Integrating MOSS+WWF+ASPX - Part 2

Starting with SharePoint Workflow Project
Once you have the sharepoint extension installed, the default project based on these templates would have the OnWorkFlowActivated activity placed as the first activity in the workflow. When Sharepoint initiates our workflow, its this activity it calls as the first step - acting as the entry point into our workflow.

Data Sharing
Sharepoint shares data with the workflow using one of the following ways:
1.) Instance of SPWorkflowActivationProperties would anytime contain the workflow properties, the most important of which is the initiation data. Initiation data could basically be any custom string passed in while you start the workflow from sharepoint. If you happen to have a custom initiation page (we shall discuss later) which explicitly initiates the workflow within sharepoint, it could perhaps serialise a data class instance based on the form data which we could use via this activation property.

2.) Events - Each of the OnXX events against an activity have event properties passed applicable to the context.

3.) Activity Properties - Each activity have certain properties which map to a workflow property/variable, which you usually setup during design time.
eg:- CreateTask activity has got two properties TaskID, TaskProperty. If you refer to the same variable in a different activity property, (say CompleteTask.TaskID), you are effectively refering to the same task. Also, any data you set to these variables are also passed back to Sharepoint. What you acheive here is sharing/relating data items between activities and between workflow & sharepoint.

Nearly all activities have a correlation token which is an identifier for the workflow context. This is for sharepoint to understand the context in which the activity is working. Eg:- you would use the same correlation-token for the createtask, ontaskchanged, completetask activities to specify that all these are of the same workflow context.

Does sharepoint persist the workflow?
Ofcourse it does. There is no way sharepoint can remember workflows running for days (say the task may not have been looked yet by the user). In these special cases when sharepoint is explicitly waiting for an event (
during a while activity, during a delay activity etc), sharepoint automatically serializes the workflow. When the related event happens , sharepoint deserializes the workflow and returns control back to the workflow. At this point, its the correlation token which is used to relate the item in concern with the workflow context [eg:- identify the task context]

So to try out some basic stuff, add the basic activities - CreateTaskActivity and within a WhileActivity put the OnTaskChangedActivity and finally a CompletetaskActivity. If your property links and the correlation token is right, there is nothing more to be defined at the workflow definition designer.
To define what happens at each activity (some code finally):
At the CreateTask activity, setup values for the task property like who is the recipient, description, taskid etc.
At the whileactivity, check if the task has been completed - perhaps using a public variable which was inturn set at the OnTaskChanged activity.
And at the completetask, setup the task status to 'complete'.

Guess we are done defining the Workflow.

Next lets define the custom pages which we would use for initiation of the task and also relate these pages to the workflow. Please await for part 3 :)

Tuesday, 3 April 2007

Sharepoint - Integrating MOSS+WWF+ASPX - Part 1

MOSS 2007 brings out the capability to use workflows defined within WWF; though not in the very easiest of ways. The number of steps to perform this action is a bit extensive. Sharepoint by default does let you define simple workflows using the sharepoint designer, but you would definitely have to go via the WWF path if there are too many custom business actions which needs to be performed during the workflow. Think about it, you get the full flexibility of the C# language and the .NET library once you start using the WWF - two steps away from heaven

Stuff you would need to define the workflow
WWF extension to VS.NET - to get the workflow designer and basic workflow project templates.
Sharepoint 2007 SDK - to get the sharepoint workflow templates and activities.

Quickest intro to WWF
Activities interact in sequence (sequential workfow) or via a trigger/state change (state machine workflow) to complete the work-flow. Activities are the building blocks for the workflow; once the WWF extensions are installed, you get a good set of activities to work with - while,if-else,delay,code etc etc.

Custom activities could be defined by the user (check out System.Workflow.Activities) such that these could be plugged into the workflow. While defining workflow, its interesting to note that the workflow definition could be defined in an XML file (XOML file actually) very easily. Its the same XML definition which gets depicted as interconnected boxes in the designer.

Once you have your workflow defined, whats remaining is hosting the same - the easiest option to test a workflow would be to write a console application which initiates the runtime (System.Workflow.Runtime.WorkflowRuntime) and starts the workflow by creating an instance of the previously created workflow using a WorkflowRuntime.CreateWorkFlow. Simple? Try it out... :)

Workflow for Sharepoint using WWF
Once you have the sharepoint SDK installed, you get a two new project templates and custom activities specific to sharepoint like createtask, deletetask, onwtaskchanged etc. We shall use these items in the next session to create a sharepoint workflow and later integrate this workflow into sharepoint.

Until then.

Sharepoint BDC - Easy LOB Integration

MOSS 2007 brings out new capabilities in integrating third party data sources and line-of-business apps into the sharepoint environment. Once integrated, these data sources act 'quite' similar to the standard sources letting you apply the various sharepoint functions such as list, search etc.

There is no need to write complex custom handlers (nobody wants to write one - not recommended by the MOSS team either!) or IFilers, now with the introduction of Business Data Catalog - BDC

The idea is very simple - you could integrate any data source which has an adapter via the ADO.NET path or a webservice. Once you dig out the adapter,the only remaining step is to define the BDC. The BDC definition is an XML file conforming to the BDCMetaData.xsd schema. Tip - when you start with a new XML file using VS.NET 2005, go to the properties for this XML file and point the 'schema' to the BDCMetaData.xsd; this enables intellisense while editing the XML file.

Common items which you define in the BDC :
LobSystemInstance - This defines where the datasource is and the adapter to use for connection, think of it as the connection string you normally provide.

Entities - When you expose the data source, what you definitely need to tell MOSS is what items you need to make available from your datasouce. Say from the default SQL Server [pubs] DB, you might want to expose the employee items only. For each entity, you would need to define the properties (employee id, name etc) and the identifier (employee id) at the bare minimum.

Methods and Method Instances - This defines the actions you could perform against the entity. You would define the method defintion ; say by using an SQL command string with the parameters (parameter types could be .NET types, say System.Data.IDataReader, System.String etc).

Method instances is an interesting concept; the same procedure definition (a template) could have different roles (method instances) to play under different scenario. Method types define the role the method plays. Eg:- when you need to define a SpecificFinder and a Finder type, a single method template should suffice.

Some of the method types defined are quite smart; AccessChecker method type could be used to do a custom access filter of the items in MOSS just before it is shown to the user (say just before the search result is shown within MOSS). You could write stored procedures in the backend which tell MOSS whether the data needs to be shown to the specific user, then link it up as an AccessChecker in the BDC definition file. I think thats cool.

BDCMetaMan - A very handy tool where you define the connection, entities etc visually and the XML file is generated for you. The free version could be used as a draft for more hands on tweaking.

Check out BDC covered extensively at MSDN.

Survival tips for the 'common programmer'

Learn Learn
For the 'common programmer'[R.K Laxman - 'Common Man' variant], the importance of a good foundation in computer science and continuously upgrading your knowledge cannot be emphasised further. The reason for this post are the many interviews conducted over the past few days which have been very disappointing and a few talks with my colleagues.

In addition to computer science fundamentals, what definitely appear to be missing from the many software professionals is the passion to learn stuff, the desire to look into the details to know how things works

Your basic foundation, which should have at least covered computer architecture, OS fundamentals, Networking fundamentals, programming concepts and constructs
(for a more exhaustive list, check out the syllabus from any of the B.Tech or B.Sc Computer Science courses) seems to be missing.

Second, you need to be aware of whats around and happening in this field; now how would I do that ? Subscribe to postings via a good RSS reader - Google Reader is a good option. Nearly all websites support for RSS subscriptions. Most importantly, make sure you read through them periodically.

Information Overload ?
Now, while reading through the many stuff, how do you make sure its relevant to you ? There is no way anyone could read and understand each of the topic (that would take 25hrs daily... behind bars perhaps?). An easy option is to not go into the details of the implementation, but be aware of the concept; as in, know the fundas. Unless the posting itself is of an interesting nature and you want to go in deeper.

The same logic applies to newsgroup postings; subscribe to newsgroups which appear interesting, but be aware of what needs a closer read. The experts appear to 'read between the lines'; you could skip paragraphs and sentences to read through the article to get an overall idea. If it does appears interesting, go back and read all the lines.

Overall, just make sure you are updated - make the above two steps a habit :)

Look Further
Now, when you learn something new, make sure you delve a bit more deeper than the skin to understand the hows and whys. These two questions should clear a lot many doubts on why the stuff is there in the first place and how the stuff solves it.

eg:- Most of us appear to know that the foreach construct in C# lets you loop through each items in the collection (solves the 'why' part). All good. Now, how does it do it and how can I extend my System.Object descendant to be made usable within the foreach construct? Enter IEnumerable interface.

Another one - Threads in C# do let me run jobs in parallel ('why' part). Now how does the CLR manage user threads? Did you know that a thread need not be created at the OS level each time a /new Thread()/ is called ? Enter Thread pool managed by the CLR.

What needs to be stressed is the importance of going deeper into anything you learn by answering the above two questions each time.

All the best fellow programmers. Would like comments on how you guys learn and update yourself.