Advanced Workflow Topics
This section includes these advanced Workflow topics:
-
Loops within Workflows
-
Launching Workflows from a Task or Workflow
-
Workflow Forms
Loops within Workflows
A loop occurs when a step transitions back to a step that executed previously. The state of that step is reinitialized and the step is executed again. A loop can transition back any number of steps. You define a loop transition the same way you would any other transition. However, you must just select a target step that appears before the loop transition in the process designer.
In most case, when you create a loop transition, you want to give it a conditional When expression. If a loop transition is unconditional, the workflow can enter an infinite loop and not be able to finish.
Launching Workflows from a Task or Workflow
You can launch workflows from tasks or other workflows without using a system event to trigger the workflow.
Workflows Launched from Custom Tasks
You can launch workflows from a custom task in IdentityIQ. Because tasks are compiled java classes, the custom task must be written as a Java method.
To create a workflow from a custom task:
-
Create a WorkflowLaunch object in the Java method.
-
Populate the object with the data the workflow requires.
-
Use the Workflower class to launch the workflow.
It is often necessary for one workflow to launch another workflow. This can be performed in Beanshell using code similar to the previous example. However, using the workflow library method scheduleWorkflowEvent is easier. Not only does this method launch a workflow, it also allows you to delay the launch until a time in the future.
To have one workflow to launch another workflow, create a step and select scheduleWorkflowEvent as the action. This method requires the following arguments:
import java.util.HashMap;
import sailpoint.api.sailpointContext;
import sailpoint.api.Workflower;
import sailpoint.integration.ProvisioningPlan;
import sailpoint.integration.ProvisioningPlan.AccountRequest;
import sailpoint.integration.ProvisioningPlan.AttributeRequest;
import sailpoint.object.Identity;
import sailpoint.object.Workflow;
import sailpoint.object.WorkflowLaunch;
import sailpoint.tools.GeneralException;
import sailpoint.tools.xml.XMLObjectFactory;
HashMap launchArgsMap = new HashMap();
String myIdentityName = "T339222";
Identity myIdentity = context.getObjectByName(Identity.class, myIdentityName);
//Create Provisioning Plan and add needed attribute values
ProvisioningPlan plan = new ProvisioningPlan();
plan.setIdentity(myIdentity);
AccountRequest accountRequest = new AccountRequest();
AttributeRequest attributeRequest = new AttributeRequest();
accountRequest.setApplication("IIQ");
accountRequest.setNativeIdentity(wbIdentity);
accountRequest.setOperation("Modify");
attributeRequest.setOperation("Add");
attributeRequest.setName("assignedRoles");
attributeRequest.setValue("Benefits Clerk");
accountRequest.add(attributeRequest);
plan.add(accountRequest);
//Add needed Workflow Launch Variables to map of name/value pairs
launchArgsMap.put("allowRequestsWithViolations","true");
launchArgsMap.put("approvalMode","parallelPoll");
launchArgsMap.put("approvalScheme","worldbank");
launchArgsMap.put("approvalSet","");
launchArgsMap.put("doRefresh","");
launchArgsMap.put("enableRetryRequest","false");
launchArgsMap.put("fallbackApprover","admin");
launchArgsMap.put("flow","RolesRequest");
launchArgsMap.put("foregroundProvisioning","true");
launchArgsMap.put("identityDisplayName","John.Smith");
launchArgsMap.put("identityName","John.Smith");
launchArgsMap.put("identityRequestId","");
launchArgsMap.put("launcher","admin");
launchArgsMap.put("notificationScheme","user,requester");
launchArgsMap.put("optimisticProvisioning","false");
launchArgsMap.put("plan",plan);
launchArgsMap.put("policiesToCheck","");
launchArgsMap.put("policyScheme","continue");
launchArgsMap.put("policyViolations","");
launchArgsMap.put("project","");
launchArgsMap.put("requireViolationReviewComments","true");
launchArgsMap.put("securityOfficerName","");
launchArgsMap.put("sessionOwner","admin");
launchArgsMap.put("source","LCM");
launchArgsMap.put("trace","true");
launchArgsMap.put("violationReviewDecision","");
launchArgsMap.put("workItemComments","");
sailpoint.object.ProvisioningPlan spPlan = new sailpoint.object.ProvisioningPlan();
spPlan.fromMap(plan.toMap());
launchArgsMap.put("plan", spPlan);
//Create WorkflowLaunch and set values
WorkflowLaunch wflaunch = new WorkflowLaunch();
Workflow wf = (Workflow) context.getObjectByName(Workflow.class,"myWorkflowName");
wflaunch.setWorkflowName(wf.getName());
wflaunch.setWorkflowRef(wf.getName());
wflaunch.setCaseName("LCM Provisioning");
wflaunch.setVariables(launchArgsMap);
//Create Workflower and launch workflow from WorkflowLaunch
Workflower workflower = new Workflower(context);
WorkflowLaunch launch = workflower.launch(wflaunch);
// print workflowcase ID (example only; might not want to do this in the task)
String workFlowId = launch.getWorkflowCase().getId();
System.out.println("workFlowId: "+workFlowId);
Workflows Launched by Other Workflows
Installations often have one workflow start another workflow using the scheduleWorkflowEvent method in the Standard Workflow Handler. One of the initiating workflow steps launches the method through a call action.
Arguments to the step include the following:
Name | Value |
---|---|
workflow | Name of the workflow to launch. |
requestName | Name to be assigned to the request. If not specified, the name of workflow is the default. |
scheduleDate | Date and time you want the workflow to launch. Must be specified with a java.util.Date value. If this argument is not set, the workflow launches immediately. |
scheduleDelaySeconds | An alternative to using scheduleDate. When set, the value is the number of seconds to delay before launching the workflow. |
caseName | Specify a user friendly name for workflowCase to be displayed in the user interface. If no name is specified, the default is the name of workflow. |
launcher | Name of the identity to be displayed as the launcher of the new workflow case. If this argument is not specified, the launcher of the initiating workflow is used. |
A workflow that is launched by another workflow is different from a workflow that is launched as a subprocess. If a workflow is launched as a subprocess, the calling workflow waits until the subprocess is completed. After the workflow returns control to the caller, the processing continues.
A workflow that is launched by another workflow causes a completely separate workflow to begin launching. After the new workflow is started, the original or calling workflow moves on to its next step.