Using Global Configuration Values in XPATH

Novell Identity Manager has several kinds of variables. Local variables are what the name suggests, and have two levels of scoping, driver and policy. Driver scoping means the variable hangs around after definition for the duration of the event, throughout the policies in the driver. This is a new feature in Identity Manager 3.5 and higher. Policy scoping, the default if you do not say otherwise means that the variable remains only through the duration of this policy object.

Global Configuration Variables (GCV from now on) are used to store things at the driver or the driver set level and can be very powerful. This is very useful if you are developing in a lab tree, before promoting the solution to production and your tree layout is different in the lab. You can store the references to base containers you use in a GCV and when it is time to move to production, just change those values to the correct ones for the production environment.

I detailed some examples of how to do that in a two part article about GCV'izing the Active Directory driver, see the following articles for some examples:

To reference these variables, there is a local variable token, and Global configuration variable token in Argument Builder, but a lot of fields do not use Argument Builder to specify. For example, when testing the condition, Source DN, you could want to test if it is in the Subtree held in a variable.

In the example articles, I showed how to use the notation ~GCVName~ to represent a GCV in policy. For local variables the notation is $VariableName.

An additional place where the use of variables like this comes in handy, is within an XPATH expression.

For example, set a local variable CurrentDN to the current objects DN, say via the Source DN() token. Lets say that the value is TREE-NAME\ACME\US\USERS\JSMITH

Have a GCV called eDirActiveUsers that holds the value, ACME\US\USERS and you want to test if the Current DN is the subtree of the eDirActiveUsers container. Lets say you also have a eDirDisabledUsers GCV that holds the value ACME\US\DISABLED

Now if you were using a condition, and you selected Source DN or Destination DN condition tests, then Policy Builder would give you a couple of options. You could test if it was in the subtree, in the container, equal, not equal and so on. So not much advice I can offer here, as it is already built in.

But what if CurrentDN is not the DN of the object in the current document? Say you are using a Work Order driver, and a Work Order is created, and it references an object elsewhere in the tree. Now you need to know before you proceed, is that user in the Active or Disabled container.

Well Source DN and Destination DN condition tests in an IF token or the main tests for a rule only refer to the current object. You could have some fun and store the value of Destination DN in another variable, lets call it CurrentDestDN and then do a Set Operation destination DN to the value of CurrentDN (the DN of the object the Work Order is referencing). Now the destination DN of the current operation is the one you want to test. Therefore you can use an IF token to test if Destination DN is in the subtree of ~eDirActiveUsers~ or ~eDirDisabledUsers~ as the case may be. Do remember when you done to set operation destination DN back to the value you stored in the CurrentDestDN variable if that makes sense in what you are trying to accomplish.

Now that previous example is a pretty stupid way to do it, but should work. It turns out there is probably a much simpler approach using XPATH.

The more I use and watch other people use XPATH the more I learn. There are a couple of sites with some examples of XPATH (and to me something as complex, Regular Expressions) at:

XPATH has a function called contains(), which takes two strings, and returns true if the second string is contained within the first string.

For more XPATH functions, you can look at:

This is a nice reference, as I often find myself thinking, gee it would be nice to get the length of this string, but no DirXML Script tokens support it, check out the XPATH link above, and lookee here, there is an XPATH string-length("string") function.

Back to our example,

contains("I am Bob", "Bob") 

would return true. How does this help? Well XPATH in Identity Managers implementation also supports both classes of variables using $Local-Variable and ~GCVName~ notation.

So therefore

contains($CurrentDN, ~eDirActiveUsers~)

looks like it will work, right? Well it would except that the way Identity Manager handles a local variable versus a GCV is slightly different. Once you understand the difference it will be really easy to work with.

Global configuration values, when used in tokens are treated just like variables, and looked up each time you run across them in a rule. When I say look up, I mean retrieve from a list in memory, since a change to configuration of the driver, say changing a GCV but without restarting the driver will not cause it to take effect.

When you use the ~GCVName~ notation, something different happens. As the driver is started, it finds all instances of ~something~ and matches the 'something' part, then replaces it with the literal string stored in the GCV. Thus our line:

contains($CurrentDN, ~eDirActiveUsers~)

at run time will be interpreted as:


The $CurrentDN gets quotation marks because that is how variables are represented, but the GCV is a literal replacement of the string, so no quotes get added automatically.

Thus to make it actually work, we would need to use:

contains($CurrentDN, "~eDirActiveUsers~")

Then this would return true in our case, and you could react to that as appropriate.

Overall using a Global Configuration Value when you can for things that might change can be very powerful. I am a huge fan of using them.


How To-Best Practice
Comment List