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)).
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.
Hi Thanks for wonderful article .
I am looking for complete user attribute history store. how it can be achieved ?
Hi Shashidhar,
Provided solution is good in case for some technical or data flow logic reason you need attribute history.
In case you want to have full history there are following options:
– MIM Reporting – part of the MIM Portal (however it requires some additional infrastructure because it uses System Center to keep history data)
– build your own custom solution – separate SQL database with full history of attributes and have provisioning/data flow rules which will be updating that database (I’ve been preparing such solution for number of my customers).
Best Regards
Borys