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

Running a task from a rule or workflow

Running a task from a rule or workflow

A Task can be initiated from code in any rule (including workflow rules) by instantiating a TaskManager and calling one of its methods for running a task. Methods to run a task include:

  • runSync(): Run a task synchronously, bypassing the Quartz scheduler and returning the result to the same thread.
    • TaskResult runSync(String TaskDefinitionName, Map<String,Object> args)
    • TaskResult runSync(TaskDefinition def, Map<String,Object> args)
    • TaskResult runSync(TaskSchedule schedule, Map<String,Object> schedArgs)
  • runNow(): Force immediate execution of a previously scheduled task. The task remains scheduled.
    • void runNow(TaskSchedule sched)
  • run(): Run a task immediately (creates a TaskSchedule object that is deleted automatically when execution completes).
    • void run(String TaskDefinitionName, Attributes<String,Object> args)
    • TaskSchedule run(TaskDefinition def, Map<String,Object> args)
  • runWithResult:Launch task immediately, pre-creating a TaskResult; used if need to store the result ID somewhere (typically in a WorkItem) to facilitate monitoring of the task execution.
    • TaskResult runWithResult(TaskDefinition def, Map<String,Object> args)

 

Examples

1. Using TaskResult runSync (String TaskDefinitionName, Map<String,Object> args)

try {
  TaskManager tm = new TaskManager(context);
  TaskResult result = tm.runSync("Identity Refresh", new HashMap());
} catch (Exception e) {
  log.error("Exception processing request for Identity Refresh run from rule");
  throw new GeneralException(e);
}

2. Using void runNow(TaskSchedule sched)

TaskDefinition task = context.getObjectByName(TaskDefinition.class,"Identity Refresh");
if (null != task) {
  try {
// Task Schedule Setup
    TaskSchedule taskSchedule = new TaskSchedule();
    taskSchedule.setName("Schedule for" + task.getName());
    taskSchedule.setDeleteOnFinish(true);
    taskSchedule.setDescription("Job Scheduled from Rule");
    taskSchedule.setTaskDefinition(task);
    taskSchedule.setLauncher("spadmin");
    Date now = new Date();
    taskSchedule.setNextExecution(now);
    TaskManager tm = new TaskManager(context);
    tm.runNow(taskSchedule);
  } catch (Exception e) {
    log.error("Exception processing request for "+task.getName());
    throw new GeneralException(e);
  }
// Include this if you want to wait for the results from the task:
//   TaskResult tr = tm.awaitTask(taskSchedule, 1800);
}

3. Using TaskSchedule run(TaskDefinition def, Map<String,Object> args)

TaskDefinition task = context.getObjectByName(TaskDefinition.class,"Identity Refresh");
if (null != task) {
  try {
    Date now = new Date();
    TaskManager tm = new TaskManager(context);
    tm.run(task,null);
  } catch (Exception e) {
    log.error("Exception processing request for "+task.getName());
    throw new GeneralException(e);
  }
}

4. Using void run(String TaskDefinitionName, Attributes <String, Object> args)

try {
  TaskManager tm = new TaskManager(context);
  tm.run ("Identity Refresh", new Attributes());
} catch (Exception e) {
  log.error("Exception processing request for Identity Refresh run from rule");
  throw new GeneralException(e);
}

 

Labels (4)
Comments

Is there any way to wait until the task has completed successfully ?

 

As in i want to run a task from a rule, but i only want the rule to continue if the task has completed successfully, not just kicked off successfully ?

 

Is this possible ?

I think the answer is "technically speaking it is, but I would not recommend you to do it". Because of the async nature of tasks (they're basically Quartz jobs), you'd had to code some polling to periodically check, in your rule, for the results or errors. The problem is that this process could take a very long time and, while your rule runs, it consumes resources. Also, think about what could happen in a parallel environment, or what could happen if the server enters a shutdown process while your rule is polling the task for results. Instead, if you have a process that relies on a sync answer from a async process such as a task, I'd recommend you to split your process into 2 different processes and schedule a "Run rule task" to periodically check for results (for all tasks that match your logic) to start the 2nd part of the process or to finish the ones that failed (and remember that it's not trivial to figure out when a long-running task has failed in case of a server shutdown or outage). Even for quick tasks, that you can add some thread.sleep(some seconds here) to wait for results, you can still have invalid results (sleep time is too short) or bad performance (sleep time is too long).

Hi,

I would like to control the start time of the task. I tried runSync and runNow, but both executed immediately even though I added the added the time in TaskSchedule.. Basically, I want to schedule it for system time + 5 minutes when rule is called. I have some entitlements that are dependent on each other, I am requesting both entitlements together, but can not control the sequence they are executed. If the one which has dependency executes first then it fails, so I want to execute identity refresh task after 5 mins if it fails. I know with in that 5 mins other entitlements will complete, so executing Identity Refresh will do what I need and do not want to wait for the normal schedule of Identity Refresh to avoid the delay in the access requests fulfillment. Appreciate your feedback. Thanks.

 

As I understood these methods are meant to be executed immediately. I ended up calling a workflow with wait time for refreshing the identity from the before rule for adding the delay that I wanted-

https://community.sailpoint.com/t5/IdentityIQ-Articles/Scheduling-a-Workflow-to-run-in-the-future-fr...

Thanks,

 

Version history
Revision #:
5 of 5
Last update:
‎Jul 24, 2023 04:14 PM
Updated by: