cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

IdentityNow Rule Guide - Web Services Before Operation Rule

IdentityNow Rule Guide - Web Services Before Operation Rule

Purpose


This rule is used to calculate attributes before a web-service operation call.

Execution

 

  • Connector Execution - This rule executes within the Virtual Appliance and may offer special abilities to perform connector-related functions, and may offer managed connections to sources.
  • Logging - Logging statements are viewable within the ccg.log on the Virtual Appliance and by SailPoint personnel.

 

 

Input

 

Argument Type

Purpose

application sailpoint.object.Application

Application whose data file is being processed.

provisioningPlan sailpoint.object.ProvisioningPlan

Used to update the payload of the http request. Provisioning plan has an account request which defines the operation to be performed on the account. An account request can contain multiple attributes requests and each attribute request represents an operation on a single account attribute. This argument enables the user to update the body/payload or URL attributes of endpoint object using the provisioningPlan information.

requestEndPoint sailpoint.connector.webservices.EndPoint Current request information; contains the header, body, context url, method type, response attribute map, successful response code
restClient sailpoint.connector.webservices.WebServicesClient This is a WebServicesClient (HttpClient) object that would enable the user to call Web Services API to target system.
oldResponseMap java.util.Map The response object returned from earlier endpoint configuration of same operation type like Account Aggregation, Get Object and so on.

 

Output

Argument Type

Purpose

EndPoint / Map sailpoint.connector.webservices.EndPoint / sailpoint.connector.webservices.Map

The rule allows user to return the Endpoint object (requestEndPoint) or a map. The map can hold updatedEndPoint and connectorStateMap keys where the value expected is Endpoint  (requestEndPoint) and connectorStateMap object respectively. The connectorStateMap object is a map that contains key and value of the attribute that must be updated in the application through rule.

 

Template

 

 

 

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule name="Example Rule" type="WebServiceBeforeOperationRule">
  <Description>Describe your rule here.</Description>
  <Source><![CDATA[

  // Add your logic here.

  ]]></Source>
</Rule>

 

 

 

 

Example

 

 

 

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule name="Example Rule" type="WebServiceBeforeOperationRule">
  <Description>This rule is used by the  Web Services connector before performing any operation like testconnection, aggregation etc.</Description>
  <Source><![CDATA[
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import connector.common.JsonUtil;
import connector.common.Util;
import sailpoint.connector.webservices.EndPoint;
import sailpoint.connector.webservices.WebServicesClient;
import sailpoint.object.Application;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;              
                
        Map body = requestEndPoint.getBody();
        String jsonBody = (String) body.get("jsonBody");
        log.info("Rule - Modify Body: running");

        try {

            Map jsonMap = JsonUtil.toMap(jsonBody);
            if (jsonMap != null) {
                Object roleEntry = jsonMap.get("webSiteAndRole");
                String role = "";
                if (roleEntry != null && roleEntry instanceof ArrayList) {
                    ArrayList rolesArray = (ArrayList) roleEntry;
                    if (rolesArray.size() > 0) {
                        role = (String) rolesArray.get(0);
                    }
                } else if (roleEntry != null) {
                    role = (String) roleEntry;
                }

                jsonMap.remove("webSiteAndRole");
                jsonMap.put("webSiteAndRole", role);

                log.info("Rule - Modify Body: setting webSiteAndRole = " + role);
                String webID = "";
                if (provisioningPlan != null) {
                    log.info("Rule - Modify Body: plan is not null");
                    for (AccountRequest accReq : Util.iterate(provisioningPlan.getAccountRequests())) {
                        log.info("Rule - Modify Body: iterating over account requests");
                        for (ProvisioningPlan.AttributeRequest attReq : Util.iterate(accReq.getAttributeRequests())) {
                            log.info("Rule - Modify Body: iterating over attribute requests");
                            String attrName = attReq.getName();
                            String value = null;
                            if (attrName != null && "webId".equalsIgnoreCase(attrName)) {
                                webID = (String) attReq.getValue();
                                log.info("Rule - Modify Body: setting webID = " + webID);
                            }
                        }
                    }
                } else {
                    log.info("Rule - Modify Body: plan is null");
                }

                if (!"".equals(webID)) {
                    jsonMap.put("webID", webID);
                }

                // Add in any other missing fields that are required
                if (!jsonMap.containsKey("webLogonEmail")) {
                    jsonMap.put("webLogonEmail", "");
                }
                if (!jsonMap.containsKey("taxID")) {
                    jsonMap.put("taxID", "");
                }
                if (!jsonMap.containsKey("taxIdType")) {
                    jsonMap.put("taxIdType", "");
                }
                if (!jsonMap.containsKey("actorLogonId")) {
                    jsonMap.put("actorLogonId", "");
                }

                String finalBody = JsonUtil.render(jsonMap);
                body.put("jsonBody", finalBody);
                requestEndPoint.setBody(body);
            }
        } catch (Exception ex) {
            log.error("Rule - Modify Body: " + ex);
        }

        return requestEndPoint;​
  ]]></Source>
</Rule>

 

 

Web Services Class used in Before/After Operation Rule

This section describes the following types of Web Services class:

  • WebServicesClient
  • EndPoint Class

NOTE: The Web Services Classes mentioned in this section are general guidelines. New classes/methods would be added.

WebServicesClient

The following table list the different rules and their description:

Rule Description

Constructor Detail

WebServicesClient

Default constructor.

public WebServicesClient()

Constructor that configures the client using the given args.

public WebServicesClient(java.util.Map args) throws java.lang.Exception

Throws: java.lang.Exception

Method Detail

configure

Configure connection parameters. See the ARG_* constants.

public void configure(java.util.Map args) throws java.lang.Exception

Throws: java.lang.Exception

executeGet

  • Execute method GET with headers
    public java.lang.String executeGet(java.util.Map headers, java.util.List<java.lang.String> allowedStatuses) throws java.lang.Exception
    Parameters: headers (Request headers) and allowedStatuses (Allowed status codes)

  • Execute method GET with URL and headers
    public java.lang.String executeGet(java.lang.String url, java.util.Map headers, java.util.List<java.lang.String> allowedStatuses) throws java.lang.Exception
    Parameters: url (Request URL), headers (Request headers) and allowedStatuses (Allowed status codes)

Returns: Response object

Throws: java.lang.Exception

executePost

  • Execute method POST with URL, payload and headers
    public java.lang.String executePost(java.lang.String url, java.lang.Object payload, java.util.Map headers, java.util.List<java.lang.String> allowedStatuses) throws java.lang.Exception
    Parameters: url (Request URL), payload (Request body), headers (Request headers) and allowedStatuses (Allowed status codes)

  • Execute method POST with URL and payload
    public java.lang.String executePost(java.lang.String url, java.lang.Object payload, java.util.List<java.lang.String> allowedStatuses) throws java.lang.Exception
    Parameters: url (Request URL), payload (Request body) and allowedStatuses (Allowed status codes)

Returns: Response object

Throws: java.lang.Exception

executePut

  • Execute method PUT with URL and payload
    public java.lang.String executePut(java.lang.String url, java.lang.Object payload, java.util.List<java.lang.String> allowedStatuses) throws java.lang.Exception
    Parameters: url (Request URL), payload (Request body) and allowedStatuses (Allowed status codes)

  • Execute method PUT with URL, payload and headers
    public java.lang.String executePut(java.lang.String url, java.lang.Object payload, java.util.Map headers, java.util.List<java.lang.String> allowedStatuses) throws java.lang.Exception
    Parameters: url (Request URL), payload (Request body), headers (Request headers) and allowedStatuses (Allowed status codes)

Returns: Response object

Throws: java.lang.Exception

executePatch

  • Execute method PATCH with URL and payload
    public java.lang.String executePatch(java.lang.String url, java.lang.Object payload, java.util.List<java.lang.String> allowedStatuses) throws java.lang.Exception
    Parameters: url (Request URL), payload (Request body) and allowedStatuses (Allowed status codes)

  • Execute method PATCH with URL, payload and headers
    public java.lang.String executePatch(java.lang.String url, java.lang.Object payload, java.util.Map headers, java.util.List<java.lang.String> allowedStatuses) throws java.lang.Exception
    Parameters: url (Request URL), payload (Request body), headers (Request headers) and allowedStatuses (Allowed status codes)

Returns: Response object

Throws: java.lang.Exception

getResponseHeaders

Get last executed Request's Response headers.

public java.util.Map<java.lang.String,java.lang.String> getResponseHeaders()

executeDelete

  • Execute method DELETE with URL
    public java.lang.String executeDelete(java.lang.String url, java.util.List<java.lang.String> allowedStatuses) throws java.lang.Exception
    Parameters: url (Request URL) and allowedStatuses (Allowed status codes)

  • Execute method DELETE with URL and headers
    public java.lang.String executeDelete(java.lang.String url, java.util.Map headers, java.util.List<java.lang.String> allowedStatuses) throws java.lang.Exception
    Parameters: url (Request URL), headers (Request headers) and allowedStatuses (Allowed status codes)

Returns: Response object

Throws: java.lang.Exception

 

EndPoint Class

The following table list the different rules and their description:

Rule

Description

Constructor Detail

EndPoint

public EndPoint()

Method Detail

setAfterRule

Setting the after rule name

public void setAfterRule(java.lang.String value)

setBeforeRule

Setting the before rule name

public void setBeforeRule(java.lang.String value)

setParseRule

public void setParseRule(java.lang.String value)

setContextUrl

Set the context url for the particular operation (create user, update user, account aggregation, and so on)

public void setContextUrl(java.lang.String value)

setHttpMethodType

Set the http method (put, post, get, patch and delete) for the particular operation (create user, update user, account aggregation, and so on)

public void setHttpMethodType(java.lang.String value)

setOperationType

Set the operation (Account Aggregation, Group Aggregation, Create Account etc) for the particular operation record (create user, update user, account aggregation, and so on)

public void setOperationType(java.lang.String value)

setRootPath

Set the root of the JSON response returned from the managed system (Managed system) for the particular operation (create user, update user, account aggregation, and so on)

public void setRootPath(java.lang.String value)

setFullUrl

set the complete url (endpoint) of the operation that need to be performed for the particular operation (create user, update user, account aggregation, and so on)

public void setFullUrl(java.lang.String value)

setBaseUrl

Set the base url (the machine id or IP and the port where the service is executing) for the operation that need to be performed. Ideally this would be common for all the operation.

public void setBaseUrl(java.lang.String value)

setSequenceNumberForEndpoint

Set the Sequence number particular operation (create user, update user, account aggregation, and so on)

public void setSequenceNumberForEndpoint(int value)

setUniqueNameForEndPoint

Set Unique operation name for particular operation (create user, update user, account aggregation, and so on)

public void setUniqueNameForEndPoint(java.lang.String value)

setResMappingObj

Set the Response mapping for the response attribute returned in the JSON response from the managed system (Managed system) for the particular operation like create user, update user, account aggregation, and so on. Here the key would be attribute name (attribute in the schema) and value would be the JSON response path after the root path mentioned above.

public void setResMappingObj(java.util.Map value)

setHeader

Set HTTP header information in the form of key value (For example, key=“ContentType” Value=“Application/JSON”)

public void setHeader(java.util.Map value)

addHeader

Adding key value if header exists or will create header and add

public void addHeader(java.lang.String entry, java.lang.String value)

setBody

Set http body information as a Map. Here the map would contain three keys bodyFormat, bodyFormData and jsonBody. The bodyFormat value can be raw that means user has provided values as raw JSON string else user has provided value in the key value format that must be converted into JSON.

public void setBody(java.util.Map value)

setResponseCode

Set the value of successful response code as list (200, 299, 201). This would be respected by the connector if any other response code would be consider as request failure.

public void setResponseCode(java.util.List value)

getAfterRule

Fetch the name of after rule assigned to the particular operation like create, update user, account aggregation, and so on:

public java.lang.String getAfterRule()

getBeforeRule

Fetch the name of before rule assigned to the particular operation like create, update user, account aggregation, and so on.

public java.lang.String getBeforeRule()

getParseRule

public java.lang.String getParseRule()

getContextUrl

Fetch the contextUrl provided to the particular operation like create, update user, account aggregation, and so on

public java.lang.String getContextUrl()

getHttpMethodType

Fetch the httpMethodType (get,put,post,delete and patch) provided to the particular operation like create, update user, account aggregation, and so on.

public java.lang.String getHttpMethodType()

getOperationType

Fetch the operationType (Account Aggregation,Create Account,Group Aggregation etc) provided to the particular operation like Create, update user, account aggregation, and so on.

public java.lang.String getOperationType()

getRootPath

Fetch the rootPath provided to the particular operation like Create, update user, account aggregation, and so on.

public java.lang.String getRootPath()

getFullUrl

Fetch the fullUrl that is a combination of basicUrl + contextUrl for the particular operation like Create, update user, account aggregation, and so on.

public java.lang.String getFullUrl()

getBaseUrl

Fetch the baseUrl which is common for all operation like Create, update user, account aggregation, and so on.

public java.lang.String getBaseUrl()

getSequenceNumberForEndpoint

Fetch the sequenceNumber for the particular operation (Create, update user, account aggregation, etc) that decide the priority of execution for operation, if there are multiple endpoint of same operation like account aggregation.

public int getSequenceNumberForEndpoint()

getUniqueNameForEndPoint

Fetch the uniqueName provided to the particular operation like Create, update user, account aggregation, and so on.

public java.lang.String getUniqueNameForEndPoint()

getResMappingObj

Fetch the responseMapping map that will have key as schema attribute and value as JSON path in the JSON response for particular operation like Create, update user, account aggregation, and so on.

public java.util.Map getResMappingObj()

getHeader

Fetch the Http header map that holds the header information for particular operation like Create, update user, account aggregation, and so on.

public java.util.Map getHeader()

getBody

Fetch the body map that holds the body information with keys like bodyFormat, jsonBody and bodyFormData. The bodyFormat can have raw or formData value. bodyFormData will have value as map jsonBody will have value as string with whole JSON.

public java.util.Map getBody()

getResponseCode

Fetch the success response code (list) value which will decide whether the operation was successful or not for particular operation like Create, update user, account aggregation, and so on.

public java.util.List getResponseCode()

getAttributes

public sailpoint.object.Attributes getAttributes()

getAttribute

public java.lang.Object getAttribute(java.lang.String name)

getBooleanAttributeValue

public boolean getBooleanAttributeValue(java.lang.String name)

getStringAttributeValue

public java.lang.String getStringAttributeValue(java.lang.String name)

setAttribute

public void setAttribute(java.lang.String name, java.lang.Object value)

getPaginationSteps

Fetch the paging steps as a string which will decide how account/group paging will work.

public java.lang.String getPaginationSteps()

setPaginationSteps

Set the paging steps as a string which will decide how account/group paging would work.

public void setPaginationSteps(java.lang.String paginationSteps)

toString

public java.lang.String toString()

Overrides: toString in class java.lang.Object

getResponseBody

Retrieve last executed Request's Response Body.

public java.lang.String getResponseBody()

setXpathNamespaces

Sets XPath namespaces using the supplied Map object.

public void setXpathNamespaces(Map<String, String> xpathNamespaces)

getXpathNamespaces

Retrieves XPath namespaces.

public Map<String, String> getXpathNamespaces()

getPagingInitialOffset()

Retrieves the initial page offset.

public int getPagingInitialOffset()

setPagingInitialOffset()

Sets the initial paging offset.

public void setPagingInitialOffset(int pagingInitialOffset)

getPagingSize()

Retrieves the page limit.

public int getPagingSize()

setPagingSize

Sets the page limit.

public void setPagingSize(int pagingLimit)

Labels (1)
Comments

Can we totally stop the execution of the requestEndPoint if some condition passed in plan does not match a condition. PS. return null; does not work.

Hi Team,

I am getting below error while running the code in Web Service Before Operation Rule.

persistent hashmap cannot be cast to java.lang.string

Code:

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import connector.common.JsonUtil;
import connector.common.Util;
import sailpoint.connector.webservices.EndPoint;
import sailpoint.connector.webservices.WebServicesClient;
import sailpoint.object.Application;
import sailpoint.object.ProvisioningPlan;
import sailpoint.object.ProvisioningPlan.AccountRequest;
import java.text.SimpleDateFormat;
import java.util.Date;

Map body = requestEndPoint.getBody();
String jsonBody = (String) body.get("jsonBody");
//log.info("Rule - Modify Body: running");
Date date = new Date();
SimpleDateFormat formater = new SimpleDateFormat("yyyy-MM-dd");
String strDate = formater.format(date);

try
{
Map jsonMap = JsonUtil.toMap(jsonBody);
if (jsonMap != null)
{
// get the date from jsonbody and update it
Object date = jsonMap.get("date");
jsonMap.remove("date");
jsonMap.put("date", strDate);
// append the body back to source

String finalBody = JsonUtil.render(jsonMap);
body.put("jsonBody", finalBody);
requestEndPoint.setBody(body);
}
}
catch (Exception ex)
{
log.error("Rule - Modify Body: " + ex);
}

return requestEndPoint;​

 

Please advice.

 

Thanks,
Sasitharan Duraisamy.

@Sasi13130203 

I encountered the "persistent hashmap cannot be cast to java.lang.string" issue myself. How are you attaching the before operation rule to your source? In the source configuration API, you should have a line "beforeRule": null, in the configuration for each endpoint. Since the documentation doesn't make it clear how to attach the rule, I had first tried:
"beforeRule": {

"name": "RuleName",

"type": "WebServiceBeforeOperationRule",

"id": "123456..."

}

I believe that's the hash map that IdN is trying to cast into a string, as this "beforeRule" is just a string.

Try setting it to:

"beforeRule": "RuleName",

Hopefully that helps. It made all the difference for me.

 

Hii @MattUribe  

 

Thanks for the response. I made the changes as per your suggestion. The code got executed & test connection was success. But the jsonBody in the target application is not getting changed. Basically, I am trying to update (code shared above) the date in below JSON, whenever we are triggering the above WebServiceBeforeOperationRule via Test Connection or Account Aggregation.but that is not happening. 

RAW JSON BODY : 

 {
"jobFileContent" : "LS0tLS0tLS0gRU5DUllQVEVEIERBVEEgLS0tLS0tLS0KQUVTL0NCQy9QS0NTN1BhZGRpbmcKYXAzQ05ZVUZ4TTg9CmxFSWhXYUlXVmtPTEphUGwrbUp0S3F1RVBGanNzeWFlUkxlWmxFcHQ1ZWc9CkdWSTl3ejNUNHFkbnRmTldzOVpXUDlzL2Z1OUxUbURWWVdNOG1aL2hjR3ZPa2ozeUh3SHZ6THErd3dJY2pZNW5JTkx1dEdqUmcyTlAKR1g5YVllZ2F5NW9jUE5nNkQzRlNiVWpZdFc2SWk0VTVsb0F3MEpFcUdySHlrdHRRNFRnMgotLS0tLS0tLSBFTkQgT0YgRklMRSAtLS0tLS0tLQ==",
"date" : "2022-01-19",
"manAkPnr" : "000250.WEB.WEB1",
"tenant" : "",
"outputFormat" : "XML"
}

 

Please advice.

 

Thanks,

Sasitharan Duraisamy.

Hi Team,

Can call two different api from WebServiceBeforeOperation Rule at same time.

For e.g. I have one api to create user and another to add Entitlement but i wanted to use both the api.

I wanted to create a user with default entitlement.

 

Please advice.

 

Thanks,

Satish

Hi Team,

We have a requirement, where we need to send the body as XML. I went through the article, but could not figure a way to send the request body as String or XML. Is it supported by IDN?

Thanks,

Samant Vishwakarma

Hi, this rule does not support printing provisioningPlan object in XML? This is because when I try using provisioningPlan.toXml(), I was not able to deploy the rule to tenant. However, https://developer.sailpoint.com/idn/docs/rules/java-docs clearly mentions the toXml() being available.

Version history
Revision #:
5 of 5
Last update:
‎May 17, 2022 11:01 AM
Updated by: