Novell Identity Manager Workflows – Combo Box Iteration

Over the years we have seen a number of workflows developed. Most were pretty straightforward. There was a request form, an approval form or two, and an entitlement/role/resource activity action before closing out the workflow. Every once in a while there might even have been an integration activity thrown in along the way to just make things interesting. But from time to time there is a requirement that users can select multiple items from a picklist and then the workflow has to perform separate actions for each item selected. This is a bit more challenging.

**NOTE: As with all Tips and Tricks we provide on the IDMWorks blog, use the following AT YOUR OWN RISK.  We do not guarantee this will work in your environment and make no warranties***

Identity Workflows…over the years we have seen a number of workflows developed.  Most were pretty straightforward.  There was a request form, an approval form or two, and an entitlement/role/resource activity action before closing out the workflow.  Every once in a while there might even have been an integration activity thrown in along the way to just make things interesting.  But from time to time there is a requirement that users can select multiple items from a picklist and then the workflow has to perform separate actions for each item selected.

This is a bit more challenging.

There isn’t a predefined activity in Designer to do anything remotely along the lines of a action based per item picklist.  As a result you must build this process manually.

So let’s take a look at how to do this in Novell IdM.

First the good news!  This is not an overly complex process but does have a few pieces to it as seen below:

  1. Determine where in the workflow you want to start this process and add a “Mapping” activity.
  2. Map the expression “flowdata.getObject(‘<fieldName>’).size()” to a new flowdata element.  This will be used to get our max count index or upper range.
    • flowdata.getObject(‘<fieldName>’)” will return all of the items selected in the specified field.*Side note: depending on your version of Designer the “getObject” method may not be obvious but it can be manually entered using the proper casing to achieve the desired results*

 

    • The “.size()” method will actually return the count of the items returned from the first part of the call so when put all together the “flowdata.getObject(‘<fieldName>’).size()” expression will return a count of only the selected items in the selected field.

 

 

    • In the same “Mapping” activity set a value of ‘0‘ (zero) to a new flowdata element.  This element will be used as the counter element to show how many iterations have been completed.

 

    • Next add a “Condition” activity.  This activity will compare the current counter value to the upper range to determine if another iteration is needed.  If the counter is less than the upper range (true) then continue iteration otherwise exit the loop to the next desired activity (false) .
        • Sample: “flowdata.get(‘Counter‘) < flowdata.get(‘UpperRange’)”

       

  1. Along the “true” path from the “Condition” activity add another “Mapping” activity.  Map the expression “flowdata.getObject(‘<fieldName>’).get((flowdata.get(‘<counterName>’))*1)” to a new flowdata element.  This will get the value of the selected item at the current counter index, or position.
    • Just like in the first mapping, the “flowdata.getObject(‘<fieldName>’)” expression will only return the selected values in the specified field.

 

    • The “.get()” method will allow you to specify a position, or index, in the array of values from the first method to return a single value from the list.

 

    • The “(flowdata.get(‘<counterName>’)*1)” expression will retrive the value of the current iteration count and multiply it by 1 to provide an integer value for the “.get()” method part of the expression.  This means that the string value of ‘0′ multiplied (*) by the integer of 1 will result in an integer of 0, which in an array of values means the first value.

 

 

    • Now that you have the selected value you can perform whatever action is needed.  Most commonly I have granted entitlements, roles, and/or resources based on the selected value using the proper activity for the version of IDM being used.
      *Side note: Pretty much all supported versions of IDM and Designer at the date of this blog’s publication have an entitlement activity.  With IDM 4.0 and Designer 4.0 there is a “Role Request” activity for granting and revoking roles but resources must be individually granted or revoked using the “Integration” activity and the User Application WSDL which has the necessary web methods to perform the desired action.  Now in IDM 4.0.1 and Designer 4.0.1 Novell added a “Resource Request” activity that is similar to the other activities which make it very easy to grant/revoke resources through a workflow.

 

    • After performing the desired action(s) it is time to increase the count.  To do this we need another “Mapping” activity.  In this activity map the expression “((flowdata.get(‘<counterName>’)*1)+1)+”” ” to the same flowdata element that was originally set to ‘0‘ back in Step 2, that way we keep the same flowdata variable name as our counter.

 

    • Connect the “Mapping” activity from Step 7 to the “Condition” activity from Step 4 to complete the iteration loop.  This means that with each iteration the counter will go up by a value of 1 and as long as that counter value is less than the value of the number of selected items this loop will occur.  Once those values are equal or the counter is somehow greater the loop will exit and the workflow will follow the “false” path laid out from the “Condition” activity.

And yes, you can add additional activities within the iteration loop.  It is very common to have various “Log” activities sprinkled through the loop outputting things like the current counter value, the current selected item value, etc.

“Um…I think there is a flaw in your logic.  If I have three items selected wouldn’t I need my counter to be greater than 3 and not equal to 3 before exiting the loop?” No! While the “.size()” method gives you count of 3, this is just the count of items selected but when you iterate through the item list the list is actually considered an array so the first item starts at position 0, not 1 like counting does.  This means that the selected values of a pick list are read like this:

  1. List Item 1 = Array Index 0
  2. List Item 2 = Array Index 1

  3. List Item 3 = Array Index 2

This means that as long as our index counter is less than our object count we can continue but once our counter is equal to or greater than our object count we need to stop.  If we had a count of three and tried to access Array Index 3 in the example above the workflow would encounter an error because no value of Array Index 3 will be found and the workflow would terminate.

So as you can see it isn’t a difficult process to do, it just requires some careful mapping and pathing to make sure things go where they need to go and in the proper order.

Questions, comments or concerns?  Feel free to reach out to us at IDMWorks.