0
Under review
Adapter data not mapping to locker during baseline sync
Adrian Corston 2 years ago
in UNIFYBroker/Plus
•
updated by Matthew Davis (Technical Product Manager) 3 weeks ago •
10
Some adapter field data isn't being updated in their locker entity when a baseline sync is run.
Screen snaps will be in a follow-up comment.
Customer support service by UserEcho
Yes, there is a second link/adapter which can contribute this data - there are two inbound paths, one for pending user data (Aurion Pending Employee > Employee) and one for current user data (Aurion Employee > Employee). There would have been a pending user data entity joined to the locker many months ago (before the user first started) but it has since been deleted since the user commenced work and moved to the adapter which isn't updating.
When I look at the pending user link (Aurion Pending Employee > Employee) I see a join on the locker's "Delete Join" screen, but no corresponding one on the adapter's screen. So I am guessing the locker join hasn't been cleaned up when the adapter entity was deleted, and the (higher priority) 'phantom join' is blocking the flow of data. What do you think?
That could be the case. A way to check - if possible - would be to delete that 'phantom join' (as long as you can see an appropriate join on the other link) and run another baseline sync to see if the correct data flows for that particular locker entity.
Can you share the join strategy that is being used in this environment? And do you know the normal flow of data for a user transitioning from pending to active? Would they exist in both adapters before the pending one disappears, or would the pending disappear before they're found in the active adapter?
All links are using the connection-oriented join strategy.
After deleting he locker-only join on the 'Aurion Pending Employee > Employee' link and running a baseline sync on the 'Aurion Pending Employee > Employee' link, the locker-only join on the 'Aurion Pending Employee > Employee' link is recreated and the field in the locker retains the old value from six months ago.
After deleting the locker-only join on the 'Aurion Pending Employee > Employee' link and running a baseline sync on the 'Aurion Employee > Employee' link, the locker-only join on the 'Aurion Pending Employee > Employee' link is recreated and the field in the locker retains the old value from six months ago.
I don't know if the 'pending' user record is deleted before or after the 'current' user record appears. I do know that current users who terminate remain in the 'current' adapter (with terminated details) and when they are rehired they reappear in the 'pending' adapter simultaneously, which is why the pending data is given priority.
Perfect, thanks. And can you confirm (just for posterities sake) the join criteria between 'Aurion Pending Employee' adapter and 'Employee' locker, and that there's no entity in the 'Aurion Pending Employee' adapter for the locker entity on that join criteria?
Aurion Pending Employee > Employee link join criteria is same, and there is no existing adapter entity matching the locker's join criteria on that link.
Hi Adrian
I've been looking into this issue and am documenting my findings here, as well as providing some options for moving forward. If you have any questions about this, feel free to ask.
Reproduction
This issue is easily and consistently reproducible. The process to follow to reproduce is
Quick Fix
The following query will update all locker origin information, removing priority calculation values for those that came from adapter entities that no longer exist. If this fix is to be used, please run the inner
SELECT
query first and verify that only the appropriate locker entity origin information will be updated.UPDATE "LockerOrigin" SET "SourcePartitionId" = null, "SourceEntityId" = null, "SourceField" = null WHERE "LockerOriginKey" IN ( SELECT lo."LockerOriginKey" FROM "LockerOrigin" as lo LEFT JOIN "Entity" as e ON lo."SourcePartitionId" = e."PartitionId" AND lo."SourceEntityId" = e."EntityId" WHERE lo."SourceEntityId" is not null AND e."EntityId" is null );
After running this command, run a baseline sync on the users link and the locker entity should be updated correctly. The origin information view in the UI will be empty any field that isn't updated with a different value to what it already had.
Full Fix
The full fix for this issue are updated versions of several PostgreSQL function. There are no changes required to the Broker binaries, and thus no patch dlls, however these changes should still be handled in the same way, as they are still modifying the logical processes of the application.
The following commands will update four functions so that origin information relating to removed source entities will not be considered in field priority calculations. Ensure that no synchronizations are in progress while running these commands; stopping Broker would be ideal. If rollback is needed, the original versions can be found in
<installDir>\Database\IdentityBroker Install PostgreSql.sql
.CREATE OR REPLACE FUNCTION public.get_entity_id_origins( entity_ids uuid[]) RETURNS SETOF "Origin" LANGUAGE 'plpgsql' COST 100 VOLATILE PARALLEL UNSAFE ROWS 1000 AS $BODY$ BEGIN RETURN QUERY ( SELECT o.* FROM "Origin" as o LEFT JOIN "LockerEntity" as le ON o."SourcePartitionId" = le."LockerPartitionId" AND o."SourceEntityId" = le."LockerEntityId" WHERE (o."SourceEntityId" is null or le."LockerEntityId" is not null) AND o."EntityId" = ANY(entity_ids) ); END; $BODY$; CREATE OR REPLACE FUNCTION public.get_entity_id_field_origins( entity_id uuid, field text) RETURNS SETOF "Origin" LANGUAGE 'plpgsql' COST 100 VOLATILE PARALLEL UNSAFE ROWS 1000 AS $BODY$ BEGIN RETURN QUERY ( SELECT o.* FROM "Origin" as o LEFT JOIN "LockerEntity" as le ON o."SourcePartitionId" = le."LockerPartitionId" AND o."SourceEntityId" = le."LockerEntityId" WHERE (o."SourceEntityId" is null or le."LockerEntityId" is not null) AND o."EntityId" = entity_id AND o."Field" = field ); END; $BODY$; CREATE OR REPLACE FUNCTION public.get_locker_entity_id_origins( entity_ids uuid[]) RETURNS SETOF "LockerOrigin" LANGUAGE 'plpgsql' COST 100 VOLATILE PARALLEL UNSAFE ROWS 1000 AS $BODY$ BEGIN RETURN QUERY ( SELECT lo.* FROM "LockerOrigin" as lo LEFT JOIN "Entity" as e ON lo."SourcePartitionId" = e."PartitionId" AND lo."SourceEntityId" = e."EntityId" WHERE (lo."SourceEntityId" is null OR e."EntityId" is not null) AND lo."EntityId" = ANY(entity_ids) ); END; $BODY$; CREATE OR REPLACE FUNCTION public.get_locker_entity_id_field_origins( entity_id uuid, field text) RETURNS SETOF "LockerOrigin" LANGUAGE 'plpgsql' COST 100 VOLATILE PARALLEL UNSAFE ROWS 1000 AS $BODY$ BEGIN RETURN QUERY ( SELECT lo.* FROM "LockerOrigin" as lo LEFT JOIN "Entity" as e ON lo."SourcePartitionId" = e."PartitionId" AND lo."SourceEntityId" = e."EntityId" WHERE (lo."SourceEntityId" is null OR e."EntityId" is not null) AND lo."EntityId" = entity_id AND lo."Field" = field ); END; $BODY$;
After running these commands, run a baseline sync on the users link and the locker entity should be updated correctly, and the issue should not reoccur. The origin information view in the UI will continue to display incorrectly for any field that isn't updated with a different value to what it already had. This is something we're aiming to improve in Broker v6.
Thanks Beau, nice work. I'll get it installed and tested and let you know how awesome you are :)
Hi Beau,
UNIFY Platform & Automation team applied the 'Full Fix' patch in my customer's DEV environment and when running the baseline sync the following error appears:
Sorry about that. My previous comment has been updated with the correct commands.
The new code runs in DEV and I validated correct data for a number of test users, but I don't have data in this environment which was showing the problem. I've requested deployment of the patch to PROD so it can be tested (there is no TEST environment for this customer).