cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

#Rule the world: Delete work item(s) and workflow case(s)

#Rule the world: Delete work item(s) and workflow case(s)

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()) &amp;&amp; !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.

Labels (2)
Attachments
Comments

Hello Max,

Thanks for uploading this script. It really helped me in creating a similar script for deleting workitems created prior to enabling of workitem expiration option in my environment.

In my script I am facing below issue now:

When I delete workflow cases using this script, it deletes both workitem and workflowcase however the corresponding task result is also deleted.

Any option of only deleting / rejecting workflow case  and keeping the task result with status as Success with some proper message ( As if the workitem got expired and we have task results retained).

Any help will be highly appreciated.

Thanks

Vikas

Hello Vikas,

the WorkflowCase is the mother object of these processes.

I do not know a way to Keep the TaskResults. You should use it to delete a whole Workflow.

Keeping the TaskResult without any Action from the WorkItems/Workflow is also not really helpful.

If really want to save the TaskResult. You have to add a list where you save These Objects before you delete them during the runtime.

Via API you can Access the TaskResult from the WorkflowCase. After you have deleted all the WorkflowCases, you can iterate trough the List of TaskResults and save them.

BR

Max

Hi,

We have several workitems of type="Remediation" which were created for revocations in certifications. We would like to close these. I do not see WorkflowCaseRef in the xml object of the workitem. How do I close these?

regards,

Vikas

I think this has to be deleted like described in this arcticle: https://community.sailpoint.com/message/61586#61586

BR

Max

What does the commitTrasaction does? I was doing the same as what your rule has except for the commitTrasaction but it is taking a minute to process each workflowcase and is CPU intensive. Putting commitTransaction speeds up processing and is less CPU intensive.

commitTransaction() writes SailPoint Objects into the Database. Many commitTransactions() calls can effect bad Performance. Thats the reason why if added the other solution with (optimize Performance comment). I hope that answers your question and i understand it correct what you were asking.

I am getting the below error when I tried to remove the workflow cases using your Rule code ==> Any solution for the below error

ERROR:

sailpoint.tools.GeneralException: The application script threw an exception: sailpoint.tools.GeneralException: Could not execute JDBC batch update BSF info: Delete Old WorkflowCases at line: 0 column: columnNo

Regards,

Kannan SB

This is a standard error from SailPoint which appears, if transactions to the database cannot be executed. So i have no idea what is the problem.

Does the value of the "workflowCaseName" exist? You can check it in your debug-page. Is your exception appearing every time?

I have checked and I never deleted any workItem or Workflowcases in debug/database. I have tried with your rule and noticed sometimes it throws an error "JDBC Could not Update" and I have tried with delete workflowcase in console am getting below error.

> delete workflowcase "Update Identity xxxxxxx AccessRequest"

java.lang.OutOfMemoryError: Java heap space

might be poor console JVM configuration I think for this error out. If you could suggest something to do the clean up old items.

Regards,

Kannan Sb

Our refresh has led to lot of provisioning forms getting opened due to attributeAssignments. We do not want to fill the forms and give that access. Is it ok to use this code and close them out? Will that cause any corruption on the identities?

Version history
Revision #:
5 of 5
Last update:
‎Mar 09, 2023 06:46 PM
Updated by: