Policy working for detective but not for preventive

Below code is working fine detective policy, but it failing at the for preventive policy.

When i enabled the log it prints “iterator creator” and it fails from logger.debug(“iterationhasnext” + it.hasNext());

 if(Util.isNotNullOrEmpty(identityType) && Util.isNotNullOrEmpty(identityCorpid) && identityType.equalsIgnoreCase("individual")){ 


    logger.debug("Inside if condition - individual identities");

    QueryOptions qo = new QueryOptions();

    Filter filter = Filter.and(Filter.join("value", "ManagedAttribute.value"),
                               Filter.join("application", "ManagedAttribute.application"),
                               Filter.join("name", "ManagedAttribute.attribute"));

    qo.addFilter(filter);
    qo.addFilter(Filter.eq("ManagedAttribute.iiqElevatedAccess", true));

    qo.addFilter(Filter.eq("identity.id", identity.getId()));
    qo.addFilter(Filter.eq("aggregationState", "Connected"));

    Iterator it = context.search(IdentityEntitlement.class, qo,"id"); 
    logger.debug("iterator created");
    logger.debug("iterationhasnext" + it.hasNext());

    try{
      logger.debug("iterationhasnext" + it.hasNext());
      while (it.hasNext()) {
        logger.debug("Elevated access has been encountered for the Corp ID");
}}

Below is the error message i am getting.
*** An unexpected error occurred: The application script threw an exception: java.lang.NullPointerException: Null Pointer in Method Invocation BSF info: Policy-Name at line: 0 column: columnNo**

any thoughts why it is failing for preventive and working fine for detective ?

@guduru510 -

To resolve the NullPointerException in the preventive policy while the detective policy works, follow these steps:


Root Cause Analysis

The error occurs because it.hasNext() is called on a null iterator (it). The preventive policy likely runs in a context where the query context.search(...) returns null (e.g., invalid query parameters, missing data), whereas the detective policy has valid data. Key differences:

  1. Timing: Preventive policies run before an action is committed (e.g., identity creation), so referenced data (e.g., identity.getId()) might not exist.
  2. Query Validity: The query might reference fields unavailable in the preventive context (e.g., identity.id for a new identity).

Solution

1. Add Null Checks for Critical Objects

  • Ensure identity and identity.getId() are not null before building the query:
    if (identity == null) {
        logger.debug("Identity is null. Exiting.");
        return;
    }
    String identityId = identity.getId();
    if (identityId == null) {
        logger.debug("Identity ID is null. Exiting.");
        return;
    }
    

2. Validate Query Parameters

  • Avoid passing null values to filters (e.g., Filter.eq("identity.id", identityId) fails if identityId is null):
    qo.addFilter(Filter.eq("identity.id", identityId)); // Only if identityId != null
    

3. Handle Null Iterator Safely

  • Check if the iterator it is null before using it:
    Iterator it = context.search(IdentityEntitlement.class, qo, "id"); 
    if (it == null) {
        logger.debug("Iterator is null. No entitlements found.");
        return;
    }
    logger.debug("iterationhasnext: " + it.hasNext());
    

4. Use Try-Catch Blocks

  • Wrap the query and iteration in a try-catch to handle exceptions:
    try {
        Iterator it = context.search(...);
        if (it == null) return;
        while (it.hasNext()) { ... }
    } catch (Exception e) {
        logger.error("Query failed: " + e.getMessage());
    }
    

5. Log Critical Variables

  • Add debug logs to inspect values in both policies:
    logger.debug("Identity ID: " + identityId);
    logger.debug("Query Options: " + qo.toXml());
    

Why Preventive Policies Fail

  • New Identities: In preventive mode, identity.getId() might be null if the identity hasn’t been saved yet.
  • Invalid Queries: The query Filter.eq("identity.id", ...) fails if identity.id is null.
  • Missing Entitlements: Entitlements (e.g., ManagedAttribute) might not be linked during preventive checks.

Final Code Adjustments

if (Util.isNotNullOrEmpty(identityType) && Util.isNotNullOrEmpty(identityCorpid) && identityType.equalsIgnoreCase("individual")) {
    logger.debug("Inside if condition - individual identities");

    // Check if identity and identity.getId() are valid
    if (identity == null) {
        logger.debug("Identity is null. Exiting.");
        return;
    }
    String identityId = identity.getId();
    if (identityId == null) {
        logger.debug("Identity ID is null. Exiting.");
        return;
    }

    QueryOptions qo = new QueryOptions();
    Filter filter = Filter.and(
        Filter.join("value", "ManagedAttribute.value"),
        Filter.join("application", "ManagedAttribute.application"),
        Filter.join("name", "ManagedAttribute.attribute")
    );
    qo.addFilter(filter);
    qo.addFilter(Filter.eq("ManagedAttribute.iiqElevatedAccess", true));
    qo.addFilter(Filter.eq("identity.id", identityId)); // Use validated identityId
    qo.addFilter(Filter.eq("aggregationState", "Connected"));

    try {
        Iterator it = context.search(IdentityEntitlement.class, qo, "id");
        logger.debug("iterator created");
        if (it == null) {
            logger.debug("Iterator is null. Exiting.");
            return;
        }
        logger.debug("iterationhasnext: " + it.hasNext());
        while (it.hasNext()) {
            logger.debug("Elevated access encountered for Corp ID");
        }
    } catch (Exception e) {
        logger.error("Error during query: " + e.getMessage());
    }
}

Additional Notes

  • Preventive Policy Context: Ensure the policy is configured to receive the correct identity object (e.g., during provisioning workflows).
  • Field Availability: Confirm ManagedAttribute.iiqElevatedAccess exists and is accessible in the preventive context.

By addressing these issues, the preventive policy should behave consistently with the detective policy.

Hope this helps.

We are not creating the Identity here and we are only checking if the user selected managed attribute is elevate or not. if it is elevated then do an preventive policy.

I think null check will prevent the exception only but policy evaluation won’t remain accurate

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