From a performance perspective, best practice suggests limiting the size of the User view whenever possible. A smaller view means less data is pulled from the resource and sent over the network. Because the view is held as a variable in the workflow, any time the workflow task is suspended the view must be written to the TaskInstance object. If a system is running thousands of workflows concurrently, and each workflow contains large views, the amount of time spent transferring the view to/from the repository (which includes serialization/deserialization) becomes a significant bottleneck.
The best use of a view is to carry only enough data necessary to allow changes to the user to be made and approved intelligently. If the intent of the caller is to change a user’s password on a set of resources, all that is necessary to know to drive this process is a list of accounts associated with the user. Specific account data would not typically be necessary for this process.
A customer might decide to implement a custom workflow so that users can request access to a particular resource, that workflow should check out the User view to allow a change to be submitted to it (pending the appropriate approval). In this example, the only information that probably must be available is the Identity Manager User portion of the view so that the waveset.resources list and the accountInfo object can be updated appropriately. In this situation, use the TargetResources option when checking out the User view to check out only the Identity Manager User portion of the User view with an option map similar to the following:
<map> <s>TargetResources</s> <list> <s>Lighthouse</s> </list> </map>
You can reduce the size of the User view in the WorkItem view. Work items are the objects that represent a task assigned to an individual such as an approval, a delegation, or simply an interruption in a workflow to allow a user to input additional information. Custom workflows create approvals and interact with forms through manual actions. In short, a manual action copies all Workflow variables that are in the scope of the current <ManualAction> element. In addition to the task context, into a variables object within the WorkItem object. In terms of approvals, you rarely need the full User view and context variables. As a result, consider reducing the WorkItem size by specifying the ExposedVariables argument when defining a ManualAction.
The <Exposed Variables> element tells the workflow exactly which variables are necessary to capture in the WorkItem for subsequent processing. Remember that if a single workflow supports multiple approvers, Identity Manager will create multiple work items (one for each approver).
The preceding scenario shows a relatively uncomplicated implementation of single manual action. But typical deployments involve more complicated scenarios. For example, a customer might require that when a user is created, an approval goes to a ”bucket’, where one of approximately 25 approvers can select the approval. To mimic a bucket, you can create a work item for each approver in the bucket. All an approver must do is accept the action. Once accepted, Identity Manager can discard the remaining 24 work items, and generates the actual approval work item for the approver who accepted the bucket request.
Consider that there are a total of three buckets that act as escalation tiers. When the approval is processed through Bucket 1, Identity Manager escalates a new request into Bucket 2, and the process begins again. This process results in approximately 26 work items per bucket (25 + 1) multiplied by three (for three buckets). One user request would create 78 work items, granted not all at once. But then consider this occurring in a deployment environment containing a user base of 500,000 users with hundreds of these requests flowing in each day. Had the implementer of this scenario not bothered to size the WorkItem views by using the ExposedVariables argument, Identity Manager would store a large amount of bit of non-essential data in the work items and being passed over the JDBC connection.
<Activity id=’0’ name=’activity1’> <ManualAction id=’-1’> <FormRef> <ObjectRef type=’UserForm’ name=’Access Review Abort Confirmation Form’/> </FormRef> <ExposedVariables> <List> <String>user.waveset.accountId</String> <String>user.waveset.resources</String> <String>user.accounts[Lighthouse].idmManager</String> <String>user.accounts[Lighthouse].fullname</String> </List> </ExposedVariables> <ViewVariables> <List> <String>user</String> </List> </ViewVariables> </ManualAction> <WorkflowEditor x=’53’ y=’111’/> </Activity>
You must write a custom user provisioning request workflow for users to execute. This type of workflow might be handy when customers want managers to submit provisioning requests for their direct reports but prefer to avoid making every manager in the organization an Identity Manager administrator.
With these requirements in mind, you create a custom workflow that:
allows managers to create or update direct reports
incorporates a ManualAction that allows managers to edit the checked-out view or the newly created view
ensures that by check in, the process will have gone through (using custom manual actions), or will go through (Using out-of-the-box approval processes), the appropriate approval processes.
You will also need to refresh the view. Refreshing the view means that Identity Manager re-examines the assigned resource information and re-fetches that information from the native resources to update the User view with the latest information (if it changed since view check-out).
You can ensure that Identity Manager refreshes the view by specifying a ViewVariables element within the manual action that instructs Identity Manager which variables in the WorkItem’s variables object should be treated as a view and thus refreshed when requested. See the preceding example for an example of specifying the variable user as a ViewVariable.
As you can see from the preceding scenarios, you can control the size of WorkItem objects through the careful use of top-level variables. Identity Manager creates a WorkItem object for each manual action that is processed in a workflow. By default, these objects contain a copy of all top level variables from the executing workflow. There are three ways to control the variables that are passed into and assimilated back from WorkItem objects:
You can use ExposedVariables to control which variables from the workflow are copied into the WorkItem object. If you have defined ExposedVariables, only those variables in the list are copied to the WorkItem. Using this option controls the size of WorkItem objects reducing memory usage, database size, and CPU processing time. The definition should be a list containing string representations of the workflow variables. Two example definitions follow.
<!-- Pass the entire view object but no other WF variables --> <ExposedVariables> <List> <String>userView</String> </List> </ExposedVariables> <!-- More optimized to only pass the Lighthouse attributes and email value --> <!-- Note the definition of a partial GenericObject path and a complete GenericObject path --> <ExposedVariables> <List> <String>userView.accounts[Lighthouse]</String> <String>userView.waveset.email</String> <String>managerFlag</String> </List> </ExposedVariables>
Passing only the data that the UserForm requires to operate optimizes the WorkItem processing time. This reduces the time required when processing the workItemEdit.jsp and also reduces total memory consumption and GC activities for the JVM. Without this option, the system can quickly consume a large amount of CPU time during concurrent user operations.
You can use EditableVariables to control which variables from the WorkItem object are assimilated back into the workflow. The classic usage of this definition is to control which variables can be edited by the approver. EditableVariables is most useful during parallel approvals to prevent two approvers from overwriting the same data. Make sure you read the note regarding ExposedVariables.
<ExposedVariables> <List> <String>userView.accounts[Lighthouse]</String> <String>userView.waveset.email</String> </List> </ExposedVariables> <!-- Only the firstname, lastname fields should be assimilated from the WorkItem --> <-- Note the inclusion of the formButton variable which is used to store the button value --> <EditableVariables> <List> <String>userView.accounts[Lighthouse].firstname</String> <String>userView.accounts[Lighthouse].lastname</String> <String>formButton</String> </List> </EditableVariables>
<Field button='true'> <Display class='Button'> <Property name='name' value='variables.formButton'/> <Property name='label' value='Submit'/> <Property name='command' value='Save'/> <Property name='value' value='submit'/> </Display> </Field>
To debug, see workflow.fileTrace attribute of the System Configuration object to identify which variables are being assimilated back into Workflow from the view. ViewVariables is used to control which variables represent view objects which should be refreshed when a refreshView operation is executed from the workItemEdit.jsp page. In general a refreshView operation reloads the view data from all of its sources such as resource adapters.
You can use ViewVariables to control which variables represent view objects that should be refreshed when a refreshView operation is executed from the workItemEdit.jsp page. In general, a refreshView operation reloads the view data from all of its sources such as resource adapters.
<!-- The userView variable should be refreshed during a refreshView --> <ViewVariables> <List> <String>userView</String> </List> </ViewVariables>
Use ViewVariables only when absolutely necessary for correct form and user interaction. This is option is seldom used.