lets make an advanced provisioning config that can set the removeSyncRowsAfterSecondsOutOfTarget at the provisioner level. Default to the grouper-loader property if not set on provisioner
When a group is unmarked as provisionable for a provisioner and was never actually provisioned to the target, its sync group row and associated sync membership rows were never cleaned up. The timeout-based cleanup required inTargetEnd to be non-null, but for groups that were never in the target, inTargetEnd is always null, so the cleanup condition was never satisfied. Over time this causes sync tables to accumulate stale rows, which degrades incremental provisioning performance (e.g. Harvard Okta provisioner taking 57 minutes for 3 inserts).
Changes:
- Removed the inTargetEnd != null guard from the timeout cleanup in fullSyncGroups, fullSyncMembers, and fullSyncMemberships in GrouperProvisioningSyncIntegration. The inner logic already handles null inTargetEnd gracefully by using max(inTargetEnd, provisionableEnd, lastUpdated) to determine the timeout start.
- Added a per-provisioner advanced config removeSyncRowsAfterSecondsOutOfTarget so individual provisioners can override the global timeout. Falls back to grouper.provisioning.removeSyncRowsAfterSecondsOutOfTarget (default 604800 seconds / 7 days).
- In filterByGroupNotProvisionable, skip groups that are not provisionable and not in the target, avoiding unnecessary sync membership queries that were the main cause of the performance degradation.