Web Services Connector: $plan.attribute$ || $response.attribute$

Hello SailPoint Community,

Same question as here: Web Services update account with all attributes

There should be another keyword beside plan and response so that $future.name$ is:

  • $plan.name$ if this attribute is going to change
  • $account.name$ otherwise

Or maybe a method to select the first set value (even if empty): $first($plan.attribute$, $response.attribute$).

Best regards,
Andrei

I agree that it would be nice to have an easy way to populate existing attributes in an HTTP Operation. I have one connector that requires all attributes to be populated in order to update the account. The way I did this was through a Before Operation Rule. The rule does the following:

  1. Get the current account attributes on the source for the impacted Identity, in our case the Get uses the same URL as the PUT for updating the account information.
  2. Map that current account attributes
  3. Map the attributes that have been specified in the Body of the Update Account Operation (requestEndPoint.getBody())
  4. If the attribute exists in the request, put the request value into the mapping of the current account attributes.
  5. Update the requestEndPoint Body with the updated current account information.
//Get Body from Request EndPoint
Map body = requestEndPoint.getBody();
//Get Header from Request EndPoint
Map header = requestEndPoint.getHeader();
if(body != null) {
	String jsonBody = (String) body.get("jsonBody");
	Map requestMap = JsonUtil.toMap(jsonBody);
	WebServicesClient client = new WebServicesClient();
	String accesslevelURL = requestEndPoint.getFullUrl();
	Map args = new HashMap();
	args.put(WebServicesClient.ARG_URL, accesslevelURL);
	client.configure(args);
	List<String> allowedStatuses = new ArrayList();
	allowedStatuses.add("2**");
	String response = client.executeGet(accesslevelURL, header, allowedStatuses);
    //Get original attributes from Source
	Map originalMap = JsonUtil.toMap(response);
    //If Attribute is in the request, replace the attribute in the original information feed
    if(requestMap.containsKey("firstName")){
       originalMap.put("firstName", requestMap.get("firstName"));
    }
    if(requestMap.containsKey("lastName")){
       originalMap.put("lastName", requestMap.get("lastName"));
    }
    if(requestMap.containsKey("emailAddress")){
        originalMap.put("emailAddress", requestMap.get("emailAddress"));
    }
	body.put("jsonBody", originalMap);
	//update body for the Request EndPoint
	requestEndPoint.setBody(body);
}
return requestEndPoint;
1 Like

Hi Carl,

I found, if you want all attributes to be sent in the update account, then I just suffix attribute name with an ‘x’ on the attribute in the provisioning plan, so it doesnt get removed before it hits the Before Operation rule.

            {
                "name": "firstNamex",
                "transform": {
                    "type": "accountAttribute",
                    "attributes": {
                        "attributeName": "firstName",
                        "sourceName": "Blah Web Service"
                    }
                },
                "attributes": {},
                "isRequired": true,
                "type": "string",
                "isMultiValued": false
            }

Then you can use $plan.firstNamex$ to get the value

Would that work for your use case?

Hi Jason, I don’t think this will work in cases where you want to use either the account value, or, if set, the new value from the provisioning plan.

I must say that it’s a pain creating a (relative simple) rule in SailPoint. The documentation (and tooling) should definitely be improved.

Even something as simple as this doesn’t work as expected:

import sailpoint.connector.webservices.EndPoint;

public Endpoint f() {
	return requestEndPoint;
}
return f();

Exception occurred in Test Connection. Error: Error executing before operation rule for endpoint ‘Test_connection’: BeanShell script error: bsh.EvalError: Sourced file: inline evaluation of: import sailpoint.connector.webservices.EndPoint; public Endpoint f() { . . . '' : Class: Endpoint not found in namespace : at Line: 3 : in file: inline evaluation of: import sailpoint.connector.webservices.EndPoint; public Endpoint f() { . . . ‘’ : Endpoint BSF info: My Before Provisioning Rule at line: 0 column: columnNo


Reading the examples on Web Services Before Operation Rule | SailPoint Developer Community you’d think that you need to create an XML to deploy a rule…


The Web Services Classes mentioned in this section are general guidelines. New classes and methods may be added.
From Web Services Class Used in Before and After Operation Rules

It would be more useful to reference the authoritative documentation, than to let users guess if any new classes were added in the meantime.

And so on and so forth.

Hi Andrei

It used to be that you would put the rule in an XML document for uploading via API

new /beta/connector-rules API doesn’t require the XML parts.

POST https://<tenant>/beta/connector-rules

body:
{
        "description": "This rule is to do stuff.",
        "name": "Test WSAO",
        "type": "WebServiceAfterOperationRule",
        "signature": {
            "input": [],
            "output": null
        },
        "sourceCode": {
            "version": "1.0",
            "script": "import java.util.HashMap;\nimport java.util.Map;\nimport com.jayway.jsonpath.JsonPath;\nimport org.apache.logging.log4j.Logger;\n ............. \n\nreturn responseMap;"
        },
        "attributes": {
            "sourceVersion": "1.0"
        }
    }

Hi Jason,

It would be nice if the documentation was getting updated/improved. Finding the right way of doing things is currently pretty convoluted for new users, and it often involves having to search the discussion board for things that should be updated in the documentation (and often finding automatically closed discussions without any answer).

1 Like

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