I had noticed the Oracle EBS drivers get added to Designer a few patches ago, but never really had much of a chance to look at them. As I have been doing in my driver walkthrough series, I decided to do the Oracle eBusiness HR driver next.
In the first article I made it through the configuration, GCVs, and the started working through the Subscriber channel.
In this article I will finish the Matching policy in the Subscriber channel and onwards.
The Subscriber channel Match Policy set has three policies. I discussed the first on in the previous article.
Continuing on, to the second policy object.
This policy object has a single rule, "Employee entitlement: do not match existing accounts" that checks if it is a user, if the GCV enabling use of entitlements is true, and if the UserAccount entitlement is not available. This means you should be using Entitlements and are not, in which case you should not match. This is enforced by setting the operation property attempt-to-match to false.
In the previous rule, if the object was in the proper subtree, we set this value to false. You can see how you can layer on levels of decisions with different policy objects and by carefully ordering the policies/rules control the precedence.
The comment for the rule is useful. It notes that this is meant for users with entitlements to match existing users, which is just restating what the match policy set is meant to do. But it goes on to note that if you link IDV users to Oracle EBS HR records, deletes could flow through, which may not be desired. I.e. If you delete the user in the IDV that delete would flow to Oracle. Which is also basically true of every driver. That is why you use a policy in the Sub or Pub Event Transforms to handle those cases if they are not desired.
There are three rules in this policy object.
veto if 'attempt-to-match' is not 'true'
Matching Policy with person id
Matching Policy without person id
veto if 'attempt-to-match' is not 'true'
This is the rule that enforces the attempt-to-match operation property setting.
The conditions are if the operation property attempt-to-match is not available or is set to false, then Veto the event. It seems like a single test of not equal true would be a simpler test. But probably does not really matter. My guess is they started and the first match policy was if SourceDN in subtree, and if it is not, they do not even set the operation property, so the not available case. Then the Entitlement implementation policy sets the value to false. Thus they are testing for those two cases here.
Matching Policy with person id Matching Policy without person id
These two policies are basically the same thing, just two different approaches, and with an interesting comment in the rules. They wrote "This is a sample policy. Because we can't differentiate the employees record in Oracle E-Business Suite. For example, we can create many number of employees with the same 'firstname' and 'lastname' values. The only unique attribute is 'PERSON_ID' in EBS, but which will be generated automatically after the employee is created in EBS. Kindly customize as per your actual requirement."
If the DirXML-ebsPersonId is available in the source Identity Vault for this user, then try to match using that attribute. If it is not available, then the second rule tries to match by first and last name which is notoriously bad as matching criteria, which the comment calls out.
It is interesting to see a request to customize a rule delivered through a Package since that is actually not exactly the right way to do it. First you copy the package with the contents, customize that, and use it as your package instead of the NetIQ default package.
Regardless a better question is, why did they use DirXML-ebsPersonId, and not the more standard schema attribute workforceId or the older NSCP:employeeNumber attribute? While I appreciate the notion of using Schema to store data in appropriate places it seems like this is a case of going one step too far.
If I were to fix this, I would probably contemplate doing something like in the Input Transform, cloning the operation attribute DirXML-personID (or P_PERSON_ID since it is before the schema map) to workforceID. MIght as well keep the data in both sources. I would probably change this rule to match the DirXML-ebsPersonId, but using the data from Attribute WorkforceId instead.
That is it for the Matching policy set, on to the Create policy set. There is only one policy object here.
There is one rule, "User Create Policy" that tests for the User case, and if so, vetos if the DirXML-ebsGender attribute is not available. That is kind of interesting and I wonder why they did that.
It is almost as if to say they do not wish to ever create new users, and the gender attribute is almost never going to be set on non-existing EBS accounts. Maybe that was a simpler way of vetoing creates? I am not sure, but that seems a bit different than I would have expected.
That is it for the Create Policy set, and the Placement policy set is empty, since the target is a database exposed over SOAP so not a lot of structure to consider in placing a user. They go into a single table, not much needed to control that.
The Subscriber Command Transformation Policy Set is next and has two policy objects.
There is a single rule named "Employee entitlement change (Delete Option)" in this policy object.
We start with two GCVs being tested in the condition block. First drv.entitlement.Employee is tested for true, and second drv.entitlement.remove is tested if it is set to delete. Then test if a user, then a modify event (this part is important) and finally is the UserAccount entitlement is changing.
This is where a user getting the entitlement removed is handled normally. Which is what happens here, however something a little funny happens after that.
The first action is a loop over each Removed Entitlement "UserAccount", of course there should be only one, but note I said SHOULD, there is nothing preventing there being more than one. Worst case you loop once, better case, you handle all the values.
Also if you loop over the Added or Removed Entitlement tokens, and perform an action inside the loop, there is an implied use of the Implement Entitlement token. That is, when you perform an action to enact or implement an entitlement you were initially supposed to use the Implement Entitlement token which would then update the DirXML-EntitlementResult attribute. The token would add some XML that the engine would understand to update the DirXML-EntitlementResult attribute based on the final result of the event.
You can read more about Entitlements here and how all this stuff fits together here: Series: Talking about Entitlements(Ya, I got a bit wordy on the topic, but there turned out to be a fair amount to say)
All that is to say, the first loop is over the Remove case. We checked if the GCV drv.entitlement.remove to see if we delete the user in EBS when the entitlement is removed. (Say their roles changed and the Roles and Resource Service Driver (RRSD) went out and updated their Resources which removed some Entitlements). If we are in that case, then inside the loop we delete the destination object, and remove the association, but flagged as when="before". This way the users Association is cleaned up, the target object is removed, and all is good.
Initially when I read this I thought, this is not good, there is no handling of the Disable case. Generally, the setting for using Entitlement is a question between deleting or disabling the target user when the Entitlement is removed. But I went back to the GCV and checked and the second option is to "Do Nothing". I take that to mean there is no convenient way in Oracle EBS HR to disable a user. I admit to barely being able to spell EBS, as I know next to nothing about it. My guess is that either the database table or the SOAP interface has no way to disable a user. If anyone reading this knows EBS well enough to tell me how to disable a user in EBS HR, please post a comment, since I would be very curious to know! That got me distracted to go look up the WSDL for the Oracle EBS web service. I wonder if it is an option...
More interestingly, since as discussed earlier this has XSLT transforms buried in the shim, I wonder if I could send in raw SOAP constructed in Policy through the driver to handle this? That would be fun to try. Anyone have a EBS test system I could drop a package onto to test? I am mostly curious, since it sounds kind of fun.
Back to the Entitlement processing aspect, the third item inside the loop is a Break token. This has me wondering if this is a wise plan. Very often with entitlements you see multiple changes in one event. Most specifically the RRSD driver on a transition of entitlement state writes a remove of the old entitlement value (1 for granted, 0 for revoked, and absent for never granted so implicitly revoked), and then a second event adding the entitlement. I concede this rule will handle that properly, since the Removed Token is not as simple as a Removed Attribute token, and is smart enough to know that the removal of a DirXML-EntitlementRef of state = 0 (revoked) will NOT count as a Removed Entitlement.
But I was wondering about error cases, which seem like they happen with Entitlements too often, where there is more than one entitlement and possibly getting more than one removed, this would only handle the first case, Now to be fair as well, if there were two entitlements UserAccount being removed, (Legal, since the Path syntax has a string component and the XML in it could differ allowing two values for the same Entitlement referenced in the volume component) then probably a single delete would suffice. It is not like you could delete the user twice, I suppose. I do not have a specific error case I can enumerate where this would break, but I have this feeling that I am uncomfortable with it. I will have to ponder this one a bit more.
The next loop is actually more problematic. This one loops over Added Entitlement "UserAccount" which in principle is the right thing to do, and then inside the loop does an Add Destination Object for this user. The problem is that we are in the Command Transform, post Matching, post Create, and thus will not process the Match nor Create policy sets. Now Create is pretty weak here, but Matching is pretty important. We do not wish to duplicate existing users. We want to match if possible first.
The proper way to have done this would be to handle this in the Subscriber Event Transform, because if you 'synthesize' a <sync> event in XML before you complete the Event Transform, then engine will perform a real sync event, sort of like the engine had spit out the event itself. Then you properly progress through the normal set of policy sets.
Now I am not entirely sure of the wisdom of adding a user to the HR database from the IDV at all. Usually in the HR case it goes the other way. HR sends Users down the Publisher channel to be added to the Identity Vault, acting as the source of users. Perhaps the intent is to flag users via the Entitlement (coming from a Resource, coming from a Role) to link the accounts together, for perhaps existing users?
Thus this one has me concerned. Keep an eye on it. I would love to hear back if anyone has a good notion of what this specific option is all about. Feel free to leave a comment on the post if you happen to find out.
That about wraps up this article, stay tuned for more.