Certification Rule for Entitlement isCertifiable

Which IIQ version are you inquiring about?

Version 8.2

Share all details related to your problem, including any error messages you may have received.

I am working on an exclusion rule that should omit entitlements that have the attribute “isCertifiable” == FALSE. This is a string value. Below is the code I have and the error I am running into.

Error:
An unexpected error occurred: BeanShell script error: bsh.EvalError: Sourced file: inline evaluation of: import java.util.Iterator; import java.util.List; import sailpoint.object. . . . '' : Typed variable declaration : Error in method invocation: Method get(java.lang.String) not found in class'sailpoint.object.EntitlementGroup' : at Line: 26 : in file: inline evaluation of: import java.util.Iterator; import java.util.List; import sailpoint.object. . . . ‘’ : entGroup .get ( “isCertifiable” ) BSF info: Sentry Certification Exclusion Rule at line: 0 column: columnNo

Code:
import java.util.Iterator;
import java.util.List;
import sailpoint.object.Bundle;
import sailpoint.object.Certifiable;
import sailpoint.object.*;
import sailpoint.object.EntitlementGroup;

Iterator iter = items.iterator();

while (iter.hasNext()) {
Certifiable cert = (Certifiable) iter.next();

log.warn( "The cert is of type " + cert.getClass()); 
if (cert != null ) { 
  // Item = EntitlementGroup 
  if (cert instanceof EntitlementGroup) { 
    EntitlementGroup entGroup = (EntitlementGroup) cert; 

    if (entGroup != null ) { 

      if (entGroup.getAttributes() != null ) { 
        sailpoint.object.EntitlementGroup item = (sailpoint.object.EntitlementGroup) iter.next(); 
        String groupName = entGroup.getDisplayName(); 
        log.warn("Display Name" + groupName);
                 
        String isCertifiable = entGroup.get("isCertifiable"); 
        log.warn("You are here");

        if (isCertifiable.equalsIgnoreCase("FALSE")) { 

          itemsToExclude.add(objItem); 
          iter.remove(); 

        } 

      } 
      else { 
        continue ; 
      } 

    }
  }
}

}

return “Removed Entitlement”;

Hi @Alyson_Trad

Change the below line
String isCertifiable = entGroup.get("isCertifiable");

to
String isCertifiable = entGroup.getAttribute("isCertifiable");

Then try again.

Thanks
Krish

1 Like

@MVKR7T Thank you for the reply! I have updated this code and am still getting a similar error. I also tried getAttributeValue.

Error:
Typed variable declaration : Error in method invocation: Method getAttribute(java.lang.String) not found in class’sailpoint.object.EntitlementGroup’ : at Line: 26 : in file: inline evaluation of: ``import java.util.Iterator; import java.util.List; import sailpoint.object. . . . ‘’ : entGroup .getAttribute ( “isCertifiable” ) BSF info: Sentry Certification Exclusion Rule at line: 0 column: columnNo

Ya, Checked the Java doc for EntitlementGroup, there is no getAttribute() method but it has setAttribute() method.

Anyway, We have getAttributes() method.

import sailpoint.object.Attributes;

Attributes attrs = entGroup.getAttributes();
String isCertifiable = attrs.get("isCertifiable");

This should work.

We can get Map object from Attributes object and can get a specific attribute as well.

import sailpoint.object.Attributes;
import java.util.Map;

Attributes attrs = entGroup.getAttributes();
Map map = attrs.getMap();
String isCertifiable = map.get("isCertifiable");

Thanks
Krish

I see with my logging statements that it is not actually grabbing the entitlement attributes, but instead the value of the entitlement.

Logs:
Attribute: {memberOf=CN=CL Policy ODS Adhoc Universe Users,OU=Groups,DC=TESTEnv,DC=com}
2023-11-28 09:48:20 WARN QuartzScheduler_Worker-15 sailpoint.server.InternalContext:-1 - Map: {memberOf=CN=Entitlement,OU=Groups,DC=TESTEnv,DC=com}
2023-11-28 09:48:20 WARN QuartzScheduler_Worker-15 sailpoint.server.InternalContext:-1 - This isnull

Code:

import java.util.Iterator; import java.util.List; import sailpoint.object.Bundle; import sailpoint.object.Certifiable; import sailpoint.object.*; import sailpoint.object.EntitlementGroup; import sailpoint.object.Attributes; import java.util.Map;

Iterator iter = items.iterator();

while (iter.hasNext()) {
Certifiable cert = (Certifiable) iter.next();

log.warn( "The cert is of type " + cert.getClass()); 
if (cert != null ) { 

  if (cert instanceof EntitlementGroup) { 
    EntitlementGroup entGroup = (EntitlementGroup) cert; 

    if (entGroup != null ) { 

      if (entGroup.getAttributes() != null ) { 
        sailpoint.object.EntitlementGroup item = (sailpoint.object.EntitlementGroup) iter.next(); 
        String groupName = entGroup.getDisplayName(); 
        log.warn("Display Name" + groupName);

        Attributes attrs = entGroup.getAttributes();
        log.warn("Attribute: " + attrs);

        Map map = attrs.getMap();
        log.warn("This is my map: " + map);

        String isCertifiable = attrs.get("isCertifiable");
        log.warn("This is" + isCertifiable);

        if (isCertifiable.equalsIgnoreCase("FALSE")) { 

          log.warn("this is not certifiable");

          itemsToExclude.add(entGroup); 
          iter.remove(); 

        } 

      } 
      else { 
        continue ; 
      } 

    }
  }
}

}

return “Removed Entitlement”;

Print the EntitlementGroup object

log.warn("Entitlement Group object::" + entGroup.toXml());

and see if isCertifiable attribute is there or not.

if it is there, you will get an idea to extract it.

From entGroup you can get Entitlement name and application related details, using that you have to fetch the Managed Attribute Object and find if the entitlement is certifiable or not, you cannot get it directly from Entitlement group Object, if you need complete code help for this let me know, I can give but this should be your approach.

Try this Code and See if this works for you

Please keep posted once you test

if(entGrp.getAttributes()!= null){
Attributes atts = entGrp.getAttributes();

List entlist = atts.getKeys();
Iterator entit = entlist.iterator();
while (entit.hasNext()) {
String attrname = entit.next();
String attrval = atts.getString(attrname);

String appName = entGrp.getApplicationName();
Application app1 = context.getObjectByName(Application.class, appName);
ManagedAttribute ma = ManagedAttributer.get(context, app1, attrname, attrval);
if (ma != null) {

if (ma.getAttributes().get("isCertifiable") != null){
        String isCertifiable = ma.getAttributes().get("isCertifiable");
if (isCertifiable.equalsIgnoreCase("FALSE")) { 

          itemsToExclude.add(entGrp); 
          iter.remove(); 

        } 
}
}
}
}
1 Like

Thanks for the suggestion!
I tested this code, but its not liking the get() method for ManagedAttributes.

Error:
An unexpected error occurred: BeanShell script error: bsh.EvalError: Sourced file: inline evaluation of: import java.util.Iterator; import java.util.List; import sailpoint.object. . . . '' : Typed variable declaration : Error in method invocation: Static method get(sailpoint.server.InternalContext, sailpoint.object.Application, java.lang.String, java.lang.String) not found in class'sailpoint.object.ManagedAttribute' : at Line: 35 : in file: inline evaluation of: import java.util.Iterator; import java.util.List; import sailpoint.object. . . . ‘’ : ManagedAttribute .get ( context , app1 , attrname , attrval ) BSF info: Sentry Certification Exclusion Rule at line: 0 column: columnNo

Code:

import java.util.Iterator; import java.util.List; import sailpoint.object.Bundle; import sailpoint.object.Certifiable; import sailpoint.object.*; import sailpoint.object.EntitlementGroup; import sailpoint.object.Attributes; import java.util.Map;

Iterator iter = items.iterator();

while (iter.hasNext()) {
Certifiable cert = (Certifiable) iter.next();

log.warn( "The cert is of type " + cert.getClass()); 
if (cert != null ) { 

  if (cert instanceof EntitlementGroup) { 
    EntitlementGroup entGrp = (EntitlementGroup) cert; 

    if (entGrp != null ) { 

      if(entGrp.getAttributes()!= null){
        Attributes atts = entGrp.getAttributes();

        List entlist = atts.getKeys();
        Iterator entit = entlist.iterator();
        
        while (entit.hasNext()) {
          String attrname = entit.next();
          String attrval = atts.getString(attrname);

          String appName = entGrp.getApplicationName();
          Application app1 = context.getObjectByName(Application.class, appName);
          ManagedAttribute ma = ManagedAttribute.get(context, app1, attrname, attrval);
          
          if (ma != null) {

            if (ma.getAttributes().get("IsCertiable") != null){
              String isCertifiable = ma.getAttributes().get("IsCertiable");
              if (isCertifiable.equalsIgnoreCase("FALSE")) { 

                itemsToExclude.add(entGrp); 
                iter.remove(); 

              } 
            }
          }
        }
      }  

    }
  }
}

}

return “Removed Entitlement”;

This is not managedAttribute , it is this one

import sailpoint.api.ManagedAttributer;

Use ManagedAttributer in that particular line of code and import the above

That resolved the error I was seeing.

When looking at the certification, the groups marked as FALSE for isCertifiable are still showing in the certification. Is that expected?
I am not the owner of the certification so im not sure if it just greys out the option to remove.

@Alyson_Trad

Is this certifications which are already created or the new ones after doing the field update?

I just tried a fresh certification this morning and it looks to still be including those entitlement.
I see, when I click on the details of the entitlement, that it is isCertifiable: FALSE.

In the code it was mentioned as IsCertifiable and in your comment it is mentioned as isCertifiable, there is a case difference, not sure if it is just a typo here while sending but anyhow , can you share the complete updated code you are using and one of the enitlement from Debug page which is part of Certification and still isCertifiable false.

I have verified it is isCertifiable. I updated it all in the code to reflect this and created a new certification. Looks like they are still sticking on the certification.

import java.util.Iterator; import java.util.List; import sailpoint.object.Bundle; import sailpoint.object.Certifiable; import sailpoint.object.*; import sailpoint.object.EntitlementGroup; import sailpoint.object.Attributes; import java.util.Map; import sailpoint.api.ManagedAttributer;

Iterator iter = items.iterator();

while (iter.hasNext()) {
Certifiable cert = (Certifiable) iter.next();

log.warn( "The cert is of type " + cert.getClass()); 
if (cert != null ) { 

  if (cert instanceof EntitlementGroup) { 
    EntitlementGroup entGrp = (EntitlementGroup) cert; 

    if (entGrp != null ) { 

      if(entGrp.getAttributes()!= null){
        Attributes atts = entGrp.getAttributes();

        List entlist = atts.getKeys();
        Iterator entit = entlist.iterator();
        
        while (entit.hasNext()) {
          String attrname = entit.next();
          String attrval = atts.getString(attrname);

          String appName = entGrp.getApplicationName();
          Application app1 = context.getObjectByName(Application.class, appName);
          ManagedAttribute ma = ManagedAttributer.get(context, app1, attrname, attrval);
          
          if (ma != null) {

            if (ma.getAttributes().get("isCertiable") != null){
              String isCertifiable = ma.getAttributes().get("isCertiable");
              if (isCertifiable.equalsIgnoreCase("FALSE")) { 

                itemsToExclude.add(entGrp); 
                iter.remove(); 

              } 
            }
          }
        }
      }  

    }
  }
}

}

return “Removed Entitlement”;

Can you share one of the entitlement ( xml) from debug page which should satisfy above rule but still showing in Certification

Absolutely. See below:

I don’t see anything, looks like missed the attachment.

Hi @Alyson_Trad,

I have made slight change to the code to check whether the attributes are null before checking the isCertifiable attribute.

import java.util.Iterator; 
import java.util.List; 
import sailpoint.object.Bundle; 
import sailpoint.object.Certifiable; 
import sailpoint.object.*; 
import sailpoint.object.EntitlementGroup; 
import sailpoint.object.Attributes; 
import java.util.Map; 
import sailpoint.api.ManagedAttributer;

Iterator iter = items.iterator();
String explanation = "";
while (iter.hasNext()) {
  Certifiable cert = (Certifiable) iter.next();
  
  log.warn( "The cert is of type " + cert.getClass()); 
  if (cert != null ) { 
    if (cert instanceof EntitlementGroup) { 
      EntitlementGroup entGrp = (EntitlementGroup) cert; 
      if (entGrp != null ) { 
        if(entGrp.getAttributes()!= null){
          Attributes atts = entGrp.getAttributes();
          List entlist = atts.getKeys();
          Iterator entit = entlist.iterator();
          while (entit.hasNext()) {
            String attrname = entit.next();
            String attrval = atts.getString(attrname);
            String appName = entGrp.getApplicationName();
            Application app1 = context.getObjectByName(Application.class, appName);
            ManagedAttribute ma = ManagedAttributer.get(context, app1, attrname, attrval);
            if (ma != null) {
              if (ma.getAttributes() != null && ma.getAttributes().get("isCertiable") != null){
                String isCertifiable = ma.getAttributes().get("isCertiable");
                if (isCertifiable.equalsIgnoreCase("FALSE")) { 
                  itemsToExclude.add(entGrp); 
                  iter.remove(); 
                  explanation = "Removed Entitlement";
                } 
              }
            }
          }
        }
      }
    }
  }
}

return explanation;

If the code is still not working, please make sure to check couple of things.

  • Attribute Name : As Satish mentioned double check the attributeName with case. If there is a change in attribute replace isCertiable with the correct attribute name.
  • Attribute Type : Also check the type of the extended attribute, if the type is boolean please change this line if (isCertifiable.equalsIgnoreCase("FALSE")) to
if (isCertifiable.equalsIgnoreCase(false))

@iamksatish @Jarin_James Thank you both for your help, looks like the above code is working now.

I did notice the isCertifiable was mis-spelt in the previous code which also contributed to this issue.