Implementation Rules Scripts and API Training - Run Rule

Dear comunity,

Currently I’m doing the traingin “Implementation Rules Scripts and API”, exercise one - Run a Rule from the IdentityIQ Console

This exercise it must run 3 rules:
1.import /home/spadmin/APITraining/config/Rule-TRNG-UtilRuleLibrary.xml
2. import /home/spadmin/APITraining/config/Rule-TRNG-IdentityLookup.xml
3. rule TRNG-IdentityLookup /home/spadmin/APITraining/config/LookupRuleArgs.xml

As is expected in the vm providing by the training works fine, but I setup my own environment and when test the exactly same step i get

Found the Identity: Name = Adam.Kennedy, Email address = [email protected]
2023-10-17T11:09:29,855 ERROR main org.apache.bsf.BSFManager:451 - Exception:
java.security.PrivilegedActionException: null
at java.security.AccessController.doPrivileged(Native Method) ~[?:1.8.0_372]
at org.apache.bsf.BSFManager.eval(BSFManager.java:442) [bsf.jar:?]

Caused by: org.apache.bsf.BSFException: BeanShell script error: bsh.EvalError: Sourced file: inline evaluation of: import sailpoint.object.Identity; //this value context entry point sailpoint i . . . '' : Command not found: getManagerEmail(java.lang.String) : at Line: 10 : in file: inline evaluation of: import sailpoint.object.Identity; //this value context entry point sailpoint i . . . ‘’ : getManagerEmail ( identity .getName ( ) )
BSF info: IdentityLookup at line: 0 column: columnNo

I want to urdenstand why?
Please find the 3 rules here:
1.Rule-TRNG-UtilRuleLibrary.xml

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell"  name="UtilRuleLibrary">
  <Description>This rule library contains utility methods used in the Rules-API training course.</Description>
<Source>
  import sailpoint.object.Identity;
  import java.sql.Connection;  
  import java.sql.DriverManager; 
  import sailpoint.object.EmailTemplate;
  import sailpoint.object.EmailOptions;
  import sailpoint.object.ProvisioningPlan;
  import sailpoint.object.ProvisioningPlan.AccountRequest;
  import sailpoint.object.ProvisioningPlan.AttributeRequest; 
  import org.apache.commons.logging.Log;
  import org.apache.commons.logging.LogFactory;
  
  Log logger = LogFactory.getLog("=====rule.UtilRuleLibrary====");

  //************
  // Retrieve manager of the specified identity
  // Args: user name 
  // Returns: manager identity's name 
  //************
  public String getUserManager(String identityName) {
     Identity identity = context.getObjectByName(Identity.class, identityName);
     if (null != identity) {
         Identity manager = identity.getManager();
         if (null != manager) {
             return manager.getName();
         }
     }
  }

  //************
  // Retrieve email of the specified identity (user name provided, email address returned)
  // Args: user name 
  // Returns: email address 
  //************
  public String getUserEmail(String identityName) {
     Identity identity = context.getObjectByName(Identity.class, identityName);
     if (null != identity)
	return identity.getEmail();
  }

  //************
  // Retrieve email address of the specified user's manager
  // Args: user name
  // Returns: manager's email address
  //************
  public String getManagerEmail(String identityName) {
     return getUserEmail(getUserManager(identityName));     
  }

  //************
  // Return name of provisioned group
  // Args: provisioned provisioningPlan
  // Returns: group name from plan
  //************
  public String getProvisionedGroup(ProvisioningPlan plan) {
     String groupName = null;

    if (plan != null) {
        logger.trace("Provisioned Plan: " + plan.toXml());
     }
     List accountRequests = plan.getAccountRequests();
     if (null != accountRequests) {
       for (AccountRequest acctReq : accountRequests) {
           AttributeRequest attrReq = acctReq.getAttributeRequest("groups");
           if (groupName == null)
              groupName = attrReq.getDisplayValue();
           else
              groupName = groupName + ", " + attrReq.getDisplayValue();
       }
     }
     logger.trace("Group Name: " + groupName);
     return groupName;
  }
  
  //************
  // Send the specified email message to the specified user
  // Args: user name, email template, email arguments
  // Returns: none
  //************
  public void sendEmail(String identityName, String templateName, Map args) {
  
     // Get email address of notification target
     String emailDest = getUserEmail(identityName);
     if (null == emailDest) {
         logger.error("ERROR: could not find email address for " + identityName);
         return;
     }
      
     // Get the email template based on templateName
     EmailTemplate template = context.getObjectByName(EmailTemplate.class, templateName);
     if (null == template) {
         logger.error("ERROR: could not find email template [" + templateName + "]");
         return;
     }
     // Provide arguments and send email message
     EmailOptions ops = new EmailOptions(emailDest, args);
     context.sendEmailNotification(template, ops);

     return;
  }

  //************
  // Connect to external database
  // Args: none 
  // Returns: database connection 
  //************
    public Connection connectToDatabase() {
   
    // Load the class driver
    String driverClass = "com.mysql.cj.jdbc.Driver";  
    Class driverClazz = null;  
    try {  
       driverClazz = Class.forName(driverClass);  
    } catch (Exception ex) {  
       String errMsg = "Failed to load driver class for JDBC Driver: " + driverClass;  
       logger.error(errMsg + ": " + ex);  
       return null;  
    }    

    // Connect to the external database      
    String dbType = "mysql";  
    String dbHost = "localhost"; 
    String dbName = "CodesDB";  
    String dbUser = "root";  
    String dbPass = "1:xDikd6BMwY+LL9iXETAjBg==";  
    String dbUrl = "jdbc:mysql://" + dbHost + "/" + dbName + "?useSSL=false";    
    String clearDbPass = context.decrypt(dbPass);  
    Connection dbCxn = null;  
    try {  
       dbCxn = DriverManager.getConnection(dbUrl, dbUser, clearDbPass);  
    } catch (Exception ex) {  
       String errMsg = "Error while connecting to database [" + dbUrl + "]";  
       logger.error(errMsg + ": " + ex);   
    }
    return dbCxn;
  }
  </Source>
</Rule>
  1. Rule-TRNG-IdentityLookup.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell"  name="IdentityLookup">
  <Description>This rule accepts an identity name and retrieves the corresponding identity object, returning the user's email address.</Description>
  <!--Reference another rule-->
  <ReferencedRules>
       <Reference class='Rule' name='UtilRuleLibrary'/>
</ReferencedRules>
<!--Rule return type The value returned from a rule is reported in the task results as its result status-->
<Signature returnType='String'>
    <Inputs>
      <Argument name='context'>
        <Description>
         A sailpoint.api.SailPointContext objec,the context argument is a SailPointContext object, the entry point into the SailPoint API – 
		  giving you methods for accessing other objects and interacting with the SailPoint database. 

        </Description>
      </Argument>
      <Argument name="log">
        <Description>
          The log object associated with the SailPointContext.
        </Description>
      </Argument>
      <Argument name='config'>
        <Description>
          Map of arguments, including identityName.
        </Description>
      </Argument>
    </Inputs>
    <Returns>
      <Argument name='email'>
        <Description>
          The string value of the user's email address
        </Description>
      </Argument>
    </Returns>
  </Signature>  
<Source>
  import sailpoint.object.Identity;
  //this value context entry point sailpoint interact with the sailpoint db
  Identity identity = context.getObjectByName(Identity.class, config.get("identityName"));
  if (null != identity) {
      System.out.println("Found the Identity: Name = " + identity.getName() + ", Email address = " + identity.getEmail());
      // [1] Replace with code to return manager email address
      //-------------------------------------
      //return identity.getEmail();this attribute value will returned by the rule when the requested identity is found
	  
      	return getManagerEmail(identity.getName());
      //-------------------------------------
  }

  </Source>
</Rule>
  1. Rule TRNG-LookupRuleArgs.xml
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Map PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Map>
   <entry key="config">
    <value>
     <Map>
       <entry key="identityName" value="Adam.Kennedy"/>
     </Map>
    </value>
   </entry>
</Map>

in Rule 1 where i can find this provisioning group?

also this connection with the db (I already create the same db)

Do you have manager for the Identity Adam.Kennedy in your IIQ Setup ?

yes
image

I solve it was missing the

    <ReferencedRules>
        <Reference class="sailpoint.object.Rule" name="UtilRuleLibrary"/>
    </ReferencedRules>
2 Likes

Looks like a good example of Rubber Duck Debugging :smiley:

@Remold actually a tricky one because is two steps to take into account, first import the rule, then edit and the reference, and miss that point

1 Like

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