Every WorkItem has a WorkflowCase!
If you want to delete a WorkItem you have the delete the mother object, the WorkflowCases.
If you only delete the WorkItem, the WorkflowCase can get stuck forever in your system. That is bad and can cause errors in other processes and tasks.
I deliver a Rule in this article to delete a WorkItem and its WorflowCase in a clean way. Often there are many WorkItems created by the Refresh Identity Cube Task.
Sometimes there are some you do not want to have in the system. Normally you have to find the root cause of these wrongly created items.
Delete one single WorkItem/WorkflowCase (search this tag sequence in the WorkItem):
</Requester>
<WorkflowCaseRef>
<Reference class="sailpoint.object.WorkflowCase" name="QuickLink Launch for identity spadmin - 1"/>
</WorkflowCaseRef>
</WorkItem>
With this name you find the WorkflowCase in the debug-page.
To delete multiple WorkflowCases you can use the following Rule:
This Rule can delete old WorkflowCases.
You can define a simulation mode. Use it to have a dry run and see what you are doing before starting this rule.
Also there is a time gap in days. 0 means all WorkflowCases. 1 means all WFCases older than 1 day.
The workflowCaseName is a startsWith Filter. Here you have to already know the name of your WorkflowCase names to delete.
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE Rule PUBLIC "sailpoint.dtd" "sailpoint.dtd">
<Rule language="beanshell" name="Delete Old WorkflowCases">
<Description>
Searches for WorkflowCases and terminates them.
</Description>
<Source>
import sailpoint.object.*;
import sailpoint.api.Terminator;
import java.util.*;
import org.apache.log4j.Logger;
import org.apache.log4j.Level;
Logger logger = Logger.getLogger("de.rule.DeleteOldWorkflowCases");
logger.setLevel(Level.INFO);
boolean simulation = false;
String workflowCaseName = "QuickLink Launch for identity spadmin";
// Set this Ineteger to the days how long workflowCases should be kept. ex.: 1 = delete all WFCases older than 1 day !
int daysGapToDelete = 0;
int countDeletedWorkflows = 0;
Map keepCaseMap = new HashMap();
logger.info("Delete Old Refresh gestartet -->" + workflowCaseName);
Terminator term = new Terminator(context);
// Now minus gap days
Calendar cal = new GregorianCalendar();
cal.add(Calendar.DATE, -daysGapToDelete);
Date cutOffDate = cal.getTime();
QueryOptions qo = new QueryOptions();
qo.addFilter(Filter.lt("created", cutOffDate ));
qo.addFilter(Filter.like("name", workflowCaseName, Filter.MatchMode.START));
Iterator it = context.search(WorkflowCase.class, qo, "id");
while(it.hasNext()){
String id = (String) it.next()[0];
WorkflowCase wfCase = context.getObject(WorkflowCase.class, id);
if(wfCase != null){
logger.info("found workflow for termination " + wfCase.getId() + " - " + wfCase.getName() );
// Delete everything
if(!keepCaseMap.containsValue(wfCase.getId()) && !simulation){
logger.info("Identity: " + wfCase.getTargetName() + " --> deleting old workflow case " + wfCase.getId() + " - " + wfCase.getName() + " " + countDeletedWorkflows);
term.deleteObject(wfCase);
countDeletedWorkflows++;
}
}else{
logger.info("workflowcase is null " + name);
}
if(!simulation){
// if (countDeletedWorkflows % 30 == 0) { // optimize performance
context.commitTransaction();
//}
}else{
logger.info("Simulation is true --> no commits");
}
}
if(!simulation){
context.commitTransaction();
}else{
logger.info("Simulation is true --> no commits");
}
logger.info("Delete Old Refresh done -->" + workflowCaseName);
return "done --> deleted --> " + countDeletedWorkflows;
</Source>
</Rule>
The Rule is also attached as file listed below.
Hi,
Thank you so much for the rule. You mentioned that the workflowCase removes only a workItem - how about the Access Request itself, that one is not removed by it? Is there a way to clean up everything at once?