Stumbling Through

Join me as I stumble, bumble and fumble my way through some new developer technologies. We'll laugh, we'll cry, there may be a mouse tossed through a monitor, but in the end we will all hopefully learn something.
in

December 2007 - Posts

Stumbling Through: K2 Blackpearl (More Smart Objects Part I)

Since 'Smart Objects' are one of the key new features of K2 blackpearl over K2 2003, I've decided that I need to spend more time stumbling through them and their capabilities.  I'm still a little confused as to when, why and how to use them, my previous postings on smart objects exhibited only a very narrow scope of what they are used for and they were pretty straight-forward at that.  So here is my goal:  Every workflow that will be created for my current client will need to have the same sort of information attached to it that go beyond the normal process data; things like the current branch that the workflow belongs to would be a nice piece of information to have for reporting purposes.  I think a SmartObject would be suitable for that, a 'StandardInformation' smart object that gets attached to every workflow and gets the current branch from... well... somewhere I don't know, we'll probably just hard-code it at first just to prove out the concept.

Let's get started then, shall we?  I already have a K2 workflow Visual Studio project with a few processes, it doesn't matter what the processes do as long as they actually work, as the feature we are focusing on here is SmartObject integration.  Add a new SmartObject to the project and name it 'StandardInformation':

image

The SmartObject editor opens up in simple mode by default, with pre-populated CRUD methods which I guess we'll keep.  More importantly, though, is that we add some properties that define this object.  As mentioned earlier, we need a 'Branch' property, but every SmartObject definition must also have a key property and 'Branch' certainly does not fit the bill so we'll add an 'ID' property as well:

image

I hope to explore the 'Associations' and 'Additional Settings' menus in the future, but they are more advanced than what we are trying to accomplish with this SmartObject so we'll leave them alone for now.  Similarly, I should explore 'Advanced Mode' a little more, but there is nothing there that is necessary at this time, so add that to my ever-growing list of things to explore later.  For the time being, let's save off this SmartObject as-is and open up any old process to see how we can meld the two together.  I am going to use my 'Assign to Group' process which is a POC for assigning tasks to Active Directory groups and Workspace roles and allowing a single user to take ownership of said task via the 'Claim' action.  FYI, assigning tasks to Active Directory groups does not currently put a task on the worklist of every user within the group, this is a bug that will be resolved with Service Pack 1, due out by the end of the year or so:

image

Now, in staying true to the theme of this blog, I currently have no idea how to do what we are trying to do with the SmartObject... I see two SmartObject-centric options in Visual Studio - there is the 'SmartObject Event' available in the toolbox:

image

and the 'SmartObject Association' icon in the upper-right corner of the canvas:

image

Which to use, and when?  Well, let's just blunder on through and see what happens... we'll start with the 'SmartObject Event' by dragging it onto the canvas from the toolbox:

image

Right off the bat, the wizard's welcome screen tells us that we can use this wizard to 'call smart object methods' and 'bind process data to smart object method inputs'... sounds kind of like what we'd want to do.  Maybe we can use this wizard to call the 'Create' method of our smart object, and pass in the branch name from a process data field?  Sounds like a plan, lets cancel out of this wizard for now and add a process-level field called 'Branch' which will hard code to 'Chicago' for now:

image

Drag the SmartObject event out onto the canvas again and click 'Next' to begin the process.  The first dialog prompts us for the smart object method that will be called in this event.  We can use the object browser to drag out the 'Create' method of our standard information SmartObject:

image

Click 'Next' and it prompts us to specify values for the 'Create' method parameters.  We only want to specify a value for 'Branch', because 'ID' is an autonumber (it will be automatically generated) so click the 'Branch' property and then click 'Assign'.  Drag in our 'Branch' process level data field and click 'OK' to accept it:

image

Click 'Next' and it asks us to supply a data field for the 'ID' return value of the Create method... we don't really care about the ID, so just say 'Next' and 'Finish'.  Hook up the default activity with our SmartObject event somewhere in the workflow process so we can see if it works:

image

Deploy everything and start up this workflow via the Workspace.  So now how are we going to actually see the smart objects that have been created?  That is where the reports come into play... open up the workspace and go to the 'Reports Designer'.  Select the 'Reports' tab and then click 'Create Report'.  Name the report 'Test' and make it a simple Tabular Report:

image 

Click 'Next' and we are now presented with a huge array of data source categories to drill through.  What we want is to drill through the Workflow Reports, Workflow Solutions, [project name], [process name] categories and select the process instances.  After selecting the process, the right side of the screen will be populated with the possible data in that process.  Why don't we see our SmartObject in there?  Well, I think that is where that other SmartObject canvas tool comes into play... let's revisit our workflow, and click the 'SmartObject Association' tool in the upper right hand corner of the canvas:

image

What this wizard is asking us is what SmartObjects can be associated with this process and whether or not they should be created within the workflow and/or within reporting.  we definitely want to create the one for reporting, so it will show up in the data sources as expected when creating our reports.  Blow through this wizard, associating it with our smart object (shouldn't be any tough questions here) and re-deploy the process.  Get back into our report data sources, and this time we see the smart object as an option:

image

Notice that you see 'StandardInformation' out there twice in my screen shot... that is because I forgot I had been playing around with a SmartObject named 'StandardInformation' previously, and while I had deleted it from my project, there is no way to delete it from the blackpearl server (being a neat freak, I really really hate this).  I ended up creating another SmartObject named 'Standard Information' and re-associated everything to get it to work.  Anyway, get through the rest of the report wizard and make sure you include the 'branch' property somewhere in your report, to prove that it is getting out there correctly.  When you view your report, it should look something like this:

image

Despite the issues I had with the duplicate SmartObject, I think we've proved out our goals coming into this thing... Every workflow can be associated with that same SmartObject, allowing them all to have additional properties (Branch, in this case) associated with them for reporting purposes.  I believe that this is something that would not be possible in K2 2003 without some custom queries against the K2 database, which probably is not a very fun thing to do.  One weakness of K2 2003 that still exists in blackpearl is that these custom properties are still not available to display on the worklist web part.  That would be an extremely useful feature that to the best of my knowledge is not available without doing some custom coding.

Posted: Dec 05 2007, 02:33 PM by tbyrne | with no comments
Filed under:
Stumbling Through: K2 Blackpearl (Escalations Part I)

A key feature of workflows that needs to be implemented in any technical workflow solution is escalations, that is, redirecting a task to a different user or sending notifications to various system users if the task goes un-addressed for too long.  Today, I'd like to take a look at how the K2 blackpearl product handles escalations in the following scenario:

We will create a simple task, called 'Escalating task', and put it on a specific users task list.  If the task goes un-addressed after one minute, that owner of the task will be sent an e-mail reminder to address the task.  If the task goes un-addressed for five minutes, then it will be moved from the current work list to a different user's work list.

Let's get started by adding a new Process to a workflow project (see previous posts on blackpearl if you need more direction on how to do this).  Within this process, drag out a 'Default Client Event' wizard to the canvas.  We won't make this event actually do anything important, but the wizard requires an action of some sort so simply make it navigate to my company's home page at www.claritycon.com:

image

Click 'Next' and specify that we would NOT like notification of the event (don't want to get our escalation e-mails mixed up with notification e-mails).  Click 'Next' again and blow through the Action wizards and accept their default 'Task Completed' action recommendation, but do not create the line for this outcome (we aren't going to care what happens when the user closes this task, that isn't what we are testing here).

For the Destination User, specify someone that you can log in as to view their task list, just so we can be sure it is appearing as expected when we run this process.  Finish the wizard, and our client event will appear within a new activity on the canvas.  Within this activity, select the 'Activity Escalations' icon from the activity strip (it looks like a clock).  This brings us to the Activity Escalations dialog, where we can specify as many different escalations as this activity requires.  In our case, that will be two - the e-mail escalation and the redirect escalation.  Lets define the e-mail escalation first by clicking the 'Add' button:

image

Click 'Next' and specify that we want an 'e-mail' action template:

image

Now the process is asking us for specifics on when this escalation should take place.  We want it to happen one minute after the task has been assigned to the user, so select 'Escalate After' - 1 Minute:

image

Click 'Next' again and we are required to fill in some information about the e-mail we are sending out.  It doesn't really matter who it is from or what it says, as long as it is directed to the owner of this task.  That is accomplished by clicking the 'Destination User' as the recipient, which becomes available when you uncheck 'Specify'... or so I thought!  Why the heck can't we select 'Destination user'?  Bug!  Bug!  Bug!  I screamed in my head, but no, this is by design and I will explain why... by default, only one instance of an activity is created that is owned by the server, and various destination users simply get links to it from their respective work lists.  So telling it to send an e-mail to its 'destination user' is invalid at this point, because the task is technically global, and has no idea what destination users may be linking to it.  To change this behavior so that the activity is created for the actual destination user, we need to re-visit the 'Destination Rule' on the activity strip (looks like a cluster of three people).  After clicking the destination rule icon, immediately click 'Back' to get the welcome screen which allows us to run in advanced mode:

image

Click 'Next' after checking the advanced mode option and we are presented with a 'Destination Rule Options' screen... the default option here is 'Plan just once', which is not what we want.  We need to specify one of the options under the 'Plan per destination' section to create the activity for each destination.  I'm not yet sure what the difference is between the two options here, for our simple test I'm sure 'All at once' will be fine:

image

Click 'Next' and we get a custom dialog based on the selection we just made... in our case, it is asking for parameters on how to handle 'slots' (instances) of this activity.  Since we are assigning the activity to one (and only one) user at a time, these options don't really apply to us so we can accept the defaults:

image

Now we get to the 'Destination Sets' dialog, which provides further customization on specifying who will be receiving the activity.  Again, this is all overkill for our simple test, so just create one destination set named 'Default' and put our destination user into it:

image

Click 'Finish' and our activity is now setup to create specific instances for the destination users.  Now, let's get back into our e-mail escalation and we see that this time, Destination User is enabled:

image

Finish the wizard and our e-mail escalation is complete.  Now, lets create our redirect escalation by clicking 'Add' again on the Activity Escalations dialog:

image

Click 'Next' and this time, specify the 'Redirect' template:

image

Click 'Next' and specify that we want this to escalate after five minutes:

image

Click 'Next' and we need to now specify who to redirect the task to:

image

Click 'Finish' and then 'Finish' again to complete our escalation definitions.  Deploy this process, and start it up via workspace.  Visit the destination user's task list and notice the 'Escalating task':

image

After one minute, check the destination user's e-mail for the reminder.  After five minutes, refresh the task list and note that the task no longer appears:

image

Log in as the escalation destination user and see that their work list now has the task:

image

Posted: Dec 04 2007, 12:51 PM by tbyrne | with no comments
Filed under: