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,