Custom Target Certification Creation using Script with custom emails

Hey @AshrithaGampa, thanks for your patience.

I was able to trigger the certification and the filters were applied correctly. The issue seems to occur when I run the task manually. When I schedule the task for 1 minute in the future (effectively immediate), the certification triggers with the filters.

I also noticed that when I trigger the certification immediately instead of scheduling it, a new certification definition is created and used instead of the one I created from the template. That might be the root cause of what I was seeing. To compare, you could try both:

  • Schedule the task 1 minute ahead (this worked for me).
  • Run the task manually to see if it reproduces the issue or uses a different definition.

Let me know if this works for you. Attaching the code below.

HTH.

For context, followed the recommendations from this thread: Call certification event template in rule - #6 by Remold

import sailpoint.api.SailPointContext;
import sailpoint.object.CertificationDefinition;
import sailpoint.object.Filter;
import sailpoint.object.TaskSchedule;
import sailpoint.tools.GeneralException;
import sailpoint.tools.xml.XMLObjectFactory;
import sailpoint.tools.xml.XMLReferenceResolver;
 
import java.text.SimpleDateFormat;
import java.util.*;
 
// ==============================
// Constants
// ==============================
 
private static String TARGET_IDENTITY_NAME = "<TARGET_IDENTITY_NAME>";
private static String CERTIFIER_IDENTITY_NAME = "<CERTIFIER_IDENTITY_NAME>";
private static String TARGET_APPLICATION_NAME = "<TARGET_APPLICATION_NAME>";
private static String LAUNCHER_IDENTITY_NAME = "<LAUNCHER_IDENTITY_NAME>";
private static String CERTIFICATION_DEFINITION_TEMPLATE_NAME = "<CERTIFICATION_DEFINITION_TEMPLATE_NAME>";
 
// ==============================
// Certification Initialization
// ==============================
 
public CertificationDefinition initializeCertification(CertificationDefinition template,
                                                       String newCertificationName,
                                                       Date date) throws GeneralException {
 
    // Clone certificate from existing template
    XMLObjectFactory instance = XMLObjectFactory.getInstance();
    CertificationDefinition certificationDefinition =
            (CertificationDefinition) instance.cloneWithoutId(template, (XMLReferenceResolver) context);
 
    // Metadata
    certificationDefinition.setCreated(date);
    certificationDefinition.setModified(date);
    certificationDefinition.setName(newCertificationName);
    certificationDefinition.setShortName(newCertificationName);
    certificationDefinition.setNameTemplate(newCertificationName);
    certificationDefinition.setShortNameTemplate(newCertificationName);
 
    // Certifier
    certificationDefinition.setCertifierName(CERTIFIER_IDENTITY_NAME);
 
    // Filters
    certificationDefinition.setEntityFilterValues(Collections.singletonList(createFilter("name", TARGET_IDENTITY_NAME)));
    certificationDefinition.setEntityFilter(Filter.eq("name", TARGET_IDENTITY_NAME));
 
    certificationDefinition.setEntitlementFilterValues(Collections.singletonList(createFilter("application", TARGET_APPLICATION_NAME)));
    certificationDefinition.setEntitlementFilter(Filter.eq("application.name", TARGET_APPLICATION_NAME));
 
    // Save changes
    context.saveObject(certificationDefinition);
    context.commitTransaction();
    context.attach(certificationDefinition);
 
    return certificationDefinition;
}
 
// ==============================
// Certification Scheduling
// ==============================
 
public void scheduleCertification(String certId, String name) throws Exception {
 
    TaskSchedule taskSchedule = new TaskSchedule();
    taskSchedule.setName(name);
    taskSchedule.setLauncher(LAUNCHER_IDENTITY_NAME);
    taskSchedule.setArgument("certificationDefinitionId", certId);
    taskSchedule.setArgument("executor", "Certification Manager");
    taskSchedule.setArgument("resultName", name);
 
    // Set schedule time (example: +1 minutes from now)
    Calendar cal = Calendar.getInstance();
    cal.add(Calendar.MINUTE, 1);
 
    String cronExpression = String.format("%d %d %d %d %d %s %d",
            cal.get(Calendar.SECOND),
            cal.get(Calendar.MINUTE),
            cal.get(Calendar.HOUR_OF_DAY),
            cal.get(Calendar.DAY_OF_MONTH),
            cal.get(Calendar.MONTH) + 1,
			"?",
            cal.get(Calendar.YEAR));
 
    taskSchedule.setCronExpressions(Collections.singletonList(cronExpression));
 
    context.saveObject(taskSchedule);
}
 
// ==============================
// Certification Triggering
// ==============================
 
public String triggerCertification() {
 
    try {
        String currentDateTime = new SimpleDateFormat("MM/yyyy/dd HH:mm:ss z")
                .format(Calendar.getInstance().getTime());
 
        String newCertificationName = "Rule Run Certification - " + TARGET_IDENTITY_NAME + " [" + currentDateTime + "]";
 
        CertificationDefinition template = context.getObject(CertificationDefinition.class, CERTIFICATION_DEFINITION_TEMPLATE_NAME);
 
        CertificationDefinition newCert = initializeCertification(template, newCertificationName,
                new Date());
 
        scheduleCertification(newCertificationName, "sched-" + newCertificationName);
 
    } catch (Exception e) {
        e.printStackTrace();
    }
 
    return "Completed";
}
 
// ==============================
// Utility Methods
// ==============================
 
private Map createFilter(String property, String value) {
    Map filter = new HashMap();
    filter.put("operation", "Equals");
    filter.put("property", property);
    filter.put("value", value);
    return filter;
}

new return triggerCertification();