IDArchitect.NET

How to keep previous attribute value(s) in Metaverse

Sometimes it is useful to have previous value of some attribute. For example we may need id of previous user’s manager or the name of previous user’s department. I can imagine a lot of scenarios where it may be useful to know previous value of attribute.
In case you are building solution using FIM Portal you can quite easily react on attribute updates and prepare workflows which will use/keep previous value of some attribute. However if you use only FIM Synchronization, things are becoming more tricky. Information about previous value of attribute is available for a very short time. You can of course pass it to other flows using transaction properties but as well it will be available only during synchronization cycle when attribute is updated. Later on this information is not available.

Solution

The trick is to keep both values together in some dedicated MV attribute. For example let’s say we already have managerID attribute and we want to have previous value(s) of the attribute in managerIDHistory. The we will have following values in Metaverse.

Attribute Value
managerID 1234
managerIDHistory 1234;

When we change managers ID to 5678 situation will look like this:

Attribute Value
managerID 5678
managerIDHistory 5678;1234;

We can of course keep as well older values (whole history). However you have to be careful in that case about size of your attribute and frequency of changes. In case you will keep older values as well this is how it can look after next update:

Attribute Value
managerID 1111
managerIDHistory 1111;5678;1234;

In any case if you split the list stored in managerIDHistory attribute on first position you have current value of managerID attribute, on second previous value, and so on …

Metaverse attribute type

What MV attribute type to use? In most cases you can expect that this attribute will grow a little after some time, so you will need some space. Indexed strings are limited to 448 characters which may be to short. Non-indexable string would be best choice in that case (it is stored in SQL as nvarchar(MAX)).
managerIDHistory attribute definition

Import flow example

In import flow you just add current value of the attribute at first position (in case it is not yet added there). Here is example of the code for advanced import flow rule:

case "cd.person:managerID->mv.nbpPerson:managerIDHistory":
{
if (csentry["managerID"].IsPresent)
{
if (!mventry["managerIDHistory"].IsPresent)
mventry["managerIDHistory"].StringValue = "";


if (!mventry["managerIDHistory"].StringValue.StartsWith(csentry["managerID"].StringValue + ";"))
mventry["managerIDHistory"].StringValue = csentry["managerID"].StringValue + ";" + mventry["managerIDHistory"].StringValue;
}
}
break;

Export flow example

Any of your export attribute flows can make use of the previous values of the attribute. First you have to read the value list with the code similar to following example:


if (mventry["managerIDHistory"].IsPresent &&
(mventry["managerIDHistory"].StringValue.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries).Length > 1) )
{
string[] hist = mventry["managerIDHistory"].StringValue.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries);
if (hist.Length > 0)
{
// use current value stored in hist[0]
}
if (hist.Length > 1)
{
// use previous value stored in hist[1]
}
}

Than you can do with it whatever you want …

Summary

Sometimes it is useful to have previous value of some attribute. You can easily achieve it within FIM Synchronization. Proposed method is good in case of some small attributes. It is useful in case you need this value during synchronization.
Extending solution – you can extend data format and keep more information, for example date and time of the attribute change.

Still this method will not be good in case you want to implement full history reporting.

Leave a Reply

Your email address will not be published. Required fields are marked *