Friday, September 28, 2007

Alfresco : Workflow Model (Setup & Features)

I am almost writing a Tutorial on Alfresco. What the heck !! so be it.
And if so, I should say that this would be the most interesting one so far. "The Workflow".
Alfresco folks call it the Advanced Workflow and the Wiki dedicated to this is WorkflowAdministration
The Wiki is simple and does a great job for anyone who wants to get started on Workflows. What follows is the trail of my experience with this feature and some cool features that get plugged along the way.

Scenario of the Workflow

The picture above represents the requirement or the business process that we will attempt to automate via the Advanced Workflow mechanism.
  1. There are 3 people involved in the workflow.
    1. Document Specialist: Who's responsibility is to upload a document, make sure it gets evaluated and store it. This person is also the owner of the document and its process.
    2. Pre-Filler: A person who fills in missing information in the document based on image data.
    3. Evaluator: An expert in the field, who gives the approval for the completeness of the document. This person can either reject the document and send it back to the Specialist for additional information or approve it for storage.
  2. In a workflow, People can be assigned to tasks based on Swimlanes. The easiest way to understand swimlanes is to take it to its literal meaning, where swimmers in a pool will swim only in their lanes and all will pick up all the tasks in their lane alone. People can be directly assigned to a swimlane (one person per swimlane) or can be assigned via a group. In the case of a group, once one member in the group decides to take on the task, that person will be the owner from there on.
  3. The call-outs in the diagram above represents the 'cool stuff'. Sending notifications, Automatically assigning people to tasks, Automatically timing tasks, Copying content from one Space to the other etc.
  4. Besides that the workflow is simple to understand for most "Developers" and "Analysts" so I won't elaborate on the above diagram anymore.
Configuration
This is very similar to the configuration in the Content Model blog. The files involved are typically .XML files in the alfresco/tomcat/shared/classes/alfresco/extension folder (Henceforth referred as just extensions). 'xyz' below in my examples is 'credential'.
  1. xyz_workflowModel.xml : The file which will contain the Task Model of the workflow. In here we will define the tasks that are executed in our workflow. Much similar to defining a Content Type, the tasks have attributes (properties). And can have an inheritance model. (Which is what I like the most). Consider this to be the M in the MVC architecture.
  2. xyz_processDefinition.xml : This file defines the actual flow of tasks and responsibilities of people performing the tasks. It also defines a significant amount of Business Logic if required (in my opinion...it's almost always required). The Business Logic is mostly represented in either BeanShell JavaScript or Alfresco JavaScript. Apart from the subtle differences between the 2, they are mostly similar, however beware of the assumptions you might make regarding System.outs and alert()s. Check the code in the file, you will understand what I mean. Consider this to be the C in the MVC architecture.
  3. web-client-config-custom.xml : Here it is again. This file is like the standard file in Alfresco that we might end up modifying if we need to show any of our custom stuff in the Alfresco's UI. Consider this to be the V in the MVC architecture. For our example, we define what will Alfresco show when its time to display the Task to the its Owner, which attributes will be shown to whom and so on.
  4. workflow-context.xml : This is the file that lets Alfresco know, which workflow Models and ProcessDefinitions it needs to pick up during start up. This is just like the custom-model-context.xml file used for Content Types. As a matter of fact, Alfresco includes a sample file in extensions. It uses the workflowDeployer spring bean to deploy process definitions to Alfresco's jBPM engine. Why and How does Alfresco pick up this file, you ask aye? (A: refer Repository Configuration) [ToDo: Find the setting for production env so that process definition versions are not made all the time].
  5. repository.properties : Now you really don't need to change this file unless you want to send emails. Since this example does use a feature which sends emails, We will have to modify this file as well. I took the liberty to change this file simply in the \tomcat\webapps\alfresco\WEB-INF\classes\alfresco (henceforth referred as WEB-INF) folder. Also I will leave this one by saying the properties that you need to change are the ones related to mail.host.
Features
A point to keep in mind before we begin is, the workflow carries a document of a particular content type. As discussed in my earlier post (Content Model). This helps drive one feature of interchanging workflow properties marked by '(wf)' to document properties and vice-versa.

We will start with the Inheritance Model. Thats were all Object Oriented Programming Developers want to start. In the xyz_workflowModel.xml...
  • Notice the ccswfcredential:startTask inherits from the generic bpm:startTask. It doesn't define and attributes because my intention is to just start-off the workflow (automatically) when the document is uploaded. The extraction of metadata can be done later. It has to have an assignee, which currently by default will be the person who started the workflow.
  • Now, ccswfcredential:workflowTask is a my generic Task object which defines the attributes (properties) of tasks in the workflow and is inherited from the parent bpm:workflowTask. ALL other tasks in the workflow then inturn inherit from this custom generic (but workflow specific) Task. The reason for this is that all my tasks are having the same document flowing thru the workflow, different people perform different activities on this document and pass on. The activities and actions are different for different tasks but not the base information. Hence this model of inheritance.
  • Notice, as explained above all other 'actual' workflow execution tasks are just inherited from ccswfcredential:workflowTask and don't have any other member attached to it. They will have different behavior though.
Almost all the cool features are in the xyz_processdefinition.xml file. Its here that we can put JavaScript to it's maximum use. Again, keep in mind the differences between the way bean shell scripting and Alfresco JS. They can be intermixed, which will get certain obvious mistakes very hard to debug.
  • First, you will see 3 swimlanes, the first is normal, the second has an assignee that gets it's value when a person selects an assignee on Alfresco's screen manually, the third is where we can assign to a specific person automatically.
  • BeanShell scripting is accomplished by having a <script tag> without the <action class tag; if you do include the <action class="org.alfresco.repo.workflow.jbpm.AlfrescoJavaScript"> then the following <script> tag will be interpreted by the AlfrescoJavaScript class and certain things like the System.out won't work.
  • taskInstance.setVariable("ccswfcredential_firstname","WFDefault"); Will set the firstname property of the workflow in that task to WFDefault. When execution is about to leave the task, jBPM will automatically transfer the task instance's values to the corresponding workflow properties.
  • bpm_package.children[0].properties["ccs:fname"] = "WFDefault"; Aah this is awesome, bpm_package is the container of the 'Content' in the workflow, in our case the document, all of them stored in an array, so if there are multiple documents attached to tasks, then they will be referenced by children[1], children[2] so on. Once you have that, you can refer to the properties of that document and assign values.
  • <timer name='AutoPreFill' duedate='3 minute' transition='Pre-Fill'> A timer task, starts upon the execution entering in the task, and will transition to the task Pre-Fill upon completion of 3 minutes. ain't that cool ?
  • var temp = bpm_package.children[0].properties["ccs:fname"];
    taskInstance.setVariable("ccswfcredential_firstname",temp);

    Get the value of a property from the Content, put it in the workflow's property.
  • var mail = actions.create("mail"); ... mail.execute(bpm_package); Sends an Email.
  • var documentfolder = bpm_package.children[0].parent;
    var destinationFolder = documentfolder.childByNamePath("Evaluated Licenses");
    bpm_package.children[0].copy(destinationFolder);

    Copies the attached document to a particular Space.
Notice that the scripts are relative to events under the <event> tag or/and are part of a <transition> tag (which is also a type of event), Thus introducing an event based business logic to the business process workflow.

I hope you find working with workflows interesting and enjoying, I know I have. As we keep exploring the possibilities, please do keep commenting this post as well, so that we all learn from each other's experiences...Feel Free to jot down your thoughts.

3 comments :

Edward said...

Hi, cool post.
May be you know, how can i create, deploy workflow(process definition and task model - jBPM) from API not from native Alfresco web UI?
This is possible?
Thanks and regards.

Jon Lao said...

This is a very useful article!!

I have one simple question. For the taskInstance.setVariable() method. How do you know there is a such method? I don't see it being documented anywhere on Alfresco.

gouja said...

Hi,
Thanks for the tuto
I am getting an Error:
org.alfresco.service.namespace.NamespaceException: Namespace prefix ccswfcredential is not mapped to a namespace URI

Powered by Blogger.