Explaining GCVs - Part 2
Novell Identity Manager has a number of neat features, but one that I am quite the fan of are Global Configuration Values. They are so darn useful, and powerful in the course of your day to day Identity Manager development.
In fact if I had to say, my single biggest complaint with GCVs is that when developing to User Application, for Provisioning and Workflow has no easy way to reference GCVs defined in the Driver or Driver Set. Would be great to be able to share the data across both places, and require defining it just once.
I have written a number of articles on the topic already, that you can read for more background:
- Using Global Configuration Values in XPATH
- How to GCVize a Driver, Part 1: Subscriber Channel
- How to GCVize a Driver - Part 2
- Discussing GCV's in Comments field in Identity Manager
In part one (Explaining GCVs - Part 1) of this series, I discussed some of the basic types of GCV's, (string, integer, real, boolean, DN, and password-ref) and there are still three types left to discuss. The remaining three are List, Enum, and Structured.
There are a lot of ways to use GCVs. You might store a number of days before disabling inactive users in an integer GCV, and thus store the value 90. You might store the container that users should be placed in, as a DN GCV. You might store a XML document in a multiline string that you will later XML Parse to send to a JDBC driver or SOAP driver directly. (I hate XSLT! Much more fun doing it this way).
List GCVs are good, because when you use them in policy, you can treat them as a node set, and use a for each loop to loop through the list.
For example, you might want to exclude a series of say three containers, and in a policy rule (Probably the Event transform, in which ever channel) you could pretty easily add a rule that tested if the source DN is in a list of containers and then veto. In that case, the values are hard coded into the policy, and when inevitably they add a fourth container to exclude, you have to edit policy.
With a list GCV, you could add all three (and later the fourth) value, and then for each loop through the node set of the GCV, and veto if any of them match.
This becomes really helpful when you have a list of things you want to make available, but know it will probably change.
On the other hand, with the advent of Mapping tables, I find myself more partial to using a mapping table for this purpose. I would add an index column, where I would store an index value (like 1 then 2 then 3 and so on), and then use a while loop with a counter to check all the values in the mapping table.
The main reason I would do it this way, instead of with a list GCV is because a mapping table change takes affect on the next event that uses it, whereas a GCV would require a driver change. Also, with the Identity Manager 3.6 Map token, if no value is found, you can specify a default that is returned, so you can easily add an end condition for the While loop. I used this approach in these articles about load balancing the GroupWise driver for Post Office placement:
- Load Balancing User Placement in GroupWise Post Offices - Part 1
- Load Balancing User Placement in GroupWise Post Offices - Part 2
One other interesting way to use the List GCV type might be to handle DN syntax attributes. I recently was working on a SOAP driver, where the connected application had lots of reference attributes, where the equivalent of the object ID is the value stored in these reference attributes. In the eDirectory world, these are obvious maps to Distinguished Name (DN) attributes.
For a variety of reasons I decided not to transform the values of the object ID in the application to DN's for eDirectory in the Input and Output transforms, where they might more traditionally be handled. But I wanted to convert any attribute I had identified as DN syntax (and actually Time, and List syntax as well).
I was able with a list GCV to store the attribute names that were DN syntax, Time syntax, and List syntax, and then for each add/modify event, in the Command transform, loop through all the attributes in the document, and if this attribute was listed in one of the GCV's then process it.
This was a slightly different use case, since I wanted to compare the current attribute (XPATH of $current-node/@attr-name, if looping through the node set of attr, add-attr, or modify-attr so it was useful having a node set of values, taken from the list GCV. This makes it much easier to manage, without having to hard code a policy to handle each specific attribute on a one by one case.
Enum GCV's are fun. They are a prettier way to represent a set of choices. The nicest example I ran into that I like to use as a reference is in Lothar Haegers Password Notifier Driver (Specifically: IDM 3.5 Password Notification Service Driver Lothar's home page: http://www.brummelhook.com/dirxml.html).
The Password Notification Driver watches an eDirectory tree and based on GCV settings sends emails to users as their passwords get close to expiring. You can specify up to three notifications, any number of days in advance. Also as your account might be expiring, as you use up your grace logins, and as your account is locked and so on. It is a hugely useful tool, since users invariably do not notice or know their passwords are expiring. This way they have little to no excuse, if they get warned 14 days, 7 days, and one day out.
The reason this is relevant is that Lothar is based in Germany, on this silly continent that likes to write dates in formats that make no sense what so ever. (Just kidding of course, no doubt they feel the same way about silly North Americans. Personally being Canadian, I feel somewhat the same way about how Americans spell all sorts of words. More U's please!). But Lothar is a consultant (Go to his web page and hire him: http://www.brummelhook.com/dirxml.html) and needs this to be more generic, so he recognized the need for many possible date formatting strings.
He has a GCV that defines the date format. If you have used the Time or Convert Time tokens in Identity Manager, then you know what I am talking about. You can read more about these tokens at: http://www.novell.com/communities/node/2572/using-time-tokens-idm-35
I really like the tokens, since they allow you really easily build the date string via the UI, and then test along the way in Designer.
Now you could provide a GCV with the value dd-MM-yyyy hh:mm:ss to do 02-12-2010 11:13:26, or MMM dd, yyyy to generate dates in the format of February 12, 2010. But imagine leaving the user to type the format free hand as a value. That is not so pretty, as there is no interface in the GCV view to test or validate your pattern.
Lothar wanted to provide the more common patterns (for his silly world view only) and use an enumeration list to show the format in a pretty format to select, but underlying it, the selection provides the less pretty date format string.
This allows you to present complex choices, that would be hard to enter by hand. So Lothar provides some examples as you can see in the image, He has three or four common formats defined, shown as examples of how they would show up in the emails. But underlying the choice is the actual formatting string.
Thus when you need to add a silly localized date format string, you can modify the GCV, giving a pretty view for your ugly formatting string.
The XML for it is somewhat instructive:
<definition display-name="Notification Date/Time Display Format" name="DateTimeFormat" type="enum">
<description>To define custom date/time formats, see http://java.sun.com/j2se/1.4.2/docs/api/java/text/SimpleDateFormat.html for details</description>
<value>'am' dd.MM.yyyy 'um' HH:mm 'Uhr'</value>
<enum-choice display-name="Wednesday, 03.05.2005 18:35">EEEE, d.MM.yyyy HH:mm</enum-choice>
<enum-choice display-name="3.5.05 18:35">d.M.yy HH:mm</enum-choice>
<enum-choice display-name="am 21.12.1968 um 18:35 Uhr">'am' dd.MM.yyyy 'um' HH:mm 'Uhr'</enum-choice>
<enum-choice display-name="2005-05-03 16:35">yyyy-MM-dd h:mm</enum-choice>
You see a series of <enum-choice> nodes, where the display-name XML attribute defines the pretty name that appears in the selector, but the value of the node (Between the <enum-node> and </enum-node>), is the actual value the GCV will take if this choice is selected.
There is a <value> node that records the currently selected choice, with the underlying value stored and returned when used in Policy.
Thus if you wanted to add a new date format, you would add a new line, something like:
<enum-choice display-name="2010-02-12 Wednesday 16:35">yyyy-MM-dd EEEE h:mm</enum-choice>
The nice part is the UI will let you do it easily as well, so you do not even need to be concerned about the underlying XML. But it is nice to see the layout to better understand what is going on under the covers.
The second most common case I see of Enum types, is for a boolean style, but not limited to true or false, could be yes or no, mapped to true or false.
Structured GCV's are new to Identity Manager 3.6.1 and support is first added in Designer 3.5 I believe. The initial use case for them is in the SAP UM driver, which in the 3.6.1 release changed approaches. In SAP each module is a separate system, and can potentially have its own authentication store. I think the reasoning is based around the notion of allowing them to run independent of any other module, even though they greatly benefit when integrated together.
To make this sillier, SAP itself has a module called CUA, Central User Administration, to try and push users to the various modules you have installed, to make this easier. However, since it is SAP, there has to be a twist, which is that CUA does not push passwords, only other account info.
Thus in a typical IDM and SAP implementation, you could build one driver per module to sync users and passwords, or you could do a single full featured driver to CUA, and then stripped down simple drivers for passwords only, one per module. These drivers could basically be clones of each other, since all that would differ is connection information, making sure to point each one at the correct SAP module.
With IDM 3.6.1 Novell added a fan out capability to the SAP UM driver, so that you can continue to run in the previous mode or in a new approach, where one driver talks to many SAP modules. Which makes management of a single driver instead of potentially a dozen drivers a lot easier.
To manage that, they needed a way to store a number of config parameters, without having to define InstancePort1, InstancePort2, and matching InstanceIP1 and InstanceIP2. Enter Structured GCV's.
First you define the separators between values within each instance, and then between instances. Then you define a template that can consist of components made up of any of the available GCV types.
For example, in a SOAP driver, I needed to filter out certain attributes from any add or modify docs, that required approvals via a workflow. I made a structured GCV that had three components. A string, for the class name, a List for the list of attributes in that object class, and finally the DN of the workflow I needed to use in the call of Start Workflow. Kind of like how structured attribute syntaxes are available in eDirectory. (Path syntax is my favorite. A 32 bit Integer, perfect for time stamps, a DN and a string to hold whatever else you need).
These are still new to me, and I am still exploring possibilities with them. Like how to actually use them in Policy. In the case of the SAP driver, they read back the raw XML from the attribute of the Driver object that stores the GCV's. I was thinking of using the Split token based on the separator character between instances, to get a nodeset, then splitting the values inside it, by the within instance separator.
Other GCV Options:
There are some other options that there is no UI in Designer to add. Thus you have to edit the XML by hand to use these features. The good news is you can find examples.
My personal favorite to use these days in <header>. It makes the configuration look so much nicer when you add a nice header naming the section of the GCV's.
<header display-name="Whatever Your Header Should Say"/>
You can see this in many of the default driver configurations. This allows you to group a series of GCV's together, and even nicer allow you to collapse or expand them. They look something like this in XML:
Inside the <subordinates> node, list off all the GCV's that you want inside the grouping. The active-value attribute lets you control if it is expanded or collapsed based on the value of another attribute. There does not seem to be any explicit documentation on how to use this GCV option that I can find, but looking at examples in some drivers should make it reasonably clear.