j1241
(Rita Bhatta)
May 5, 2025, 4:45pm
1
Hello People,
Need your advice
Trying to sync data with 4 different payloads into a Webservice app from ISC
4 different https operation
When sync is run with individual operation it’s successful but when combined , it throws me an error
["Exception occurred while performing \u0027Modify\u0027 operation on identity \u0027291529536652808\u0027: Error: {\n \"status\" : 400,\n \"message\" : \"ContactPaths can only contain a maximum of 3 e-mail addresses.\"\n}"]
Could anyone help me how can I achieve successful sync using these 4 operation with different payloads.
Thank you
Hi Rita,
Can you share a view of what your update account API calls look like for each operation so we can understand better what your calls are doing?
Thanks,
Margo
j1241
(Rita Bhatta)
May 5, 2025, 7:04pm
3
Hello @margocbain
Sure,
All four API calls are same only Body is different.
if $email and $phone fields is empty in webservice app, the sync process should add the respective the values.
However, if values already exist, the process should not perform any addition
Add email and phone
[
{
"op": "add",
"path": "/paths/-",
"value": {
"pathId": 123456,
"value": "$plan.Email$"
}
}
]
[
{
"op": "add",
"path": "/paths/-",
"value": {
"pathId": 78901,
"countryCode": "US",
"value": "$plan.phone$"
}
}
]
if updated values for $email or $phone are received from HR, the existing values should be modified by sync in the webservice.
Modify email and phone
[
{
"op": "replace",
"path": "/paths/pathId:123456/value",
"value": "$plan.Email$"
}
]
[
{
"op": "replace",
"path": "/paths/pathId:78901/value",
"value": "$plan.phone$"
}
]
Thank you
Rita Bhatta:
replace
Hi Rita,
I’d recommend changing all of these to ‘replace’. By using the ‘add’ op, it will append the values, which explains why you’re getting the error for having more than 3 emails in the account.
Thanks,
Margo
j1241
(Rita Bhatta)
May 5, 2025, 8:46pm
5
But there will be time when a value needs to be added to $email and $phone
neeraj99
(Neeraj Nautiyal)
May 6, 2025, 10:15am
6
Hi Rita,
You can write a before operation rule. Where you could check if the email/phone already exists on the account.
if it exists then you can craft the body of “replace” operation.
If it does not exists already then you can craft the body of the “add” operation
Hope this can help but, Please letme know if you find some other solution for the problem
j1241
(Rita Bhatta)
May 6, 2025, 12:15pm
7
Hello @neeraj99
I came up with this
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
String operationToRun = null;
if (provisioningPlan != null) {
for (AccountRequest accReq : provisioningPlan.getAccountRequests()) { // listing account request
for (AttributeRequest attrReq : accReq.getAttributeRequests()) {//
String attrName = attrReq.getName();
String newValue = (String) attrReq.getValue();
String existingValue = accReq.getNativeIdentityAttributes() != null ?
(String) accReq.getNativeIdentityAttributes().get(attrName) : null;
if ("Email".equals(attrName)) {
if (existingValue == null || existingValue.trim().isEmpty()) {
operationToRun = "Add Email";
} else if (!existingValue.equals(newValue)) {
operationToRun = "Modify Email";
}
} else if ("phone".equals(attrName)) {
if (existingValue == null || existingValue.trim().isEmpty()) {
operationToRun = "Add Phone";
} else if (!existingValue.equals(newValue)) {
operationToRun = "Modify Phone";
}
}
}
}
}
return operationToRun;
neeraj99
(Neeraj Nautiyal)
May 6, 2025, 12:27pm
8
I have a question you are returning operationToRun,
Just a problem when you are writing this in before operation rule how are you capturing this?
j1241
(Rita Bhatta)
May 6, 2025, 12:32pm
9
I have created 4 different http operation so thought of writing a rule will select operation.
I am open to any suggestion here
neeraj99
(Neeraj Nautiyal)
May 6, 2025, 12:40pm
10
I was just wandering how would you explicitly select 1 update operation out of 4.
iamology
(Nithesh Rao)
May 6, 2025, 12:43pm
11
BeforeOperation rule runs for a specific operation, which means you cannot change the operation from the rule.
What you need to do is create one Modify Account operation and inside the BeforeOperation rule, change the body based on the attribute found in the Provision Plan
j1241
(Rita Bhatta)
May 6, 2025, 1:45pm
12
@iamology
What you saying is I don’t need 4 different operation set up in ISC. i just need one and modify the body. How will i send the payload to the targeted system?
iamology
(Nithesh Rao)
May 6, 2025, 2:19pm
13
You don’t need to add anything to the body in the UI. Instead update the body in the BeforeOperation rule like below
JSONArray intendedBody = new JSONArray(javaList);
Map jsonBody = new HashMap();
jsonBody.put("jsonBody", intendedBody.toString());
requestEndPoint.setBody(jsonBody);
javaList above needs to be created by applying your login on contents of Provisioning Plan
Add single update operation and then use before operation rule to call all required api’s in single code.
1 Like
j1241
(Rita Bhatta)
May 12, 2025, 6:54pm
15
Hello,
@neeraj99 @iamology @iamology
Thanks for your suggestions! I’ve used them to develop a BeforeOperation rule and would be grateful for any feedback you can provide.
import java.util.*;
import connector.common.JsonUtil;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import sailpoint.object.ProvisioningPlan.AttributeRequest;
import sailpoint.connector.webservices.Endpoint;
// Get request endpoint
Endpoint requestEndPoint = (Endpoint) args.get("requestEndPoint");
// Extract attribute values from provisioning plan
ProvisioningPlan plan = (ProvisioningPlan) args.get("provisioningPlan");
String email = null;
String phone = null;
if (plan != null && plan.getAccountRequests() != null) {
for (AccountRequest acctReq : plan.getAccountRequests()) {
if ("Source ABC".equalsIgnoreCase(acctReq.getApplicationName())) {
for (AttributeRequest attrReq : acctReq.getAttributeRequests()) {
if ("secondaryEmail".equals(attrReq.getName())) {
email = (String) attrReq.getValue();
}
if ("phoneCallCell1".equals(attrReq.getName())) {
phone = (String) attrReq.getValue();
}
}
}
}
}
// Get existing attributes from Source ABC
Map<String, Object> existingAttributes = (Map<String, Object>) args.getOrDefault("existingAttributes", new HashMap<>());
String existingEmail = (String) existingAttributes.get("secondaryEmail");
String existingPhone = (String) existingAttributes.get("phoneCallCell1");
// Build dynamic payload
List<Map<String, Object>> payloadList = new ArrayList<>();
// Email logic
if (email != null) {
Map<String, Object> emailPayload = new HashMap<>();
if (existingEmail == null || "".equals(existingEmail)) {
emailPayload.put("op", "add");
emailPayload.put("path", "/paths/-");
Map<String, Object> valueMap = new HashMap<>();
valueMap.put("pathId", 240001148045317L);
valueMap.put("value", email);
emailPayload.put("value", valueMap);
} else if (!existingEmail.equals(email)) {
emailPayload.put("op", "replace");
emailPayload.put("path", "/paths/pathId:240001148045317/value");
emailPayload.put("value", email);
}
if (!emailPayload.isEmpty()) {
payloadList.add(emailPayload);
}
}
// Phone logic
if (phone != null) {
Map<String, Object> phonePayload = new HashMap<>();
if (existingPhone == null || "".equals(existingPhone)) {
phonePayload.put("op", "add");
phonePayload.put("path", "/paths/-");
Map<String, Object> valueMap = new HashMap<>();
valueMap.put("pathId", 240001148045319L);
valueMap.put("value", phone);
valueMap.put("countryCode", "US");
phonePayload.put("value", valueMap);
} else if (!existingPhone.equals(phone)) {
phonePayload.put("op", "replace");
phonePayload.put("path", "/paths/pathId:240001148045319/value");
phonePayload.put("value", phone);
}
if (!phonePayload.isEmpty()) {
payloadList.add(phonePayload);
}
}
// Inject payload
if (!payloadList.isEmpty()) {
String finalPayload = JsonUtil.render(payloadList);
requestEndPoint.setPayload(finalPayload);
} else {
}
return requestEndPoint;
Thank you
neeraj99
(Neeraj Nautiyal)
May 12, 2025, 7:08pm
16
Hi @j1241
This looks good to me on high level. Give it a shot and see if syntax & Logic is working as expected & if not you can just drop the error here someone would pick it up.
2 Likes
j1241
(Rita Bhatta)
May 14, 2025, 7:08pm
17
Could you suggest me a better way of handlining this saas rule validator errors.
Line 23 - [LintBSHMethodInvocation(92)] Could not retrieve definition for variable name 'args'
23: Endpoint requestEndPoint = ( Endpoint ) args .getOrDefault ( "requestEndPoint" , new Endpoint ( ) )
Line 27 - [LintBSHMethodInvocation(92)] Could not retrieve definition for variable name 'args'
27: ProvisioningPlan plan = ( ProvisioningPlan ) args .get ( "provisioningPlan" )
system
(system)
Closed
July 20, 2025, 3:58pm
19
This topic was automatically closed 60 days after the last reply. New replies are no longer allowed.