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:
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);
}
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-
Thanks,
Any examples of runWithResult()?
I am trying to make sure a task is completed before the next steps in the workflow. Could you help suggest which method might be useful for it. Below for reference, what to have for isTaskRunning, any inbuilt function?
while (!check){
check = tm.isTaskRunning("Task");
Thread.sleep(5000);
count++;
if(count == 5) break; //safe break
}
@ShivangiS : I wouldn't recommend having a workflow check the status of a task running. I'd recommend performing whatever tasks are needed via a rule that can be called within the workflow as a workflow step. That would ensure that the workflow only moves forward once that rule has completed whatever it needs to do. Depending on the task, you might be able to execute it directly within the workflow. For example, if you need to refresh an identity, it can be done via a native workflow step.
To answer your questions directly... review the JavaDocs. Looks like the TaskManager API has a isTaskRunning(TaskName, TaskResultName) method that you can use, but you'd have to put the thread to sleep and keep relooping - not ideal for IIQ since you'll lose out on that thread/core while you wait for another thread to complete the task.
Additionally, if you do have situations where you need to wait for something to occur within a workflow (usually downstream provisioning/replication), you should use a "wait" step within the workflow. On any workflow step you can add an attribute "wait=<Integer>" with the integer corresponding to the number of minutes to wait before the step can be executed. This will have IIQ background the workflow so it is not consuming resources.