Sunday, March 8, 2009

Thoughts on SharePoint Workflows

SharePoint workflows are a wonderful thing. Really.

I recently had my first opportunity to map a client's document generation and publishing process to SharePoint workflows. The client's overall process can be summarized as:
  1. Draft the document
  2. Submit the document for peer review
  3. When a peer review cycle is complete, incorporate changes and determine whether another peer review cycle is required. If so, repeat from #2.
  4. Submit the document for formal approval
  5. When the document is approved, generate a document number (i.e.: a serial number, etc.)
  6. When the document has been numbered, publish the document to a publically available location
  7. When the document has been published, notify interested parties (i.e.: an email subscription list, etc.)
The software developer in me immediately started salivating over developing a SharePoint State Machine workflow to handle this process.

Then I went to a Service Oriented Architecture (SOA) class. And it hit me. The document process I was working on gave me the perfect opportunity to leverage the SOA principles of high reusability and reduced complexity by breaking the workflow down into logical pieces (SOA business process layer kinds of things), then tying them all together with an overarching workflow (SOA orchestration layer kinds of things).

So here's what I did.

My idea was to have individual workflows for each major piece (review, approve, number, publish, notify), and have an orchestrator workflow that watches the states of the other workflows and fires off the "sub"-workflows as appropriate. Here's a high-level architecture:

In the internal document library

  • Custom Orchestrator workflow, automatically initiated on new item added to library
  • OOTB Feedback workflow, manually initiated
  • OOTB Approval workflow, manually initiated
  • Custom Document Number workflow, initiated by the Orchestrator when Approval's status is "Approved"
  • Custom Publish workflow, initiated by the Orchestrator when Document Number's status is "Completed"

In the external, published documents library

  • Custom Notification workflow, automatically initiated on new item added to the library

Details

First, I leveraged the SharePoint OOTB Feedback workflow to handle the peer review process. To make it easier on the drafters, I established a SharePoint group for peer reviewers and defaulted the feedback OOTB workflow to that group. Initiating the peer review process is a manual process, but it only requires two clicks to get it going. Big results; little work.

Next, I leveraged the SharePoint OOTB Approval workflow to handle the approval process. Again, I established a SharePoint group for approvers and defaulted the approval OOTB workflow to that group. Initiating the approval workflow is a manual process, but it only requires two clicks to get it going. Here again, big results; little work.

Third, I built a Document Number Generator sequential SharePoint workflow (source code available here). When initiated, this workflow generates the serial number for the document in the client's required format. By the way, the document library this workflow is tied to is an InfoPath Form Library. The InfoPath form has a document number field that is
  • read-only in the InfoPath form
  • promoted to the SharePoint library
  • and "write-back" enabled - the checkbox for "allow users to edit this field in property view" (or something like that) is checked, effective establishing 2-way data binding between the list and the InfoPath XML data stored in the library.

After I figured out I couldn't use the SharePoint Designer "copy document" workflow because the source and destination libraries are in different sites, I built a Publish Document sequential SharePoint workflow (source code available here). The publish workflow is initiated by the Orchestration workflow when the Document Numbering workflow's status is "Completed." The publish workflow simply copies a document, in this case, an InfoPath form, from one library to another.

I had hoped to leverage a SharePoint Designer "send email" workflow to notify a SharePoint group that a new document had been published, but it turns out it's a known issue that Designer workflows don't fire for "on new" when the new item is added with SPFileCollection.Add. Bummer. So I built another SharePoint sequential workflow to send an email message to the group (source code available here). The notification workflow isn't fired by the Orchestration workflow; rather, it's setup to fire whenever a new item is added to the "published documents" library.

Finally, I built the Orchestrator workflow - to tie everything together and "orchestrate" the various discombobulated pieces into a beautiful symphony (source code available here). The orchestrator workflow is set to initiate whenever a new document is added to the library. The orchestrator just sits around and waits for the Approval workflow to complete. When the Approval workflow is complete, the orchestrator initiates the Document Number workflow. When the Document Number workflow is complete, the orchestrator initiates the Publish Document workflow. It's a very simple and easy way to "daisy chain" workflows together, and it's the key to the overall approach.

So, what are the benefits of this kind of approach?

Well, first, each piece is a piece of individual functionality that operates independently from the others. The Document Generator, Document Publishing and Notification workflows know nothing about each other. That means they can be developed and tested independently.

Moreover, by abstracting certain configuration parameters into InfoPath workflow association forms (for the document number generator, the name of the field that holds the document number; for the publisher, the destination library), these workflows aren't tied to any one specific implementation, and are highly reusable across this and other solutions.

In short, this is a SOA-based approach, resulting in highly discrete modules of functionality that are less complex than the whole, are easier to build, and are highly reusable across multiple projects.