Announcing the SAVIYNT KNOWLEDGE EXCHANGE unifying the Saviynt forums, documentation, training, and more in a single search tool across platforms. Click HERE to read the Announcement.

Rest connector: Account recon does not update account attributes

Paul_Meyer
Regular Contributor
Regular Contributor

I have an strange issue with the rest connector. After running the account and access recon jobs for the first time, for a newly created endpoint, the mapped account attributes and entitlement details are loading correctly.The mapped account attributes are as per the API response and the entitlements are as per the api response.

However after making changes to the accounts, directly using the application's api, subsequent executions of the access and account jobs does not reflect the updated changes and does not update the account attributes or entitlements.

Enabling showLogs and looking at the debug logs, the application api response contains updated attribute values, however the updated values are not reflected in the account record. No response errors are logged and no job errors are encountered.

I have

  • added statusAndThresholdConfig setting to the ImportAccountEntJSON, and account attributes are not updated.
  • moved the ImportAccountEntJSON to STATUS_THRESHOLD_CONFIG, and account attributes are not updated.
  • removed ImportAccountEntJSON and STATUS_THRESHOLD_CONFIG, and account attributes are not updated.

Any ideas how to further troubleshoot the issue or are there known issue with the rest connector?

Update:

I replicated the exact rest connector config to a v2021 instance. Account updates are slow to show in the UI, but the account attribute changes are updated on the account records.

11 REPLIES 11

rushikeshvartak
All-Star
All-Star

It seems version issue. can you share ImportAcctEntJSON


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

ImportAcctEntJSON:

{
  "accountParams": {
    "connection": "userAuth",
    "processingType": "SequentialAndIterative",
    "statusAndThresholdConfig": {
      "statusColumn": "customproperty10",
      "activeStatus": [
        true
      ],
      "deleteLinks": true,
      "accountThresholdValue": 1000,
      "correlateInactiveAccounts": true,
      "inactivateAccountsNotInFile": true,
      "deleteAccEntForActiveAccounts": false
    },
    "call": {
		"call1": {
			"callOrder": 0,
			"stageNumber": 0,
			"http": {
			  "url": "https://HOSTNAME/Data/SystemUsers?%24count=true",
			  "httpHeaders": {
				"Authorization": "${access_token}",
				"Accept": "application/json"
			  },
			  "httpContentType": "application/json",
			  "httpMethod": "GET"
			},
			"listField": "value",
			"keyField": "accountID",
			"colsToPropsMap": {
			  "accountID": "UserID~#~char",
			  "customproperty1": "Alias~#~char",
			  "customproperty10": "Enabled~#~char",
			  "customproperty47": "WorkflowLineItemNotificationFormat~#~char",
			  "customproperty11": "DocumentHandlingActive~#~char",
			  "customproperty12": "UserInfo_defaultPartition~#~char",
			  "customproperty13": "GlobalListPageLinkMode~#~char",
			  "customproperty14": "GlobalExcelExportMode~#~char",
			  "customproperty15": "ShowAttachmentStatus~#~char",
			  "customproperty16": "EventPopUpLinkDestination~#~char",
			  "customproperty17": "NetworkDomain~#~char",
			  "customproperty18": "Company~#~char",
			  "customproperty19": "SqmGUID~#~char",
			  "customproperty2": "Email~#~char",
			  "customproperty20": "SendNotificationsInEmail~#~char",
			  "customproperty21": "Density~#~char",
			  "customproperty22": "DefaultCountryRegion~#~char",
			  "customproperty23": "SendAlertAsEmailMessage~#~char",
			  "customproperty24": "SqmEnabled~#~char",
			  "customproperty25": "GlobalExcelExportFilePath~#~char",
			  "customproperty26": "Language~#~char",
			  "customproperty27": "EventPopUpDisplayWhen~#~char",
			  "customproperty28": "EventPollFrequency~#~char",
			  "customproperty29": "EventWorkflowShowPopup~#~char",
			  "customproperty3": "EmailProviderID~#~char",
			  "customproperty30": "StartPage~#~char",
			  "customproperty31": "PreferredTimeZone~#~char",
			  "customproperty32": "HomePageRefreshDuration~#~char",
			  "customproperty33": "UserInfo_language~#~char",
			  "customproperty34": "AutoLogOff~#~char",
			  "customproperty35": "Theme~#~char",
			  "customproperty36": "MarkEmptyLinks~#~char",
			  "customproperty37": "Enabled~#~char",
			  "customproperty38": "ShowNotificationsInTheMicrosoftDynamicsAX7Client~#~char",
			  "customproperty39": "Helplanguage~#~char",
			  "customproperty4": "PersonName~#~char",
			  "customproperty40": "EventPopUps~#~char",
			  "customproperty41": "PreferredCalendar~#~char",
			  "customproperty42": "PreferredLocale~#~char",
			  "customproperty43": "ExternalUser~#~char",
			  "customproperty44": "AutomaticUrlUpdate~#~char",
			  "customproperty46": "UserID~#~char",
			  "displayName": "UserName~#~char",
			  "name": "UserID~#~char"
			},
			"makeProcessingStatus": false,
			"pagination": {
				"offset": {
					"offsetParam": "$skip",
					"batchParam": "$top", 
					"batchSize": 10000,
					"totalCountPath": "completeResponseMap.@odata~dot#count"
			  }
			}
		},
		"call2": {
				"callOrder": 1,
				"stageNumber": 3,
				"http": {
						"url": "https://HOSTNAME/Data/PersonUsers?%24count=true&%24filter=UserId%20eq%20%27${accountName.replace('&','%26').replace(' ','%20')}%27",
						"httpHeaders": {
						"Authorization": "${access_token}",
						"Accept": "application/json"
					},
					"httpContentType": "application/json",
					"httpMethod": "GET"
				},
					"inputParams": {
					"dependentCall": true
				},
					"nextApiKeyField": "customproperty46",
					"makeProcessingStatus": false,
					"listField": "value",
					"keyField": "accountID",
					"colsToPropsMap": {
					  "accountID": "UserId~#~char",
					  "name": "UserId~#~char",
					  "customproperty45": "PartyNumber~#~char"
				}
		}
	}
  },
  "entitlementParams": {
    "connection": "userAuth",
    "processingType": "SequentialAndIterative",
    "entTypes": {
      "Roles": {
        "entTypeOrder": 0,
        "call": {
          "call1": {
            "callOrder": 0,
            "stageNumber": 0,
            "http": {
              "url": "https://HOSTNAME/data/SecurityRoles?%24count=true",
              "httpHeaders": {
                "Authorization": "${access_token}",
                "Accept": "application/json"
              },
              "httpContentType": "application/json",
              "httpMethod": "GET"
            },
            "listField": "value",
            "keyField": "entitlementID",
            "colsToPropsMap": {
              "customproperty1": "AccessToSensitiveData~#~char",
              "customproperty2": "UserLicenseType~#~char",
              "customproperty3": "ContextString~#~char",
              "entitlementID": "SecurityRoleIdentifier~#~char",
              "description": "Description~#~char",
              "entitlement_value": "SecurityRoleName~#~char"
            },
            "pagination": {
              "offset": {
                "offsetParam": "$skip",
                "batchParam": "$top",
                "batchSize": 10000,
                "totalCountPath": "completeResponseMap.@odata~dot#count"
              }
            },
            "disableDeletedEntitlements": true
          }
        }
      },
      "Duties": {
        "entTypeOrder": 1,
        "call": {
          "call1": {
            "callOrder": 0,
            "stageNumber": 0,
            "http": {
              "url": "https://HOSTNAME/data/SecurityRoleDuties?%24count=true",
              "httpHeaders": {
                "Authorization": "${access_token}",
                "Accept": "application/json"
              },
              "httpContentType": "application/json",
              "httpMethod": "GET"
            },
            "listField": "value",
            "keyField": "entitlementID",
            "colsToPropsMap": {
              "entitlementID": "SecurityDutyIdentifier~#~char",
              "description": "SecurityDutyName~#~char",
              "entitlement_value": "SecurityDutyName~#~char"
            },
            "pagination": {
              "offset": {
                "offsetParam": "$skip",
                "batchParam": "$top",
                "batchSize": 10000,
                "totalCountPath": "completeResponseMap.@odata~dot#count"
              }
            },
            "disableDeletedEntitlements": true
          }
        }
      },
      "Privileges": {
        "entTypeOrder": 2,
        "call": {
          "call1": {
            "callOrder": 0,
            "stageNumber": 0,
            "http": {
              "url": "https://HOSTNAME/data/SecurityPrivileges?%24count=true",
              "httpHeaders": {
                "Authorization": "${access_token}",
                "Accept": "application/json"
              },
              "httpContentType": "application/json",
              "httpMethod": "GET"
            },
            "listField": "value",
            "keyField": "entitlementID",
            "colsToPropsMap": {
              "entitlementID": "SecurityPrivilegeIdentifier~#~char",
              "description": "SecurityPrivilegeName~#~char",
              "entitlement_value": "SecurityPrivilegeName~#~char"
            },
            "pagination": {
              "offset": {
                "offsetParam": "$skip",
                "batchParam": "$top",
                "batchSize": 100000,
                "totalCountPath": "completeResponseMap.@odata~dot#count"
              }
            },
            "disableDeletedEntitlements": true
          }
        }
      },
      "Organizations": {
        "entTypeOrder": 3,
        "call": {
          "call1": {
            "callOrder": 0,
            "stageNumber": 0,
            "http": {
              "url": "https://HOSTNAME/Data/LegalEntities?%24count=true",
              "httpHeaders": {
                "Authorization": "${access_token}",
                "Accept": "application/json"
              },
              "httpContentType": "application/json",
              "httpMethod": "GET"
            },
            "listField": "value",
            "keyField": "entitlementID",
            "colsToPropsMap": {
              "entitlementID": "LegalEntityId~#~char",
              "entclass": "#CONST#LegalEntity~#~char",
              "description": "Name~#~char",
              "entitlement_value": "Name~#~char",
              "customproperty1": "CompanyType~#~char",
              "customproperty2": "PartyNumber~#~char"
            },
            "pagination": {
              "offset": {
                "offsetParam": "$skip",
                "batchParam": "$top",
                "batchSize": 10000,
                "totalCountPath": "completeResponseMap.@odata~dot#count"
              }
            },
            "disableDeletedEntitlements": true
          }
        }
      }
    }
  },
  "entMappingParams": {
    "processingType": "SequentialAndIterative",
    "entTypes": {
      "Roles": {
        "ent1KeyField": "entitlementID",
        "call": {
          "call1": {
            "connection": "userAuth",
            "callOrder": 0,
            "stageNumber": 0,
            "http": {
              "httpHeaders": {
                "Authorization": "${access_token}"
              },
              "url": "https://HOSTNAME/data/SecurityRoleDuties?%24count=true",
              "httpMethod": "GET"
            },
            "listField": "value",
            "ent1IdPath": "SecurityRoleIdentifier",
            "ent2IdPath": "SecurityDutyIdentifier",
            "ent2KeyField": "entitlementID",
            "targetEntType": "Duties",
            "mappingTypes": [
              "ENT2"
            ],
            "pagination": {
              "offset": {
                "offsetParam": "$skip",
                "batchParam": "$top",
                "batchSize": 10000,
                "totalCountPath": "completeResponseMap.@odata~dot#count"
              }
            }
          },
          "call2": {
            "connection": "userAuth",
            "callOrder": 0,
            "stageNumber": 0,
            "http": {
              "httpHeaders": {
                "Authorization": "${access_token}"
              },
              "url": "https://HOSTNAME/data/SecurityPrivileges?%24count=true",
              "httpMethod": "GET"
            },
            "listField": "value",
            "ent1IdPath": "SecurityRoleIdentifier",
            "ent2IdPath": "SecurityPrivilegeIdentifier",
            "ent2KeyField": "entitlementID",
            "targetEntType": "Privileges",
            "mappingTypes": [
              "ENT2"
            ],
            "pagination": {
              "offset": {
                "offsetParam": "$skip",
                "batchParam": "$top",
                "batchSize": 10000,
                "totalCountPath": "completeResponseMap.@odata~dot#count"
              }
            }
          },
          "call3": {
            "connection": "userAuth",
            "callOrder": 0,
            "stageNumber": 0,
            "http": {
              "httpHeaders": {
                "Authorization": "${access_token}"
              },
              "url": "https://HOSTNAME/data/SecuritySubRoles?%24count=true",
              "httpMethod": "GET"
            },
            "listField": "value",
            "ent1IdPath": "SecurityRoleIdentifier",
            "ent2IdPath": "SecuritySubRoleIdentifier",
            "ent2KeyField": "entitlementID",
            "targetEntType": "Roles",
            "mappingTypes": [
              "ENT2"
            ],
            "pagination": {
              "offset": {
                "offsetParam": "$skip",
                "batchParam": "$top",
                "batchSize": 10000,
                "totalCountPath": "completeResponseMap.@odata~dot#count"
              }
            }
          }
        }
      },
      "Duties": {
        "ent1KeyField": "entitlementID",
        "call": {
          "call1": {
            "connection": "userAuth",
            "callOrder": 0,
            "stageNumber": 0,
            "http": {
              "httpHeaders": {
                "Authorization": "${access_token}"
              },
              "url": "https://HOSTNAME/data/SecurityDuties?%24count=true",
              "httpMethod": "GET"
            },
            "listField": "value",
            "ent1IdPath": "SecurityDutyIdentifier",
            "ent2IdPath": "SecurityPrivilegeIdentifier",
            "ent2KeyField": "entitlementID",
            "targetEntType": "Privileges",
            "mappingTypes": [
              "ENT2"
            ],
            "pagination": {
              "offset": {
                "offsetParam": "$skip",
                "batchParam": "$top",
                "batchSize": 10000,
                "totalCountPath": "completeResponseMap.@odata~dot#count"
              }
            }
          }
        }
      }
    }
  },
  "acctEntParams": {
    "processingType": "http",
    "entTypes": {
      "Organizations": {
        "acctKeyField": "accountID",
        "entKeyField": "entitlementID",
        "call": {
          "call1": {
            "connection": "userAuth",
            "callOrder": 0,
            "stageNumber": 0,
            "http": {
              "httpHeaders": {
                "Authorization": "${access_token}"
              },
              "url": "https://HOSTNAME/Data/SecurityUserRoleOrganizations?%24count=true",
              "httpContentType": "application/json",
              "httpMethod": "GET"
            },
            "listField": "value",
            "acctIdPath": "UserId",
            "entIdPath": "OrganizationId",
            "pagination": {
              "offset": {
                "offsetParam": "$skip",
                "batchParam": "$top",
                "batchSize": 10000,
                "totalCountPath": "completeResponseMap.@odata~dot#count"
              }
            }
          }
        }
      },
      "Roles": {
        "acctKeyField": "accountID",
        "entKeyField": "entitlementID",
        "call": {
          "call1": {
            "connection": "userAuth",
            "callOrder": 0,
            "stageNumber": 0,
            "http": {
              "httpHeaders": {
                "Authorization": "${access_token}"
              },
              "url": "https://HOSTNAME/data/SecurityUserRoles?%24count=true",
              "httpContentType": "application/json",
              "httpMethod": "GET"
            },
            "listField": "value",
            "acctIdPath": "UserId",
            "entIdPath": "SecurityRoleIdentifier",
            "pagination": {
              "offset": {
                "offsetParam": "$skip",
                "batchParam": "$top",
                "batchSize": 10000,
                "totalCountPath": "completeResponseMap.@odata~dot#count"
              }
            }
          }
        }
      }
    }
  }
}

Since you many customproperties it might not be working can you try reducing till CP20 for account and run


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

Hi @Paul_Meyer  - looking at your example it looks like you have mapped one entitlement type "Privileges" as child entitlement in two different entitlement types - Roles and Duties?

is it working fine? i am not able to achieve same with my data. Any references or suggestion from your end?

@rushikeshvartak any suggestions from you on above stated problem?

@Paul_Meyer  @rushikeshvartak  please ignore my query. its resolved now. small mistake in url itself.

Glad you got it resolved.

@GauravJain 

The Rest connector configuration is for the Microsoft Dynamics 365 F&O application.

The entitlement hierarchy is:

  • Each Role consist of:
    • one or more Duties
    • zero or more Privileges
  • Each Duty consists of zero or more Privileges
  • Each Privilege consists of zero or more Permissions (Not configured in the above example)
  • Each Role can have zero or more Roles

For example:

Paul_Meyer_0-1674548462771.png

What does your application's entitlement hierarchy look like?

Paul_Meyer
Regular Contributor
Regular Contributor

I reduced the number of customproperties to 8. The update issue persists. Account attributes are not updated.

I've done some additional testing.

It seems that when an account record is created in Saviynt from an account recon job and the account is in an Active state, any subsequent account attribute changes are updated by an account recon job. Even when you set the application account status to Disabled, the account status in Saviynt is set to Inactive after an account recon job.

However, once the account is in Inactive state in Saviynt, any account attribute changes are not reflected/updated in Saviynt from an account recon job, such as re-enabling the account in the application or making attribute values changes on the application account.

Is there any config setting that must to be configured to 'allow' an Inactive account in Saviynt to be updated from an account recon job?

Global config or connector configjson

example 11 https://saviynt.freshdesk.com/support/solutions/articles/43000521736-rest-connector-guide#RESTConnec...


Regards,
Rushikesh Vartak
If you find the response useful, kindly consider selecting Accept As Solution and clicking on the kudos button.

@rushikeshvartak 

Adding the "includeExistingInActiveAccounts" setting to the ImportAccountEntJSON has resolved the issue.