Class TrueFoundryProvisioningTargetNativeSync

java.lang.Object
edu.internet2.middleware.grouper.app.provisioning.GrouperProvisioningTargetNativeSync
edu.internet2.middleware.grouper.app.truefoundry.TrueFoundryProvisioningTargetNativeSync

public class TrueFoundryProvisioningTargetNativeSync extends GrouperProvisioningTargetNativeSync
TrueFoundry-specific GrouperProvisioningTargetNativeSync: builds native target reporting beans for sync-back to the generic grouper_prov_group / grouper_prov_user tables.

Both groups and users are captured from the raw TrueFoundry JSON (JSON Pointer paths, like SCIM / Adobe / Duo), hooked at the API-commands seam (TrueFoundryApiCommands read methods such as retrieveSubjectsData / retrieveUsers / retrieveUserByEmail for users and retrieveRoles / retrieveTeams / getTeamById for groups) where the per-object JSON node is in scope. This avoids losing any TrueFoundry field that the TrueFoundryUser / TrueFoundryGroup typed beans do not model; operators can capture any JSON field via nativeAttributesGroups / nativeAttributesEntities with a name and optional JSON-Pointer path.

The default keys are chosen so each default's captured value matches what the OLD typed-bean getter returned:

  • users: target id from /id (the same field TrueFoundryUser.fromJson reads into id / the old build read via getId()); defaults email (from /email) and active (from /active, a JSON boolean).
  • groups: target id from /id; defaults name and groupType.

TrueFoundry group nodes are not uniform, so the commands seam hands this class a normalized capture node rather than the raw API node (see TrueFoundryApiCommands.normalizeTeamJsonForCapture / normalizeRoleJsonForCapture). Two fields the typed beans synthesize have no single raw JSON field and so are injected onto that capture node before it reaches us:

  • groupType is not a TrueFoundry JSON field at all -- fromTeamJson / fromRoleJson hard-code it to "team" / "role". The seam stamps it on the capture node so the /groupType default resolves (matching the old getGroupType() value).
  • name lives at /teamName for a team but at /name for a role. The seam normalizes both into a top-level name field on the capture node so the /name default resolves uniformly (matching the old getName() value).
Every default / pointer is therefore relative to that normalized node, consistently. All other raw fields (e.g. teamName, resourceType, isDefault, the manifest subtree) are preserved verbatim on the capture node, so an operator can capture any of them -- including fields the typed beans never model -- via nativeAttributesGroups.

Memberships are still derived from the TrueFoundryGroup typed bean's members list during DAO translation (captureMembershipsFromGroup(edu.internet2.middleware.grouper.app.truefoundry.TrueFoundryGroup, java.util.Map<java.lang.String, java.lang.String>) and the ...UsingCapturedUsers variant), because TrueFoundry membership is group-centric and carried inside the team object (member emails translated to native user ids) -- the Adobe situation. Only the group/user object capture is JSON-based.

  • Constructor Details

    • TrueFoundryProvisioningTargetNativeSync

      public TrueFoundryProvisioningTargetNativeSync()
  • Method Details

    • getDefaultNativeAttributeConfigsEntities

      protected List<GrouperProvisioningNativeAttributeConfig> getDefaultNativeAttributeConfigsEntities()
      Description copied from class: GrouperProvisioningTargetNativeSync
      Per-protocol sensible-default attribute list for entities (users) when the operator hasn't configured nativeAttributesEntities. Override in protocol subclasses to return a curated list (e.g. SCIM core schema fields). Default is empty — for LDAP this means "no extra capture beyond what the regular target query returned," which is the historical behavior.
      Overrides:
      getDefaultNativeAttributeConfigsEntities in class GrouperProvisioningTargetNativeSync
    • getDefaultNativeAttributeConfigsGroups

      protected List<GrouperProvisioningNativeAttributeConfig> getDefaultNativeAttributeConfigsGroups()
      Description copied from class: GrouperProvisioningTargetNativeSync
      Per-protocol sensible-default attribute list for groups. See GrouperProvisioningTargetNativeSync.getDefaultNativeAttributeConfigsEntities().
      Overrides:
      getDefaultNativeAttributeConfigsGroups in class GrouperProvisioningTargetNativeSync
    • buildNativeGroupFromJson

      public GrouperProvisioningTargetNativeGroup buildNativeGroupFromJson(com.fasterxml.jackson.databind.JsonNode groupNode)
      Build a native group bean from the (normalized) raw TrueFoundry group JSON. targetId is read from /id (the same field the old typed-bean build read via getId()); the attributes map is populated for each entry in GrouperProvisioningTargetNativeSync.effectiveNativeAttributeConfigsGroups() (operator-configured or default) by JSON Pointer. Returns null when the JSON is missing or has no id.
      Parameters:
      groupNode - the normalized group capture node (see class javadoc); for teams/roles this is the raw API node with name and groupType stamped on
    • buildNativeUserFromJson

      public GrouperProvisioningTargetNativeUser buildNativeUserFromJson(com.fasterxml.jackson.databind.JsonNode userNode)
      Build a native user bean from the raw TrueFoundry user JSON. targetId is read from /id (the same field TrueFoundryUser.fromJson reads and the old build used via getId()); the attributes map is populated for each entry in GrouperProvisioningTargetNativeSync.effectiveNativeAttributeConfigsEntities() (operator-configured or default) by JSON Pointer. Returns null when the JSON is missing or has no id.
      Parameters:
      userNode - a user object as it appears inside the subjects users[] array
    • captureGroupJson

      public void captureGroupJson(com.fasterxml.jackson.databind.JsonNode groupNode)
      Build + record a TrueFoundry group from its (normalized) raw JSON. No-op when sync-back is off or the node is null / id-less.
    • captureUserJson

      public void captureUserJson(com.fasterxml.jackson.databind.JsonNode userNode)
      Build + record a TrueFoundry user from its raw JSON. No-op when sync-back is off or the node is null / id-less.
    • captureMembershipsFromGroup

      public void captureMembershipsFromGroup(TrueFoundryGroup trueFoundryGroup, Map<String,String> emailToTargetUserId)
      Translate a TrueFoundry group's members list (member email strings) into native membership beans against the supplied emailToTargetUserId index, and record them. No-op if reporting is off or the input is empty.
    • captureGroupJsonFromCurrentProvisioner

      public static void captureGroupJsonFromCurrentProvisioner(com.fasterxml.jackson.databind.JsonNode groupNode)
      Capture a TrueFoundry group (from its normalized raw JSON) against the current provisioner's sync. No-op if there's no current provisioner or the active provisioner isn't a TrueFoundry one. Called from the commands seam (TrueFoundryApiCommands read methods) for every team/role parsed from a read.
    • captureUserJsonFromCurrentProvisioner

      public static void captureUserJsonFromCurrentProvisioner(com.fasterxml.jackson.databind.JsonNode userNode)
      Capture a TrueFoundry user (from its raw JSON) against the current provisioner's sync. No-op if there's no current provisioner or the active provisioner isn't a TrueFoundry one. Called from the commands seam (TrueFoundryApiCommands read methods) for every user parsed from a read.
    • captureMembershipsFromGroupForCurrentProvisioner

      public static void captureMembershipsFromGroupForCurrentProvisioner(TrueFoundryGroup trueFoundryGroup, Map<String,String> emailToTargetUserId)
      Translate a TrueFoundry group's member-email memberships into native records against the supplied email -> target-user-id index, and record them on the current provisioner.
    • captureMembershipsFromGroupForCurrentProvisionerUsingCapturedUsers

      public static void captureMembershipsFromGroupForCurrentProvisionerUsingCapturedUsers(TrueFoundryGroup trueFoundryGroup)
      Scoped-retrieve variant: capture a TrueFoundry group's memberships using an email -> target-user-id index built on the fly from the current provisioner's already-captured native users (populated by prior scoped retrieveEntity calls in the same pass). No-op if reporting is off, the group has no members, or no captured users carry an email.
    • captureMembershipInsertFromCurrentProvisioner

      public static void captureMembershipInsertFromCurrentProvisioner(String groupTargetId, String userTargetId)
      Write-track a successful TrueFoundry membership add against the current provisioner: record (groupTargetId, userTargetId) in the native membership map. No-op out of cycle or for a non-TrueFoundry provisioner. Called per written membership from the DAO insert success path.
    • captureMembershipDeleteFromCurrentProvisioner

      public static void captureMembershipDeleteFromCurrentProvisioner(String groupTargetId, String userTargetId)
      Write-track a successful TrueFoundry membership remove against the current provisioner: drop (groupTargetId, userTargetId) from the native membership map so the end-of-run flush deletes its grouper_prov_mship row. No-op out of cycle or for a non-TrueFoundry provisioner. Called per written membership from the DAO delete success path.
    • captureMembershipReplaceFromCurrentProvisioner

      public static void captureMembershipReplaceFromCurrentProvisioner(String groupTargetId, Collection<String> userTargetIds)
      Write-track a successful TrueFoundry replace-all-memberships against the current provisioner: set the native membership map for groupTargetId to exactly userTargetIds. No-op out of cycle or for a non-TrueFoundry provisioner. Called from the DAO replaceGroupMemberships success path with the group's full desired user-id set.