Pre-delegation rule

Good night community

Im working in a rule, with this rule I want to achive to predelagate some record’s in a certificacion, I mean if one of my record’s certification belongs to the workgroups “Executive Workgroups“ this one need has to be delegation for the workgroup “SAC TEAM“. Here is mi current rule, and I set on the Pre-delegation rule for a manager certification type, the certification is already stagin period, I have 2 doubts

The rule starting to work when the certification is already active?, In my rule I Misisng something due to I dont see the SAC TEAM on the column certifier’s ?

Im using IIIQ v8.4

````````````````````````````````````````````````````````````
String executiveWorkGroup = “Workgroup Executive Members”;
String sacWorkGroup = “Access Request SAC Team”;
Map resultado = new  HashMap();
CertificationEntity ce = (CertificationEntity)entity;
Identity duenoActual = null;    
if(ce != null) {
    	duenoActual = ce.getOwner();
    }
    
    if(duenoActual != null){
    	if(executiveWorkGroup.equalsIgnoreCase(duenoActual.getName())) {
    	Identity sacWork = context.getObjectByName(Identity.class,sacWorkGroup);
    		if(sacWork !=null) {
    		resultado.put("recipientName", sacWork);
    		resultado.put("reassign",Boolean.TRUE);
    		resultado.put("comments","Certifiacador original: "+executiveWorkGroup);

return resultado
``````````````````````````````````````````````````````````````````````````````

thanks community for the advice.

hi @BrianJ

You are on the right track with your rule logic, but I can help clarify a few things and suggest improvements.

:white_check_mark: To answer your questions:

  1. Does the rule work if the certification is already active?
    No — pre-delegation rules only apply during the staging phase of a certification. If the certification is already active, the rule won’t retroactively apply. You’d need to either:
  • Revert the certification to staging (if possible), or
  • Apply delegation manually or via a different mechanism.
  1. Why don’t you see the SAC TEAM in the certifier column?
    A few possibilities:
  • The getOwner() method might not be returning the expected identity (e.g., a user instead of a workgroup).
  • The name comparison might be failing due to formatting or case sensitivity.
  • The rule might not be triggered at all if the condition isn’t met.

I would try below:


String executiveWorkGroup = "Workgroup Executive Members";
String sacWorkGroup = "Access Request SAC Team";
Map resultado = new HashMap();
CertificationEntity ce = (CertificationEntity) entity;

if (ce != null && ce.getOwner() != null) {
    Identity owner = ce.getOwner();
    
    if (executiveWorkGroup.equalsIgnoreCase(owner.getName())) {
        Identity sacTeam = context.getObjectByName(Identity.class, sacWorkGroup);
        
        if (sacTeam != null) {
            resultado.put("recipientName", sacTeam);
            resultado.put("reassign", Boolean.TRUE);
            resultado.put("comments", "Certificador original: " + executiveWorkGroup);
        } else {
        }
    }
}

return resultado;

Good Mornning @haideralishaik

I made the next update to the rule. but Im still face off the same problem, if I not wrong this instruction resultado.put(“reassign”,Boolean.TRUE); reassign to the workgroup “TEST_BA“, but I dont see the workgroup TEST_BA on the column Certifiers

I dont understand what I missing.

import sailpoint.object.*;
import org.apache.log4j.Logger;
import org.jfree.util.Log;
import org.apache.commons.logging.*;
import java.util.ArrayList;
import java.util.List;
import sailpoint.object.CertificationEntity;
import sailpoint.tools.GeneralException;
import java.util.HashMap;
import java.util.Map;

Logger customLog = Logger.getLogger("com.Santander.CustomLog");
customLog.debug("predelegation manager rule : Start");
	
String executiveWorkGroup = "Santander Workgroup Executive Members";
String baWorkGroup = "TEST_BA";
Map resultado = new  HashMap();
CertificationEntity ce = (CertificationEntity)entity;
Identity duenoActual = null;
boolean bandera = false;
        
if(ce != null) {
duenoActual = ce.getOwner();
        }

 if(duenoActual != null) {
List<Workgroup> userGroup = duenoActual.getWorkgroups();
if(userGroup !=null) {
for(Workgroup wg : userGroup) {
 if(executiveWorkGroup.equals(wg.getName())) {
  bandera = true;
     break;
  }
      }
        }
 if(bandera) {

  customLog.debug("the certifier"+duenoActual.getName()+
   "belongs: "+executiveWorkGroup+
    "delegation to: "+baWorkGroup);

      resultado.put("recipientName",baWorkGroup);
      resultado.put("reassign",Boolean.TRUE);

        	} else {
        		customLog.debug("the certifier"+duenoActual.getName()+
        				"doesn't belong"+executiveWorkGroup);
        	}
        }else {
        	customLog.debug("the original certifier doesn't retrive");
        }
        
        return resultado;




Hello @BrianJ,
Replace Workgroup with Identity. Because there is no Workgroup object.

hi @BrianJ

Yes, #### recipientName should be an Identity object, not a String

You are currently passing a string (baWorkGroup ) as the recipient. IdentityIQ expects an Identity object for delegation.

:white_check_mark: Fix: Replace this line:

resultado.put(“recipientName”, baWorkGroup);

With:


Identity baIdentity = context.getObjectByName(Identity.class, baWorkGroup);
if (baIdentity != null) {
    resultado.put("recipientName", baIdentity);
    resultado.put("reassign", Boolean.TRUE);
}

Good night @haideralishaik and @Harikrishna_06

Thanks for the suggestion, I made the update on the rule but I noticed one thing is not working from the begin, is failing on the second “if”, due to on my log’s go to the final “else“ I need to understand with this instrucction what I reading, the record’s of the list one by one on the column certifier or all of it what I have inside of each record? this is my output log

CertificationEntity ce = (CertificationEntity)entity;

thanks for your support community

hi @BrianJ

Thanks for the update! Based on your logs, the rule is failing at this line:

CertificationEntity ce = (CertificationEntity) entity;

The issue is that ce.getOwner() is returning null, which means the certifier isn’t being retrieved correctly. This usually happens if the certifier is a workgroup and not an Identity.

:white_check_mark: To fix this, try checking the type before casting:



Object owner = ce.getOwner();
if (owner instanceof Identity) {
    Identity duenoActual = (Identity) owner;
    // continue with your logic
} else {
    customLog.debug("Owner is not an Identity: " + owner.getClass().getName());
}

Good Night @haideralishaik

Do you mean I have to do the next ?

I disabled the first “if”, and you right “ce” object is getting a “null” I did the next certification but It shows the next exception

		String executiveWorkGroup = "Santander Workgroup Executive Members";
        String baWorkGroup = "TEST_BA";
        Map resultado = new  HashMap();
        CertificationEntity ce = (CertificationEntity)entity;
        Identity duenoActual = null;
         boolean bandera = false;

/*
if(ce != null) {
duenoActual = ce.getOwner();
}
*/
    Object owner = ce.getOwner();
    if(owner instanceof Identity) {
    	duenoActual = (Identity)owner;
    	List<Identity> userGroup = duenoActual.getWorkgroups();
    	if(userGroup !=null) {
    		for(Identity wg : userGroup) {
    			if(executiveWorkGroup.equals(wg.getName())) {
    				bandera = true;
    				break;
    			}
    		}
    	}
    	Identity baIdentity = context.getObjectByName(Identity.class,baWorkGroup);
    	if(bandera && baIdentity != null) {
    		customLog.debug("El certificador "+duenoActual.getName()+
    				"es miembro de "+executiveWorkGroup+"delegado a: "+baWorkGroup);
    		resultado.put("recipientName",baIdentity);
    		resultado.put("reassign",Boolean.TRUE);
    	} else {
    		customLog.debug("El cerificador "+duenoActual.getName()+
    				" no pertenece al workgroup: "+executiveWorkGroup);
    	}
    }else {
    	customLog.debug("Owner is not a identity "+ owner.getClass().getName());
    }
    
    return resultado;

}

thanks again

hi @BrianJ

You’re getting a NullPointerException at runtime because the rule is trying to invoke a method on a null object. Specifically, cause:

Object owner = ce.getOwner();
if ce is null , or ce.getOwner() returns null , any method call on it (like getName() or casting) will throw this exception.

Add null checks before using the object. Here’s a safe version of the logic:

CertificationEntity ce = (CertificationEntity) entity;
if (ce != null) {
    Object owner = ce.getOwner();
    if (owner instanceof Identity) {
        Identity duenoActual = (Identity) owner;
        // continue with your logic
    } else {
        customLog.debug("Owner is not an Identity or is null");
    }
} else {
    customLog.debug("CertificationEntity is null");
}
1 Like

Good night @haideralishaik

I made the update as you say, but I still have the null pointerexception in the run time , I did another idea, but is the same issue, I know the reason is not working due to the ce is a null value, but when I run I dont know why doesn’t enter on the next instruction “certificationentity is null“ or the instruction “the certification has not items“

    CertificationEntity ce = (CertificationEntity)entity;
	List<CertificationItem> items = ce.getItems();
	
	if(items == null || items.isEmpty()) {
		customLog.debug("the certification has not items");
	}else {
		
    if(ce != null) {
    	Object owner = ce.getOwner();   
    if(owner instanceof Identity) {
    	duenoActual = (Identity)owner;
    	List<Identity> userGroup = duenoActual.getWorkgroups();
    	if(userGroup !=null) {
    		for(Identity wg : userGroup) {
    			if(executiveWorkGroup.equals(wg.getName())) {
    				bandera = true;
    				break;
    			}
    		}
    	}
    	Identity baIdentity = context.getObjectByName(Identity.class,baWorkGroup);
    	if(bandera && baIdentity != null) {
    		customLog.debug("El certificador "+duenoActual.getName()+
    				"es miembro de "+executiveWorkGroup+"delegado a: "+baWorkGroup);
    		resultado.put("recipientName",baIdentity);
    		resultado.put("reassign",Boolean.TRUE);
    	} else {
    		customLog.debug("El cerificador "+duenoActual.getName()+
    				" no pertenece al workgroup: "+executiveWorkGroup);
    	}
    }else {
    	customLog.debug("Owner is not a identity "+ owner.getClass().getName());
    }
    
   } else {
    	customLog.debug("CertificationEntity is null");
    }
	} 
    return resultado;

Hi @BrianJ,

Please refer to this code and make changes to your code accordingly.

Good night @Harikrishna_06

I updated the code, but two thing’s I dont understand I have miss match type class exception, due to on the argument’s I can pass String data, and my other doubt is why you set a List at the beginning? I mean could I use this function getCerfiers() instead entity , this is my code and my exception

    CertificationEntity ce = (CertificationEntity)entity;
  
    
	if(ce != null) {
		
		String currentIdentity = ce.getIdentity();
		duenoActual = context.getObjectByName(Identity.class,currentIdentity);
		customLog.warn("current  owner for certification is: "+ce.getName());
	}else if(ce == null) {
		customLog.warn("the ce variable is null");
	}
	
	if(duenoActual != null) {
    	List<Identity> userGroup = duenoActual.getWorkgroups();
    	if(userGroup !=null) {
    		for(Identity wg : userGroup) {
    			if(executiveWorkGroup.equals(wg.getName())) {
    				bandera = true;
    				break;
    			}
    		}
    	}
    	Identity baIdentity = context.getObjectByName(Identity.class,baWorkGroup);
    	if(bandera && baIdentity != null) {
    		customLog.warn("El certificador "+duenoActual.getName()+
    				"es miembro de "+executiveWorkGroup+"delegado a: "+baWorkGroup);
    		resultado.put("recipientName",baIdentity);
    		resultado.put("reassign",Boolean.TRUE);
    	} else {
    		customLog.warn("El cerificador "+duenoActual.getName()+
    				" no pertenece al workgroup: "+executiveWorkGroup);
    	}
    }else {
    	customLog.warn("Owner is not a identity "+ duenoActual.getClass().getName());
    }
    
    

    return resultado;

Im running out of ideas :exploding_head:

Hi @BrianJ,

Could you please update the following line in your code:

resultado.put(“recipientName”, baIdentity);

to:

resultado.put(“recipientName”, baWorkGroup);

The reason for this change is that recipientName expects a value of type String, but currently you’re passing an Identity type. To ensure type compatibility and avoid potential runtime issues, it should be updated to a String.

Good night @Harikrishna_06 and @haideralishaik

Finally work’s, I really appreaciate your support and the suggestion´s in wich to updated the rule. the rule is forwarding to the TEST_BA workgroup, just I have another doubt why in the next line I couldn’t pass an Identityobject? and just only java datatype such as String, int, boolean, etc.

duenoActual = context.getObjectByName(Identity.class,currentIdentity);

this is the current version

Logger customLog = Logger.getLogger("com.Santander.CustomLog");
		customLog.info("predelegation manager rule : Start");
		String executiveWorkGroup = "Santander Workgroup Executive Members";
        String baWorkGroup = "TEST_BA";
        Map resultado = new  HashMap();
        Identity duenoActual = null;
        boolean bandera = false;
        CertificationEntity ce = (CertificationEntity)entity;
      
        
    	if(ce != null) {
    		
    		String currentIdentity = ce.getIdentity();
    		duenoActual = context.getObjectByName(Identity.class,currentIdentity);
    		customLog.warn("current  owner for certification is: "+ce.getName());
    	}else if(ce == null) {
    		customLog.warn("the ce variable is null");
    	}
    	
    	if(duenoActual != null) {
        	List<Identity> userGroup = duenoActual.getWorkgroups();
        	if(userGroup !=null) {
        		for(Identity wg : userGroup) {
        			if(executiveWorkGroup.equals(wg.getName())) {
        				bandera = true;
        				break;
        			}
        		}
        	}
        	
        	if(bandera) {
        		customLog.warn("El certificador "+duenoActual.getName()+
        				"es miembro de "+executiveWorkGroup+"delegado a: "+baWorkGroup);
        		resultado.put("recipientName",baWorkGroup);
        		resultado.put("reassign",Boolean.TRUE);
        	} else {
        		customLog.warn("El cerificador "+duenoActual.getName()+
        				" no pertenece al workgroup: "+executiveWorkGroup);
        	}
        }else {
        	customLog.warn("Owner is not a identity "+ duenoActual.getClass().getName());
        }
        
        
	
        return resultado;
1 Like