Developing Custom Activities and Workflows
If the out-of-box activities that are available in Microsoft Forefront Identity Manager 2010 (FIM) are not sufficient to meet your workflow requirements, you can develop a custom workflow activity. (For more information, see Custom Activities and Workflows.)
The following sections explain workflow concepts that are specific to FIM and will help you develop custom workflows and activities for FIM.
When developing custom activities or workflows you must ensure that you are using .NET 3.5. The FIMService will only work with .NET 3.5. The default option in Visual Studio 2010 is .NET Framework 4. The default option in Visual Studio 2012 is .NET Framework 4.5.
Retrieving and Modifying Data
Custom activities can read and modify resources in the FIM Service database and access the workflow and request that are associated with the activity.
Reading and Modifying FIM Service Resources
The FIM Service provides workflow activities that support creating, reading, deleting, and enumerating resources in the FIM Service database. For example:
Creating Resources: Use the CreateResourceActivity activity to create resources in the FIM Service database.
Reading Resources: Use the ReadResourceActivity activity to obtain a specific resource from the FIM Service database if you know the ObjectID of the resource.
Updating Resources: Use the UpdateResourceActivity activity to update resources in the FIM Service database.
Deleting Resources: Use the DeleteResourceActivity activity to delete resources in the FIM Service database.
Enumerating Resources: Use the EnumerateResourcesActivity activity to query for resources in the FIM Service database. You should use this activity when you are retrieving multiple resources, or when the ObjectID of the resource that you are retrieving is unknown. If you know the ObjectID of the resource, you can use ReadResourceActivity instead of EnumerateResourcesActivity.
Authorization workflows should not modify resources in the FIM Service database. For more information, see Authorization Workflows Should Not Create, Modify, or Delete Resources later in this topic.
Parsing Data from a Request
FIM provides the CurrentRequestActivity activity so that you can retrieve the current Request resource that is associated with the running workflow instance. A custom activity can use this activity to obtain information from the request that triggered it. A workflow activity may require the need to parse the RequestParameter property of a Request resource. This is commonly done in custom activities that perform some validation on the input of the request that triggered them. The RequestType class provides a ParseParameters() method to parse the RequestParameter property of a Request.
The following example demonstrates how to parse the values in the RequestParameter property of a Request resource and store them as a collection of the CreateRequestParameter type. If the request that is being parsed is performing an update operation instead of a create operation, you should use the UpdateRequestParameter type, because this type exposes additional information about the mode of operation (modify, add, or remove).
ReadOnlyCollection<CreateRequestParameter> requestParameters = this.currentRequest.ParseParameters<CreateRequestParameter>();
In the previous example,
currentRequest is a ResourceType property whose value is populated by the CurrentRequestActivity activity. The CurrentRequestActivity activity retrieves the Request property that is attached to the current workflow.
Accessing the Parent Workflow
The SequentialWorkflow type derives from the
System.Workflow.Activities.SequentialWorkflowActivity class. All workflows that are hosted in FIM must derive from the SequentialWorkflow class. An activity can use the TryGetContainingWorkflow method to retrieve information about the workflow that contains it.
Passing Data between Workflow Phases
Some scenarios may require that an authorization workflow share some information with an action workflow that runs for the same request. (For more information, see Request Processing.) The recommended approach for accomplishing this scenario is as follows:
Passing Data from an Authorization Workflow Activity to an Action Workflow
Create and bind one or more attributes to the Request resource type in the FIM schema that can store the information that you want to share between activities. You can do this through Web services or by using the FIM Portal.
Grant permissions to the person or resource that will be assigned to the ActorID of the activity to read and modify the new attribute. Note that this step is not required if the ActorID is set to the FIM Service Account resource. For more information, see Microsoft.ResourceManagement.Workflow.Activities.
In the authorization workflow activity, use the UpdateResourceActivity activity to set the desired value on the new attribute.
In the action workflow activity, use the ReadResourceActivity to get the value of the new attribute.
All workflows should handle the case in which information about the original request, including data that is stored in custom attributes on that object, is not available when the workflow is run. For more information, see Workflows Might Terminate at Any Time later in this topic.
Handling Workflow Interruptions
When you are developing custom activities and workflows, it is important that you understand how the workflow host handles interruptions in workflow processing. Workflows may be terminated at any time and may be run multiple times on the same resource. (For more information, see Interrupted Workflow Behavior.) The following sections describe how to develop custom activities based on these situations.
Workflows Might be Restarted
A workflow activity that is used in FIM may have all or part of its work repeated multiple times. An authorization or action workflow is re-created from its last persistence point when the FIM Service recovers from a service interruption. Any work that the workflow performs after its last persistence point is repeated. The same workflow activity may be run multiple times on the same target resource. This may happen unintentionally as a result of policy misconfiguration, or intentionally as a result of forced rerunning of a workflow.
For the previously mentioned reasons, it is important that repeating the actions of a workflow does not result in negative or irreversible impact.
You can also use persistence points as a defense against interruptions, particularly in long-running workflows. However, remember that the use of workflow persistence points in a custom activity introduces additional overhead to the workflow runtime. (For more information, see Performance later in this topic.) For information about workflow persistence, see Windows Workflow Foundation Persistence Overview.
Interrupted Workflow Behavior defines what the FIM Service does when it is restarted to handle each workflow that was not completed when the FIM Service is interrupted.
Workflows Might Terminate at Any Time
A running workflow in FIM can encounter an error or be canceled at any time, either by a user or by the FIM Service. Custom activities must ensure that the FIM Service, or any other systems that the activity interacts with, are left in a desired state in the event the activity is canceled or terminated before it completes its actions. You should design a workflow so that it can be restarted if it does not finish (for example, if the server goes down during processing). In this case, a new instance of the workflow is created that does not have access to the original Request object that caused the workflow to be run.
Consider the following guidelines to help make sure that custom activities behave appropriately if the activity does not complete correctly:
Ensure that a workflow that runs partially does not have a significant negative impact, or cause irrecoverable damage.
Wrap the activity’s operations in a transaction. You can do this by using Windows Workflow Foundation (WF) Transactions.
In the event of a failure, use Windows Workflow Foundation (WF) Compensation to clean up after previously completed work.
If a cancel request is issued for the activity, override the Activity.Cancel method to clean up appropriately.
All workflows should be serializable, so that if the FIM Service is stopped while a workflow is in the process of executing, the workflow’s state can be persisted and later resumed exactly where it left off. If a workflow is not serializable, the workflow fails to be persisted and is rerun from the beginning when the FIM Service is restarted. For more information about serialization, see Windows Workflow Foundation Serializable Overview.
For general guidance around exception handling in workflow activities, see Exception Handling in Windows Workflow Foundation.
If you want to terminate a workflow, the easiest way to do this in FIM is to throw an unhandled exception in the activity. This results in the workflow that contains the activity to terminate, and the message that you include in the exception is appended to the RequestStatusDetail attribute of the Request object that triggered the workflow.
All unhandled exceptions are also appended automatically to the WorkflowStatusDetail property of the WorkflowInstance resource in the FIM Service database.
Additional Best Practices for Creating Custom Authorization Activities
The following sections contain additional best practices for creating custom Authorization Activities.
Authorization Workflows Should Not Create, Modify, or Delete Resources
An authorization workflow that creates, modifies, or deletes resources may leave an unwanted result if the Request that it is attached to does not finish its operation. You should not assume that after an authorization workflow activity finishes, the attached request will become authorized and commit its operation. Other authorization workflows that do not finish can cause the request operation to be denied or cause other problems to occur.
Approval Activities Should Not be Run in Parallel
We recommend that you do not run two or more approval activities (see ApprovalActivity) in parallel. Doing this may cause the request to become stuck in the authorizing phase (see Request Processing). If multiple approvals are required, you can either include a larger list of approvers in an approval, or run the two approval activities sequentially.
Selective Retrieval of Attributes
The ReadResourceActivity activity and the EnumerateResourcesActivity activity enable custom activities to retrieve resources from the FIM Service database. Both of these activities expose properties that enable you to be selective about the attributes that are retrieved. Custom activities should use these properties to make sure that only the minimum set of attributes that are required by the activity are retrieved. Retrieving additional data can adversely affect the performance of the activity and the FIM Service.
Use Persistence Points Cautiously
The use of workflow persistence points in a custom activity introduces additional overhead to the workflow runtime. This can adversely affect performance if a large volume of persistence occurs.
Testing and Debugging Custom Activities and Workflows
The following sections give recommendations about testing and debugging custom activities and workflows.
Use the WorkflowStatusDetail property of the WorkflowInstance resource as a starting point in investigating workflow-related errors. All unhandled exceptions that a workflow encounters are automatically appended to the WorkflowStatusDetail attribute of the resource in the FIM Service database. For more information about how to debug FIM, see Troubleshooting Forefront Identity Manager Service.
Testing Custom Workflows and Activities
It is important to always make sure that you thoroughly test custom workflows and activities before you incorporate them into a production environment.
In addition to verifying that the functionality of the custom workflow and activity is as expected, consider the following additional tests:
Verify the workflow activity has sufficient permissions to perform its operation.
Trigger multiple instances of the same workflow on the same target resource.
Stop the FIM Service while the workflow is running.
Start the FIM Service and verify that the workflow can resume successfully.
Cause the workflow to be terminated and verify that adequate information is provided about the reason for termination.
Rendering Custom Activities in the FIM Portal
For information about best practices for rendering custom activities in the FIM Portal, see Rendering Custom Activities in the FIM Portal.