Web Services - Daisy Chain Request without Java

Is there a way to do this?

I have 2 HTTP operations in order to get the employeeID which is ultimately what I need.

  1. Get all users. This lists all the user ID’s in the app but doesn’t include the employee ID. I’m mapping this to an account attribute called “userID”
  2. Get user details. For each user, I can call another endpoint to get their employee ID based on the previous step’s user ID response or from the account attribute “userID”. The request body contains the variable I need to pull for each user which contains their UserID. Upon success, I will map the employeeID to another account attribute.

Example body of 2nd request:

{
  "UsrIdLst": [
    {
      "UsrId": "$response.UserId$"
    }
  ]
}

Can this be done without a before provisioning rule / Java code?

This is confusing:
Account, Entitlement, or Get Object Aggregation (sailpoint.com)
> This response must be provided as an input to the second endpoint, this can be provided with help of a keyword “response” ($response.team_member_id$ ), where the team_member_id is the value fetched from Account Aggregation -1 and it is an identity attribute in the source schema.

“Identity attribute in the source schema?” Is there a typo there? Isn’t that supposed to be account attribute?

Irrespective of attribute being identity attribute or not in schema , you can refer in chained end point.
It is fine even if it does not exist in schema, it can be temporary also.

In your case , what you have configured is right.

Good to know it’s right, but it’s not working. I’ve tried multiple ways to refer to a previous operation’s response, none of it works. The child operation doesn’t receive any data in that variable.
Since I cannot see what is happening on the back end, I cannot debug or troubleshoot this. How could I see the responses from the operations or debug this?

To answer your original question, yes the Web Services connector is architected to do exactly what you are asking by defining two Account Aggregation HTTP operations, with the second operation pointing back to the first operation by defining it as a parent endpoint.

The attribute name you use in the $response.attributeName$ keyword should actually be the raw attribute name that you receive back directly in the JSON response from the first call.

For example, in your response mapping of the first call, if you mapped a JSON attribute called userId to a schema attribute called USERID, you should be using userId, not the schema attribute name that you mapped. You also need to make sure that you are indeed mapping that userID back correctly from the first call. If the response mapping from the first call is not working correctly, then that may be another reason it’s not populated for the second call. When you run your aggregation, do you actually get accounts back with the userID attribute populated?

To troubleshoot you’d have to turn on log4j debugging on the VA for the Web Services connector, but the logs can sometimes be tough to capture if I am being honest.

Thank you for that explanation. What if the JSON is nested in brackets?
The response from the first HTTP operation would be like this:

"Entity": {
    "UsrIdLst": [
		"Usr" :
		  {
			"UsrId": "string"
		  }
	]
}

I’m already using a root path in the first HTTP response of: $.Entity.UsrIdLst[*] which is working and I’m pulling in the app ID info great!

What should this look like in the body of my 2nd HTTP call?

{
  "UsrIdLst": [
    {
      "UsrId": "$response.UsrId$"
    }
  ]
}

Or should it be:

"UsrId": "$response.Usr.UsrId$"

Or:

"UsrId": "$response.Entity.UsrIdLst.Usr.UsrId$"

The body of your second call should be your first option: $response.UsrId$. The response mapping of the first call is already doing the heavy lifting so you do not need to put the full paths like your described in the other options.

Thanks. I tried all three and no dice. 1st response works great. 2nd returns an issue that I’m missing the UsrId data which tells me it’s not populating.
Hope you have some more ideas for me.

Remember I’m using this for a root path:
$.Entity.UsrIdLst[*]
The mappings I’m doing in 1st call are:
userID = $Usr.UsrId

Notice the nested Usr.UsrId ?

It sounds like I need to use this but it doesn’t work. How can I do a nested call in the $response keyword?

"UsrId": "$response.Usr.UsrId$"

I believe I found the problem. I was able to use Endpoint-1 to pull only 1 account. I was successfully able to refer to the UserID account attribute with $response.UserId$ variable in Endpoint-2. It contained the employee ID and successfully correlated.
I did this by changing the Root Path to $.Entity.UsrIdLst[0].Usr. The object in slot 0 was pulled only.

It appears that the problem is Endpoint-2 does NOT iterate through each user from EndPoint-1. I get an Error 500. It appears Endpoint-2 is trying to send ALL the users in one call to the endpoint.

Can you all confirm this is the expected behavior? Multiple endpoints do not iterate through the array returned from parent endpoints? It only does one call with the whole response array?

1 Like

I have more success. After some research I am getting accounts coming in but only if I limit the number of calls.
I started with $.Entity.UsrIdLst[:70].Usr and it failed. I think went small and did $.Entity.UsrIdLst[:10].Usr. It worked. I then increased it up to 70 slowly and it’s working.

This obviously cannot be the desired method. What could be limiting my requests? Is there by chance a trottle on the endpoint?

1 Like

Rate limiting can indeed be an issue when it comes to hitting certain APIs. Especially if the number of accounts you are fetching is large since you need to do an individual call for every account to fetch the details needed.

1 Like

Thank you Patrick, how would SailPoint handle this situation? Is that pagination? Is this supported on the 2nd Aggregation Operation?

1 Like

Pagination would come into play if the endpoint you’re hitting only allows X number of records per request. For example, only 250 records can be returned in a single HTTP request, so you need to paginate to retrieve all of the records, 250 at a time.

Rate limiting is a security measure so API endpoints cannot be overloaded. If the APIs you are hitting do indeed have rate limiting (i.e. 100 requests per minute), and you are performing the daisy-chained aggregation and there are more than 100 accounts in the system you are trying to aggregate from, you are easily making more than 100 API calls in a minute. Remember, for each ID returned in the first aggregation operation, you are then calling the 2nd aggregation for each of those IDs.

It’s hard to say without knowing more about your target application and it’s APIs. Hopefully it has some decent documentation where you could find out if it has rate limiting. Does the 500 error you are getting have anymore information?

1 Like

Great info, I will have to find out. You may be right about the limit.

I gathered is making multiple requests in IDN.

If I get all the users in the first HTTP operation request, can IDN request all the users at once in the 2nd HTTP operations request if the JSON body & API allows it? I think the API allows requests for more than 1 user in the same request.

If so, how would I refer to the returned array in the 2nd HTTTP operation?

I’m guessing this cannot be done without some java connector rules, am I right?

I found out from the vendor they do not have a rate limit, but they do have a message size limit on request/response.

This is FIS IBS in case you are wondering. Can you confirm I need a before provisioning rule?

If so, do you or anyone have any sample code that can do this? Pulling maybe 50 users at a time until all of them are pulled, then process them to pull the employeeID?

This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.