Skip to content

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:

  1. Create a WorkflowLaunch object in the Java method.

  2. Populate the object with the data the workflow requires.

  3. 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.

Workflow Forms

Standard work item forms are available for presenting approval or other data requests to approvers. However, some installations prefer to use custom forms for these activities. Based on the type of the data collection effort, a custom form might be required. You can build a custom form using a

element in the XML that is embedded within the element.

Note

The element can be used to collect data from a user, even if the workflow is not an approval. You generally use custom forms for these activities because the normal approval forms do not apply. However, you can also use custom forms for traditional approval activities when you need a different presentation format.

The basic elements in a Form definition are:

<Form>
   <Attributes>    (map of name/value pairs that influence the form renderer)
   <Button>     (determine form processing actions)
   <Section>    (Subdivision of form; may contain nested Sections and Fields)
     <Field>    (may contain Attributes map, Script to set value, Allowed Values Definition script, and Validation Script)

For detailed information about working with forms, see Forms.

Process Variable and Step Forms

You use forms added to steps on the Process Designer tab in the Business Process Editor to request data that a process needs from a user. For example, you can add a form to a step to request a value for a missing attribute.

However, to present information on the Basic Views of the Process Variables tab and the Arguments tab of the Step Editor, you use process variable and step forms.

To simplify the information displayed on the Process Variables tab:

  • Variables are displayed in more logical groups.

  • Variables that are rarely, if ever, modified are hidden.

Changes made in the Basic View are persisted to the Advanced View and more complex configuration can be performed there if needed.

The step forms are referenced from the workflows or stepLibraries. These forms define the form that is presented on the Arguments tab of the Step Editor panel and works similar to the process variable forms.

Both of these forms are referenced from workflows using the configForm variable. The forms can be defined, viewed and edited on the IdentityIQ debug page.