MIIS newbie was a bit quiet on a blog for some time but he is still around. Actually I think that right now it is ILM newbie as product name was changed.
In this tale I want to gather few comments on a best practices around building ILM extensions. What I mean by best practices? Sometimes it is very tempting to do something in ILM extension code or somebody starting adventure with ILM is looking for some ideas how to solve problem and plan attribute flow etc. In many cases people are coming to similar, but not necessary good conclusions which are leading to not stable or not predictable ILM implementations.
I saw examples of such in few cases and I saw even more questions regarding such cases so I think this is some kind of pattern which has its roots in scripting approach, experience with other systems etc. Most of such problems can be easily avoided if one will stick to few simple rules in ILM extensions approach. This is what I will refer in this note as "best practices".
Maybe this will not be something deep technical but I can see questions from user here and there which are around this so … lets our list begin.
1/ Call to external data sources from within the extension
We are building our solution, we have to plan provisioning \ deprovisioning logic, attributes flows, precedence etc. And all of this has to be based on content of connector space and metaverse. This might be a little tough and frustrating at the beginning and I will not be surprised if thought similar to this will came to somebody's mind: Dood .. this is so limited – maybe I will just make a call to external database or AD and I will check if this account or attribute exists. This will make my logic easier and I will not have to trouble with this whole CS and MV stuff.
At a first view this isn't something which looks bad. Call to some data source from .NET is fairly easy in most cases and I admit that it can make ILM design easier. For example if You want to determine unique CN for an AD object getting data from AD is simpler than building such based on metaverse data only. However this approach brakes IMO most basic rules of ILM design:
- synchronization should be independent from data sources. ILM introduces concept of connector space, which is vie on a data source, and whole synchronization logic should be built around data available in connector space and metaverse. If You miss these data … go and figure out how to get them there.
No to say that this might affect performance of whole solution. Calls to external data sources and in most cases establishing new connection to this data source is something which might be considered as a bit expensive operation which might affect whole synchronization process performance in a great way (I know about a case in which calling to AD controllers spread on the world caused that synchronization process took few days to accomplish).
Conclusion: Avoid doing external data source calls from Your MA and MV extensions. If You need data for Your logic – go and configure MA or build one, get these data into connector space and then into metaverse attribute. This is how it should be done.
2/ Attribute flow and MA execution order dependencies
Another thing which I can observer in peoples questions and some code examples is building synchronization logic with assumption regarding which attribute will be present and which MA import attribute flow will be triggered first during synchronization cycle.
This is completely wrong as Your synchronization logic should not rely on things like:
- attribute flow order: flow configuration in GUI does not mean that these flows will be executed in this order. You can't rely on this. I was involved into MIIS implementation troubleshooting in which I was not able to reproduce error and it still showed up from time to time. MA extension code analysis showed that there was assumption made in extension design phase which attribute will flow first and it was used in code. I wasn't lucky enough to catch the case in which it failed in tests, however it was failing from time to time in production.
- MA execution order: You can't assume and build Your design \ extensions with particular MA run profiles execution order and expect it to be error prone in this way. Somebody might change script and put MA run profiles calls in other order – what then? Build your logic based on attributes and fact if attribute is present or not.
- object export order: You can't rely in your design on particular object export order. For example you can't expect that if you will provision in single synchronization step both OU and user which resides in this OU You can't expect that OU will be exported to AD always before user will be exported there. If you want to have such kind of logic You have to build it on Your own in Your design.
- values order in multi valued attributes: last thing to mention here … if You want to have multi valued attribute values in particular order .. sort it on your own.
If You need to rely on some flow order for example there are technical possibilities in ILM which allows You to do this in controlled way:
- transaction properties: allows you to pass information within single synchronization process between different components and through flow (IAF -> MV -> EAF) elements. I'm not a big fan of using transaction property but this is something which can be used.
- contribution MA and contribution time: allows you to check which MA and when has contributed to this particular attribute.
If You have to do this, do this in controlled and smart way – don't make assumptions.
Conclusion: don't rely on events \ flows etc order, think about your design as about something which has to execute properly in all circumstances. No matter if somebody will run SQL MA or AD MA run profile first. Handle errors, check for attributes, check if something happened before You will proceed with 2'nd step.
3/ Full and delta synchronization assumptions in code
This one is simple – if Your attribute flow is being executed properly in full synchronization run profile it should also execute properly in delta synchronization run profile. Whole process and logic should be build in the way in which it will be independent from all environmental elements like MA execution order or type of synchronization.
Conclusion:if your run has for the same flow different results in different run profiles go and check if You haven't done some assumptions (see (2) ) which causes such behavior.
Personally I think that this list might be extended with few more points … but maybe in next post from this series.
ILM newbie over and out (for now).