Human Task Manager is an IBM® WebSphere® Process Server component that enables human beings to interact with Web services and business processes. Humans can invoke Web services using originating tasks, act as Web services themselves using participating tasks, and collaborate with other people by invoking or working on purely human tasks. Working with Business Flow Manager, which orchestrates business processes, Human Task Manager provides powerful support for the execution of business processes that involve humans. Both components together make up the Business Process Choreographer.
One of the major features of Business Process Choreographer is its ability to provide instance-based authorization for business processes and human tasks. This feature is based on Human Task Manager staff resolution (also known as people resolution) that can consider the business context when assigning human tasks to people in various authorization roles.
Human Task Manager comes with a powerful set of default staff verbs that support you in modeling authorization rules. These rules offer functionality that can go far beyond the possibilities offered by J2EE™ authorization. For example, you can model sophisticated rules like the four-eyes principle or authorizing the manager of an employee. However, to adapt the default LDAP configuration to your organization's LDAP server and schema, or to integrate your proprietary staff directory with Human Task Manager staff resolution, you might want to extend the default set of staff verbs.
This article describes the customization options for Human Task Manager staff resolution. You will learn about the XML artifacts that are used when creating or customizing staff verbs, the syntax of the supported staff queries, and then the staff resolution customization plug-points provided by Human Task Manager:
- Adapt existing staff verbs to your LDAP schema by creating a new staff plug-in configuration.
- Create new staff verbs in the verb set and the XSLT verb mapping file.
- Provide staff resolution results via input messages, or other process context data.
- Integrate a proprietary staff repository with Human Task Manager.
- Perform workload balancing with Human Task Manager using the staff resolution post-processor plug-in.
Understanding staff resolution XML artifacts
Before you can start writing new staff query verbs (also known as people assignment criteria), you will need a deeper understanding of the staff verb set format, the XSLT templates used to transform parameterized verbs into the native staff plug-in language, and the XML language the staff resolution plug-in of your choice is using. These elements are described in the next sections.
Staff verb set
Staff query verbs are abstract staff query definitions that can be used at modeling time to model authorization rules. These verb definitions are used by the WebSphere Integration Developer Task Editor to render the verb modeling panel (Figure 1), where you can define authorization rules by selecting the verb of your choice, then entering parameter values.
Figure 1. Staff verb modeling
Each staff query verb has a name, a description, and a set of parameters. Parameters can be optional or mandatory. You define authorization rules by selecting the verb and entering parameter values.
All staff query verbs are assembled together in a so-called verb set, which is an XML file available in WebSphere Integration Developer. A default verb set is part of WebSphere Integration Developer and lists all of the verbs provided by Human Task Manager. You will find the VerbSet.xml file in the directory <WebSphere Integration Developer installation directory>/wstools/eclipse/plugins/com.ibm.wbit.tel.ui_6.0.2/xml/. (If you use a version of WebSphere Integration Developer other than V6.0.2, the version part (ui_6.0.2) might be different. If you have the choice, use the directory with the highest version number.)
The verb set is usually defined or customized by an administrator. The task modeler does not modify it, but uses the screen rendered by the Task Editor based on this file. A staff query verb is similar to a programming language method. It has a name and a set of parameters. The following verb example comes from the default verb set:
<vs:DefineVerb name='Users by user ID'> <vs:Description>Assigns users, given their user ID. Supported by sample XSLT files for: - LDAP - User Registry - System </vs:Description> <vs:Mandatory> <vs:Parameter> <vs:Name>UserID</vs:Name> <vs:Type>xsd:string</vs:Type> <vs:Hint>%htm:task.originator%</vs:Hint> ... <vs:Hint>%wf:activity(-enter activity name-).readers%</vs:Hint> </vs:Parameter> </vs:Mandatory> <vs:Optional> <vs:Parameter> <vs:Name>AlternativeID1</vs:Name> <vs:Type>xsd:string</vs:Type> <vs:Hint>%htm:task.originator%</vs:Hint> ... <vs:Hint>%wf:activity(-enter activity name-).readers%</vs:Hint> </vs:Parameter> <vs:Parameter> <vs:Name>AlternativeID2</vs:Name> <vs:Type>xsd:string</vs:Type> <vs:Hint>%htm:task.originator%</vs:Hint> ... <vs:Hint>%wf:activity(-enter activity name-).readers%</vs:Hint> </vs:Parameter> </vs:Optional> </vs:DefineVerb>
The verb definition consists mainly of its name, description and a set of parameter definitions. For each parameter, a name, type, and a set of hints can be specified.
The structure of the verb set XML file is:
<?xml version="1.0" encoding="UTF-8"?> <vs:VerbSet xmlns:vs="http://www.ibm.com/schemas/workflow/wswf/plugins/staff/verbset"> <vs:Description>Default Verbset</vs:Description> <vs:DefineVerb name='Everybody'> ... </vs:DefineVerb> ... <vs:DefineVerb name='Manager of Employee by user ID'> ... </vs:DefineVerb> </vs:VerbSet>
The verb set file contains the usual XML prologue, the namespace declaration, the verb set description, and the verb definitions (inside
The verb definition has this structure:
<vs:DefineVerb name='Manager of Employee by user ID'> <vs:Description>Assigns the manager of an employee, given its user ID. </vs:Description> <vs:Mandatory> <vs:Parameter> <vs:Name>EmployeeUserID</vs:Name> <vs:Type>xsd:string</vs:Type> <vs:Hint>%wf:process.starter%</vs:Hint> ... <vs:Hint>%wf:process.administrators%</vs:Hint> </vs:Parameter> ... </vs:Mandatory> <vs:Optional> <vs:Parameter> <vs:Name>Domain</vs:Name> <vs:Type>xsd:string</vs:Type> </vs:Parameter> ... </vs:Optional> </vs:DefineVerb>
The root element has the attribute name, which identifies the verb and must have a correspondence in the XSLT verb mapping file of the staff plug-in configuration you selected. It is followed by the verb description and the set of mandatory parameters. This set is followed by the set of optional parameters. The number of parameters in each set can vary from zero to many.
The parameter definition is identical for optional and mandatory parameters. It contains the parameter name, its data type, and a number of optional hints. The parameters are displayed in the Task Editor verb modeling screen, where you can enter their values. The hints are displayed read-only in the drop-down box of the modeling screen, as shown in Figure 2. You can select one of them as parameter value.
Figure 2. Verb parameter hints
Parameterized staff verbs
When you've finished modeling your authorization rules in the Task Editor verb modeling panel, the data collected will be stored in the module EAR file as a parameterized verb, which has the following structure:
<tel:verb> <tel:name>Users by user ID</tel:name> <tel:parameter id="UserID">sarah</tel:parameter> <tel:parameter id="AlternativeID1">bill</tel:parameter> </tel:verb>
The parameterized verb has a name, and a set of parameters. Both need their correspondence in the XSLT mapping file, since the parameterized verb XML snippet is the input for the XSL transformation step. The XSLT mapping transforms the parameterized staff query verb to the query language of the selected staff resolution plug-in (also known as people directory plug-in). The information used to render the modeling screen (like description, parameter type and hints) is not part of the parameterized verb syntax.
XSLT mapping file
The parameterized staff verbs are the input for the XSLT verb mapping that is performed during task deployment. The XSL transformation maps this input to the XML language supported by the staff resolution plug-in of your choice, and considers staff repository characteristics like an LDAP schema. Example verb mapping XSLT files are provided by preconfigured staff plug-in configurations (also known as people directory configurations) that are part of WebSphere Process Server. Do not edit these files; instead, create new staff plug-in configurations based on modified copies of these files, since the sample XSLT files could be replaced with product updates.
The verb mapping XSLT file is not edited by the human task modeler or deployer, but by the administrator who has created or adapted the staff verb set, and who has deep knowledge about the staff repository (also known as people directory) it accesses. Each newly created (or adapted) verb needs its counterpart as an XSLT template in the verb mapping file. The XSLT template needs to support each parameter of the verb, at least by ignoring it without reporting errors.
Listing 5 shows the two XSLT templates needed to transform the Users by user ID verb for the user registry staff resolution plug-in.
<xsl:template name="Users by user ID"> <xsl:variable name="Name0"> <xsl:value-of select="staff:parameter[@id='UserID']"/> </xsl:variable> <xsl:variable name="Name1"> <xsl:value-of select="staff:parameter[@id='AlternativeID1']"/> </xsl:variable> <sur:staffQueries> <xsl:attribute name="threshold"> <xsl:value-of select="$threshold"/> </xsl:attribute> <xsl:call-template name="GetUserByID"> <xsl:with-param name="username"> <xsl:value-of select="$Name0"/> </xsl:with-param> </xsl:call-template> <xsl:if test="$Name1!=''"> <xsl:call-template name="GetUserByID"> <xsl:with-param name="username"> <xsl:value-of select="$Name1"/> </xsl:with-param> </xsl:call-template> </xsl:if> </sur:staffQueries> </xsl:template> <xsl:template name="GetUserByID"> <xsl:param name="username">default</xsl:param> <sur:userID> <xsl:attribute name="name"> <xsl:value-of select="$username"/> </xsl:attribute> </sur:userID> </xsl:template>
The transformation output corresponding to the parameterized verb shown above is:
<sur:staffQueries> <sur:userID name="sarah"/> <sur:userID name="bill"/> </sur:staffQueries>
The sample mapping XSLT files shipped with Human Task Manager have a structure that is optimized for modularizing medium-size mapping stylesheets. For larger mapping stylesheets, using imports and spreading the templates over many files could provide a more optimal modularization and better overview.
At the beginning of the stylesheet, declare a set of variables that can be used as constants throughout the document. The threshold parameter is a good example of such a variable, since it is likely to aim at the same upper limit of returned user IDs for all queries. Another good example is the set of objectclasses and attributes to be addressed in the LDAP directory.
Listing 7 shows a representative part of the sample mapping XSLT file for the LDAP staff resolution plug-in.
<?xml version="1.0" encoding="UTF-8"?> <xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:staff="http://www.ibm.com/schemas/workflow/wswf/plugins/staff" xmlns:sldap="http://www.ibm.com/schemas/workflow/wswf/plugins/staff/ldap" version="1.0"> <xsl:output standalone="no" encoding="UTF-8" omit-xml-declaration="no" media-type="text/xml" method="xml" indent="yes" version="1.0"/> <xsl:strip-space elements="*"/> <!-- Begin global variables --> <xsl:variable name="Threshold">20</xsl:variable> <xsl:variable name="DefaultPersonClass">inetOrgPerson</xsl:variable> <xsl:variable name="DefaultUserIdAttribute">uid</xsl:variable> <xsl:variable name="DefaultMailAttribute">mail</xsl:variable> <xsl:variable name="DefaultManagerAttribute">manager</xsl:variable> <xsl:variable name="DefaultGroupClass">groupOfNames</xsl:variable> <xsl:variable name="DefaultGroupClassMemberAttribute">member</xsl:variable> <xsl:variable name="DefaultRecursivity">yes</xsl:variable> ... <!-- End global variables -->
All sample mapping XSLT files use a root dispatcher template that delegates the transformation of the verb to a specialized template, depending on the verb name. Verbs that are unknown or cannot be supported by this plug-in should indicate this fact with a message.
<!-- Begin global dispatching --> <xsl:template match="/staff:verb"> <xsl:variable name="verb"> <xsl:value-of select="staff:id/text()"/> </xsl:variable> <xsl:choose> <xsl:when test="$verb='Users by user ID'"> <xsl:call-template name="UsersByUserID"/> </xsl:when> <xsl:when test="$verb='Group Members'"> <xsl:message>Verb 'Group Members' is not supported.</xsl:message> </xsl:when> ... <xsl:otherwise> <xsl:message >Unknown verb:'<xsl:value-of select="$verb"/>'</xsl:message> </xsl:otherwise> </xsl:choose> </xsl:template> <!-- End global dispatching -->
Notice that the sample LDAP XSLT file additionally uses a section that maps either the user ID attribute or the e-mail attribute to the returnAttribute variable, depending on the verb type. Normal staff verbs will return the user ID, and only the special staff query verbs for e-mail addresses will return the e-mail address.
The rest of the stylesheet consists of the verb mapping templates, which are described in the next sections. Be aware that the namespace of the XSLT input is different from the task execution language (TEL) namespace. This is for historical reasons, and is needed to support custom XSLT files that are written based on previous product versions.
Verb-specific mapping templates
The actual verb mapping is performed by specialized templates that create staff plug-in specific queries. They extract the verb parameters and copy them to the query parameters, and - if needed - adapt the query to the schema of the staff repository. To change or write new templates, a thorough understanding of the target XML query syntax is required. The following examples show a set of verb-mapping XSLT templates.
The simplest template only creates a constant XML document, the everybody query. It has no parameters to map into the output document:
<xsl:template name="Everybody"> <sldap:staffQueries> <sldap:everybody/> </sldap:staffQueries> </xsl:template>
This template just creates the output query, without copying any parameter values.
A more complex example is the template designed for the "Users by user ID" verb. The sample mapping template for this query has this structure:
<xsl:template name="UsersByUserID"> <xsl:variable name="Name0"> <xsl:value-of select="staff:parameter[@id='UserID']"/> </xsl:variable> <xsl:variable name="Name1"> <xsl:value-of select="staff:parameter[@id='AlternativeID1']"/> </xsl:variable> <sldap:staffQueries> <xsl:attribute name="threshold"> <xsl:value-of select="$Threshold"/> </xsl:attribute> <xsl:call-template name="GetUserByID"> <xsl:with-param name="username"> <xsl:value-of select="$Name0"/> </xsl:with-param> </xsl:call-template> <xsl:if test="$Name1!=''"> <xsl:call-template name="GetUserByID"> <xsl:with-param name="username"> <xsl:value-of select="$Name1"/> </xsl:with-param> </xsl:call-template> </xsl:if> </sldap:staffQueries> </xsl:template>
The first part of the template extracts the relevant parameter content from the verb and copies it into variables Name0 and Name1.
The code generation begins with the constant opening of the query. The threshold attribute value of the staffQueries element is copied from the constant defined at the beginning of the stylesheet.
The first query parameter, Name0, is mandatory and thus can be generated unconditionally. The second query parameter, Name1, is optional and thus the generation occurs only when it is set. The output generation for the userID query is delegated to the parameterized GetUserByID template.
Finally, the closing query constant
</sldap:staffqueries> is written.
The called GetUserByID template has the following structure:
<xsl:template name="GetUserByID"> <xsl:param name="username">defaultUserID</xsl:param> <sldap:userid> <xsl:attribute name="name"> <xsl:value-of select="$username"/> </xsl:attribute> </sldap:userid> </xsl:template>
The input parameter username is declared to be used for the output generation below. The query output is static, except for the name attribute, which receives the value of the template input parameter username.
Thus, assuming this input document for the stylesheet:
<staff:verb> <staff:name>Users by user ID</staff:name> <staff:parameter id="UserID">%wf:process.starter%</staff:parameter> <staff:parameter id="AlternativeID1">John</staff:parameter> </staff:verb>
these two templates generate this output:
<sldap:staffQueries xmlns:sldap="http://www.ibm.com/schemas/workflow/wswf/plugins/staff/ldap"> <sldap:userID name="%wf:process.starter%"/> <sldap:userID name="John"/> </sldap:staffQueries>
The example above generates a staff query (also known as people query) to be executed by the LDAP staff resolution plug-in. The query language is specific to each plug-in and will be described later.
The result of these queries is passed to the staff resolution post-processor plug-in, if available, or, alternatively, passed directly to the authorization management, which creates work items based on it, and stores them in the Business Process Choreographer database for later authorization checks.
The result of a staff query can best be described with the com.ibm.task.spi.StaffQueryResult interface. This interface is used to pass staff query results to the post-processor plug-in, as well as to pass the post-processing result to the authorization management. This interface has a result type, which can be one of four values:
- Everybody (RESULT_TYPE_EVERYBODY) determines that every authenticated user is authorized.
- Nobody (RESULT_TYPE_NOBODY) determines that no user is authorized with this role and only authorization inheritance applies.
- User IDs (RESULT_TYPE_USERIDS) determines that a set of users is returned.
- Group IDs (RESULT_TYPE_GROUPIDS) determines that a group ID is returned to create a group work item. For future extensibility, the group ID is returned as element of a string array.
If the result type is of type user IDs, a collection with user records is available. The user records are instances of the interface com.ibm.task.spi.UserData that has three properties:
- The user's user ID (called user name in this interface).
- The user's e-mail address. This property is not always populated. In version 6.0.2, staff resolution can only populate this field correctly, when every returned user has exactly one e-mail address.
- The user's preferred locale. This property is not always populated. (In version 6.0.2, this property is not yet used, thus always null.)
If the result type is of type Group IDs, a string array with group IDs is available. In version 6.0.2, this array cannot contain more than one element; the array has been introduced for future extensibility.
Independent of the result type, the interface has a further read-only property, the valid-until date. This property is initialized at object creation and determines how long the result will remain valid. After this time, it is available for staff query refresh operations. To schedule the valid-until date, the task container property timeout for staff query result is considered.
The Human Task Manager API uses a similar interface to return the result of the getUsersInRole() methods. This interface, com.ibm.task.api.StaffResultSet, differs from the StaffQueryResult interface in these ways:
- The result type can also have the value RESULT_TYPE_USERIDS_AND_GROUPIDS. This type is used if multiple work items are considered due to authorization role inheritance, and thus the result contains both user IDs and group IDs.
- For the result type user IDs only a string array with these user IDs is available, no full user records.
- The valid-until property is not available.
Staff resolution plug-ins and their queries
Since Business Process Choreographer delegates staff resolution to plug-ins, you can use various types of people directories. The staff resolution plug-ins are responsible for the retrieval of people information from an external people directory, such as an LDAP directory. The staff resolution plug-ins query the staff repository and retrieve the set of people to be assigned to a work item. They are also involved at deployment time, in order to create an optimized form of the authorization rule to be executed at run time.
When a staff resolution plug-in is invoked at deployment time, it receives the XML document that is the output of the XSL transformation, and converts it into an optimized form to be stored in the Process Choreographer runtime database.
At run time, the plug-ins execute queries against the staff repository with which they are associated (using a staff plug-in configuration), and return a staff query result, like a list of user IDs. The Process Choreographer authorization manager creates work items based on this result.
A staff resolution plug-in is represented in the runtime system as a staff plug-in provider (also known as people directory provider), and can have attached multiple staff plug-in configurations, each with a different JNDI name (to be used when modeling human tasks) and connected to a people directory server.
Staff resolution plug-in query language
When writing or customizing staff verb mapping XSLT files, detailed knowledge of their XML output formats is needed. The output of the XSL transformation is the query language a specific staff resolution plug-in can execute. This section describes the syntax of the queries supported by the various staff resolution plug-ins.
The XML query language is similar for all plug-ins shipped with Process Choreographer and has the following syntax:
<staff:staffqueries threshold="positive nonzero integer number"> staff query element * </staff:staffqueries>
<staffqueries> specification can contain one or more staff query elements,
except for the queries
<groupID/>, which can only be used standalone.
All staff resolution plug-ins support the optional threshold attribute. This parameter lets you to limit the total number of users that are returned by a staff query. In human workflows, it is usually not required to assign a very large number of users to a human task. If a staff query returns a large number of users, it is likely that the query is not defined in a well-contained manner and the large number of people assigned to a task will slow the system down, rather than help work get executed faster. Independently of the threshold attribute, people directories can impose their own limitations on potential result set sizes.
Simple staff queries
The following simple staff queries do not require access to a directory; they are supported by all of the staff resolution plug-ins shipped with Business Process Choreographer.
Every user that has been authenticated by WebSphere Application Server can access the work item created based on this query.
<staff:staffQueries> <staff:everybody/> </staff:staffQueries>
This query assigns a whole group by its WebSphere Application Server group ID, without resolving its members. A group work item is created based on this query result.
<staff:staffQueries> <staff:groupID name="group ID"/> </staff:staffQueries>
The name attribute is mandatory, and can contain context variables. Expressions containing context variables must evaluate to a valid WebSphere Application Server security group ID. This query also supports WebSphere Application Server security dynamic groups added using custom JAAS login modules.
No user is assigned to this work item, only role inheritance applies. You will rarely need this query.
<staff:staffQueries> <staff:nobody/> </staff:staffQueries>
Removes an entry from the staff query result set. It is useful to enforce the four-eyes principle here. It can only be used in combination with queries that return user IDs.
<staff:staffQueries> <staff:remove value="user ID to remove"/> </staff:staffQueries>
The value attribute is mandatory and can contain context variables like %htm:property.myProperty%. Multi-value context variables are supported. Expressions containing context variables must evaluate to one or more WebSphere Application Server security user IDs.
This query represents an explicit assignment to a specific WebSphere Application Server user ID.
<staff:staffQueries> <staff:userID name="valid WebSphere user ID"/> </staff:staffQueries>
Even though this query permits assignment to users by name, you should avoid hardcoding user IDs in the human task model. However, the ability to assign work items to users by ID is useful for assignments that are based on context data; for example, to assign the process starter.
The name attribute is mandatory and can contain context variables, such as %wf:process.starter%.
<staff:staffQueries> <staff:userID name="Billy"/> <staff:userID name="%wf:process.starter%"/> </staff:staffQueries>
Complex staff queries
Queries of type user
The queries of type user enable persons to be located based on their distinguished name or user ID. Queries of this type are useful in conjunction with context variables or intermediate results. Here is an example for the LDAP plug-in:
<sldap:staffQueries> <sldap:user dn="cn=Mary Smith, ou=mydivision, o=acme, c=us" objectclass="person" attribute="uid"/> </sldap:staffQueries>
Queries of type usersOfGroup
This query type retrieves the members of a group based on the group distinguished name or ID. The following examples illustrate the query for the LDAP and user registry plug-ins:
<sldap:staffQueries> <sldap:usersOfGroup groupDN="cn=mygroup, o=acme, c=us" recursive="yes"> <sldap:attribute name="sn" objectclass="person" usage="simple"/> <sldap:attribute name="member" objectclass="groupOfNames" usage="recursive"/> </sldap:usersOfGroup> </sldap:staffQueries> <sur:staffQueries> <sur:usersOfGroup groupName="Administrators"/> </sur:staffQueries>
Queries of type search
To locate persons or groups, the search query can be used. The following examples for the LDAP and user registry plug-in describe the syntax of this query:
<sldap:staffQueries> <sldap:search baseDN="ou=mydivision, o=acme, c=us" filter="cn=*" searchScope="onelevelScope" recursive="no"> <sldap:attribute name="sn" objectclass="person" usage="simple"/> <sldap:attribute name="member" objectclass="groupOfNames" usage="recursive"/> </sldap:search> </sldap:staffQueries> <sur:staffQueries> <sur:search type="user" name="Mi*"/> </sur:staffQueries>
Queries of type intermediateResult
For some queries, the desired result can only be accomplished with a sequence of query statements. For example, to retrieve the user ID of the manager of the process starter, the manager user object first must be resolved, and only in a subsequent query can the manager's user ID be resolved.
The query type intermediateResult supports such complex queries. It enables encapsulating a single query of type user, usersOfGroup, or search, and stores their result in a variable that can be used like a context variable in subsequent queries. The result of an intermediateResult query element is not stored in the global staff query result set.
This example outlines how to retrieve the manager of the process starter using the LDAP staff resolution plug-in:
<sldap:staffQueries> <sldap:intermediateResult name="manager"> <sldap:search baseDN="ou=mydivision, o=acme, c=us" filter="uid=%wf:process.starter%" searchScope="onelevelScope" recursive="no"> <sldap:attribute name="manager" objectclass="inetOrgPerson" usage="simple"/> </sldap:search> </sldap:intermediateResult> <sldap:user dn="%manager%" attribute="uid" objectclass="inetOrgPerson"/> </sldap:staffQueries>
In the example above:
- The LDAP dn of the manager of the process starter is retrieved. It is assumed that the manager attribute of every user contains the dn of its manager and that the uid attribute contains the WebSphere Application server user ID.
- The query result is stored in the context variable manager and contains the manager's dn.
- The query result is retrieved by the user query and contains the manager's user ID. The intermediate result manager is used like a context variable. It is assumed that the uid attribute contains the WebSphere Application Server user ID.
Query support by staff resolution plug-in
Depending on the query API flexibility and the capabilities of the people directory that a staff resolution plug-in accesses, the plug-in itself can support a specific subset of the staff queries described above.
System staff resolution plug-in
The System staff resolution plug-in supports only simple queries.
Since this plug-in supports only hardcoded staff assignments, it is not intended for use in production environments. However, it is pre-configured to run out of the box and is thus useful for testing scenarios.
User registry staff resolution plug-in
You can use the user registry staff resolution plug-in to refer to users and groups that are known to WebSphere Application Server. The implementation is based on the UserRegistry interface of the WebSphere Application Server security component. It is usually configured to use an external people directory for authenticating users, and for retrieving users and groups that can be mapped to J2EE security roles.
This plug-in supports all simple queries and the query types user, usersOfGroup, and search.
This query example resolves the members of a group known by the user registry:
<sur:staffQueries> <sur:usersOfGroup groupName="Administrators"/> </sur:staffQueries>
A more complex example resolves the user IDs of all members of the Administrators group, and the user IDs of all users with an ID that begins with "Mi":
<sur:staffQueries> <sur:usersOfGroup groupName="Administrators"/> <sur:search type="user" name="Mi*"/> </sur:staffQueries>
LDAP staff resolution plug-in
The LDAP staff resolution plug-in queries organizational information that is available via LDAP directories. It can, for example, evaluate all members of an LDAP group, or retrieve attributes of an LDAP object, like the manager attribute of a person object.
LDAP staff queries are not directly restricted to directories configured for the WebSphere Application Server user registry (security). However, the user IDs managed in the LDAP directory must match the ones used by WebSphere Application Server security for authentication. Otherwise, either the people retrieved by Human Task Manager staff resolution cannot authenticate with WebSphere Application Server, or people that are authenticated do not see their work items. (User IDs for authentication are case sensitive.)
This plug-in is the most powerful staff resolution plug-in and so can be used for production environments. This plug-in supports all simple queries and the query types user, usersOfGroup, search, and intermediateResult.
The following sample code shows usersOfGroup and search queries:
<sldap:staffQueries> <sldap:usersOfGroup groupDN="cn=mygroup, o=acme, c=us" recursive="no"> <sldap:attribute name="sn" objectclass="person" usage="simple"/> <sldap:attribute name="member" objectclass="groupOfNames" usage="recursive"/> </sldap:usersOfGroup> </sldap:staffQueries> <sldap:staffQueries> <sldap:search baseDN="ou=mydivision, o=acme, c=us" filter="cn=*" searchScope="onelevelScope" recursive="yes"> <sldap:attribute name="sn" objectclass="person" usage="simple"/> <sldap:attribute name="member" objectclass="groupOfNames" usage="recursive"/> </sldap:search> </sldap:staffQueries>
Customizing the LDAP staff resolution plug-in
The LDAP standard does not impose any restrictions on the objects and attributes managed by an LDAP directory, as the LDAP schema is variable. In consequence, there is no standard configuration that can be provided for the LDAP staff resolution plug-in that would fit the needs of all users. However, to help you create a staff plug-in configuration that fits your enterprise directory, Human Task Manager provides a default LDAP plug-in configuration that you can use as an example for your own configuration and adapted XSLT file.
When creating your custom LDAP plug-in configuration, you should:
- Create the new configuration and give it a unique JNDI name. Use this new JNDI name in your task models instead of the default.
- Do not edit and reuse the default LDAP XSLT mapping file, rather create your own copy of this file and make your changes there.
- In the custom properties panel of your new configuration ensure that:
ProviderURLmust point to your LDAP server. Make sure that you also use the proper port. If your LDAP server requires an SSL connection, make sure that SSL is enabled between your WebSphere Application Server and your LDAP server.
BaseDNmust match your LDAP server configuration.
- If your LDAP server requires an authenticated connection, change the
AuthenticationTypeto "simple." Create a J2C authentication alias and register its name using the
- For the other mandatory parameters, you can copy the defaults.
- If the JNDI connection to your LDAP server requires additional parameters, you can use the additional parameters as name-value pairs. These properties will then be set before establishing the JNDI connection to your LDAP server. You can use up to five additional JNDI properties.
The sample XSLT mapping file for LDAP LDAPTransformation.xsl is designed to be easily adapted to another LDAP schema. The default XSL templates use variables where LDAP schema specific parameters are needed. Adapting the values for these variables will be sufficient in most cases. By default, the LDAP XSLT file supports the LDAP objectclass inetOrgPerson for person objects, and groupOfNames for group objects.
The following variables are available so you can adapt the LDAP XSLT file to your LDAP schema:
- DefaultPersonClass defaults to "inetOrgPerson" and determines which LDAP objectclass will be used for person objects.
- DefaultUserIdAttribute defaults to "uid" and determines which person object attribute contains the person's user ID.
- DefaultMailAttribute defaults to "mail" and determines which person object attribute contains the person's e-mail address.
- DefaultManagerAttribute defaults to "manager" and determines which person object attribute contains the person's manager distinguished name (dn).
- DefaultGroupClass defaults to "groupOfNames" and determines which LDAP objectclass will be used for group objects.
- DefaultGroupClassMemberAttribute defaults to "member" and determines which group object attribute contains the group member distinguished names (dn).
- DefaultRecursivity defaults to "yes" and determines whether group members of subgroups are resolved as well, or not
- Threshold defaults to "20" and determines how many user ID records will be retrieved at maximum by a staff query. You might change this value, but consider that a large number of assigned people (potential owners, for example) will usually not make work faster, but potentially slow down the system, due to a larger amount of data in the database.
Additional variables are available to adapt the XSLT templates PersonSearch and GroupSearch. If you use these two verbs, consider adapting the corresponding variable values as well.
Writing a new staff verb and its XSLT template
Human Task Manager comes with a powerful default set of staff verbs that enable you to model sophisticated authorization rules. However, sometimes you will need additional verbs and Human Task Manager lets you to customize and extend the default set of staff verbs. To write a custom verb, you must:
- Edit the default verb set XML file and add the new verb.
- Edit a copy of the default XSLT file associated with the staff plug-in provider you want to use, usually the LDAPTransformation.xsl file. Add support for your new staff verb to this file.
- Deploy the new XSLT file to every node where you configured Business Process Choreographer, including the deployment manager for WebSphere Application Server Network Deployment installations.
- If not already done, create your own staff plug-in configuration that is associated with your adapted XSLT file.
Now you can use the new staff verb when modeling human tasks. Make sure that your task model is associated with the JNDI name of your new configuration.
You can create a new staff verb by following the example below. In this example, you will create a new verb called "Manager and employee by employee user ID." This verb is very similar to the "Manager of Employee by user ID" verb, but instead it will return the user ID of the employee in addition to the ID of the manager.
Editing the default verb set
The first step to create a new staff verb, is to add its template to the default verb set. Find the VerbSet.xml file in the directory <WebSphere Integration Developer installation directory>/wstools/eclipse/plugins/com.ibm.wbit.tel.ui_6.0.2/xml/. (If you use other WebSphere Integration Developer versions, the version part (ui_6.0.2) might be different. If you have the choice, use the directory with the highest version number.)
Add the new verb definition at the end of the file:
This verb has a definition that is identical (from technical point of view) to the "Manager of Employee by user ID" verb, but its description specifies the difference in how the parameter values are applied.
After saving the file, the new verb is actually ready for use within the Task Editor, but before you can deploy task templates that use it, you have to ensure support for this verb in your staff plug-in configuration. Be sure to create a backup copy of your new verb set file.
Editing the XSLT file
When editing the new version of the XSLT file, you first have to ensure that the new verb template ManagerAndEmployeeByEmployeeUserID is contained in the global dispatcher template and will be invoked:
Add the actual XSLT template can be added at the end of the file:
The new template is very similar to the "ManagerOfEmployeeByUserID" template. It has a different name and additionally invokes the GetUserByID template, which ensures that the user ID of the employee is added to the query result set.
(For this verb, a corresponding e-mail verb is not needed. Since it returns only two user IDs, there is no major performance advantage over the default verb for e-mail resolution "Email Address for Users by user ID.")
After saving your changes, the XSLT mapping file is ready for deployment.
Deploying the XSLT file
To deploy the new XSLT file, you must install it on every node where you configured Business Process Choreographer. For Network Deployment installations, you must additionally install it on the deployment manager. Make sure that you install the XSLT file to the same relative directory on all nodes.
Consider also installing it to the same directory where the default Human Task Manager XSLT files are installed: <WebSphere Process Server installation directory>/ProcessChoreographer/Staff/. Where the WebSphere Process Server installation directory is the directory that also contains the WebSphere bin, java, and lib directories. Make sure that you do not use the name of a default XSLT file already installed there.
If not already done, create your own staff plug-in configuration and associate it with your adapted and installed XSLT file. In case of a Network Deployment environment, create the configuration on the deployment manager and use the node scope. Repeat this step for each node that hosts members of the cluster.
Now you can use the new staff verb when modeling human tasks. Make sure that your task model is associated with the JNDI name of your new staff plug-in configuration instead of the default bpe/staff/userregistryconfiguration.
Assigning people from custom properties, process variables, or the input message
In some business scenarios, you might want to assign staff query results (also known as people assignment) dynamically by overriding Human Task Manager staff resolution. In scenarios where you always want to perform staff resolution on your own (for example, since you want to plug-in your custom staff repository with advanced query functionality), you will use the staff resolution post-processor plug-in. But for scenarios where you only want to provide your own staff resolution results dynamically for a certain human task activity in the business process, you might want to choose one of the options described next.
Human Task Manager staff resolution is able to provide dynamic and instance based staff resolution results using context variables that enable you to involve data from input messages, custom properties, or process variables. By using this feature, you can create a custom property or Business Object (BO) message that contains the group name or the list of user IDs you want to dynamically assign, and refer to it in the staff verbs provided by Human Task Manager or your own custom verbs.
The two examples below show how you can assign a group name to a custom property, resolve the group members dynamically, and provide a set of user IDs dynamically, thus perform staff resolution fully outside of Human Task Manager staff resolution. You can, of course, use other combinations of context variables and staff verbs as well.
Assign group members dynamically
To assign group members dynamically, you can use the staff verb "Group members" and populate the group name using the business process custom property "myGroup."
When modeling the inline human task, enter the value
as value for the GroupName parameter.
Create a snippet activity in your business process that is executed prior to the human task that is using the custom property.
Set the custom property
myGroup using the following statement:
setProcessCustomProperty( "myGroup", "cn=managers,ou=austin,o=mycompany,c=us" );
Instead of assigning the static value
cn=managers,ou=austin,o=mycompany,c=us, you will normally
use a program variable that you initialize in advance. (For more details on snippet activities, see the WebSphere Process Server Information Center.)
(This example will only work for inline human tasks. For standalone tasks you will have to provide dynamic content from the process context using their input message.)
Assign a set of user IDs dynamically
To assign a set of user IDs dynamically, you can use the staff verb "Users by user ID" and populate the "UserID" parameter with a context variable that refers to a process variable containing a string array with the set of user IDs.
When modeling the inline human task, enter the value
as value for the
UserID parameter. This assumes that you have created a data typed variable with the name
"PotOwnersVar," which has no part. It contains the message element potOwners
that resolves to a string array containing the set of user IDs.
Figure3 shows how to specify the context variable expression for the human task.
Figure 3. Specify potential owners
Figure 4 shows how to specify the business object data type to be accessed.
Figure 4. Potential owners business object
You can populate the set of user IDs in a previous assign or snippet activity.
Figure 5 shows how to specify the context variable values in an assign activity.
Figure 5. Assign activity
In your scenario, you will probably assign the user IDs from another process variable instead of statically, as in this example. (This example will only work for inline human tasks. For standalone tasks, you will have to provide dynamic content from the process context using the task input message.)
For process administrative tasks you can assign user IDs from the process input message as well, using for example,
%wf:variable.\operation1Parameters\reader%, where you do not specify a variable name in order to
access the process input message, and where "operation1Parameters" is the input message part name; whereas
"reader" is the message element that resolves to a string and contains the reader user ID. However, notice that populating authorization data from a process input message can result in a security leak,
if the process input message can be provided by non secure sources.
Integrate proprietary staff repositories with Human Task Manager
If you want to integrate a proprietary staff repository with Human Task Manager, you should implement a custom user registry for it. This integrates your repository with WebSphere Application Server security, and, by using the user registry staff resolution plug-in, you will automatically query your repository through the WebSphere user registry component. Figure 6 illustrates this option.
Figure 6. Using a custom user registry
For more details on creating and configuring a custom user registry, refer to the WebSphere Application Server Information Center. If you register and configure your custom registry with the application server, and use the bpe/staff/userregistryconfiguration as staff plug-in configuration JNDI name for your human tasks, you will automatically query your repository for users and groups.
If you want to use more sophisticated queries than the user registry plug-in supports, you can implement a staff query result post-processor plug-in (in the next section) that fully replaces the original staff query result and thus performs full staff resolution. The original staff resolution plug-in becomes a dummy that just prepares the input data for the post-processor plug-in. The post-processor plug-in accesses your proprietary staff repository and performs full staff resolution. Figure 7 shows how the post-processor plug-in is involved during staff resolution.
Figure 7. Staff resolution using the post-processor plug-in
If you want to use more sophisticated queries than the user registry plug-in supports, and you use Human Task Manager together with WebSphere Portal, then you can also implement a WebSphere Member Manager repository adapter and use the WebSphere Member Manager staff resolution plug-in for staff resolution, as shown in Figure 8.
Figure 8. Using a WebSphere Member Manager repository adapter
The WebSphere Member Manager staff resolution plug-in is packaged and documented with WebSphere Portal. Be aware that the implementation of a custom repository adapter for WebSphere Member Manager requires permission from your WebSphere Portal sales representative.
Post-processing staff query results
The staff resolution plug-ins provided by Human Task Manager offer powerful query capabilities for the creation of authorization rules. But for some special cases, you might need to modify the results provided by the staff resolution plug-in. For example, to implement workload balancing, you might want to remove users that already have a high workload from the result set, or add additional users if the workload for the whole set of returned users is already high.
To help you implement such workload balancing scenarios, Human Task Manager provides the StaffQueryResultPostProcessorPlugin service provider interface, which you can implement and then alter the staff query result returned by the staff resolution plug-in. (This plug-in interface is also useful if you want to integrate a custom staff repository with Human Task Manager and need more query capabilities than a custom user registry can provide, but cannot use the WebSphere Member Manager.)
As described in the Part 2 of this series, the post-processor plug-in (also known as people assignment post-processor plug-in) is invoked after Human Task Manager staff resolution has been performed. The plug-in interface consists of five methods, all of which have a similar signature, but are invoked for different object types: human task instances, task templates, escalation instances, escalation templates, and application components. Since the method for task instances is the most important, we will describe the programming model based on this method:
StaffQueryResult processStaffQueryResult( StaffQueryResult originalStaffQueryResult, Task task, int role, java.util.Map context );
The method receives the result of the staff queries performed by the staff resolution plug-in that runs in advance with the parameter originalStaffQueryResult. This parameter is an object that implements the StaffQueryResult interface. As additional context information, the method also receives the API object representation of the human task and the authorization role for which staff resolution is performed. The set of authorization role (assignment reason) int values is defined by the com.ibm.task.api.WorkItem interface. Further context information like the context variables and their values is available in the context map. If your staff verb parameters contain, for example, the variable %wf:process.starter% then the map will contain the key "wf:process.starter" and the value "jim", where "jim" is the user ID of the process starter. In this method, you can extract the collection of com.ibm.task.spi.UserData records by invoking:
This method returns a java.util.Collection of UserData records, to which you can add or remove records. If you want to add new UserData records, you can create them using the com.ibm.task.spi.StaffQueryResultFactory factory method:
StaffQueryResultFactory factory = StaffQueryResultFactory.newInstance(); factory.newUserData( java.lang.String userID, java.util.Locale preferredLocale, java.lang.String eMailAddress );
If you want to make greater changes, or if you want to fully replace the original staff query result, you can create a new com.ibm.task.spi.StaffQueryResult object with one of the other factory methods:
StaffQueryResultFactory factory = StaffQueryResultFactory.newInstance(); // For RESULT_TYPE_EVERYBODY or RESULT_TYPE_NOBODY factory.newStaffQueryResult(int resultType); // For a set of UserData records and result type RESULT_TYPE_USERIDS. factory.newStaffQueryResult(java.util.Collection userData); // To create a group work item, with result type RESULT_TYPE_GROUPIDS. factory.newStaffQueryResult(java.lang.String groupID);
When implementing a post-processor plug-in, consider:
- If the staff resolution plug-in has removed users from the result set using the remove query, then it is the duty of the post-processor plug-in to ensure that it does not re-add one of these users to the result set. Otherwise, the four-eyes principle or other security policies might be violated. The context map provides a list of removed user IDs as a string array value of the key HTM_REMOVED_USERS.
- The plug-in methods are invoked with an EJB context. All restrictions for implementing EJB methods apply for the plug-in code as well.
- The methods are invoked with the security context of arbitrary users; you cannot rely on the fact that the process starter subject is used, although this applies to most post-processor plug-in invocations.
- The methods are invoked within an open transaction. If you invoke other Human Task Manager EJB API methods and query for additional data, you might not see data created during the running transaction, since it has not yet been persisted.
- If your plug-in code invokes Human Task Manager API methods that lead to updates in the Business Process Choreographer database, database deadlocks could result.
When you have finished programming, assemble the plug-in:
- Assemble the plug-in class and its helper classes to a JAR file.
- Provide a plug-in registration file in the META-INF/services/ directory of your JAR file. The registration mechanism conforms to the Java 2 service provider interface specification.
- Create a file with the name "com.ibm.task.spi.plug-in_nameStaffQueryResultPostProcessorPlugin, where plug-in_name is the name of the plug-in, as it will be invoked by Human Task Manager.
- In the first line of the file that is neither a comment line nor a blank line, specify the fully qualified name of the plug-in class.
Install the plug-in JAR file in a way that the Human Task Manager application (class loader) can access it. You can choose between several installation methods:
- Add your plug-in JAR file to the (task or process) application EAR file. In the deployment descriptor editor in WebSphere Integration Developer, install the JAR file for your plug-in as a project utility JAR file for the J2EE application of the main EJB module. This makes the plug-in available for exactly this application.
- Put the JAR file in a WebSphere Application Server shared library and associate the library with the Human Task Manager enterprise application. To make the JAR file available in a Network Deployment environment, distribute the JAR file on each node manually, and then install the shared library once for each cell. Note that this option requires service level 220.127.116.11.
- Install the JAR file in the lib/ext/ or the java/jre/lib/ext/ directory of WebSphere Application Server (on every node in case of a network deployment environment).
You can register your plug-in using the human task container custom property Staff.PostProcessorPlugin (in WebSphere Process Server, select Application servers => server_name => Human task container => Custom properties). The value of the property is the plug-in name, as you specified it in the META-INF/services/ directory of your JAR file above (plug-in_name). Be aware that you can register only a single post-processor plug-in with Human Task Manager.
See the WebSphere Process Server Information Center for further information on how to assemble and install the plug-in.
Staff query result sharing
Eligible staff query results are shared to improve the overall Human Task Manager performance. For example, all staff query results for an authorization role of a task template that do not access context variables are shared for all task instances of this template. This means that staff resolution occurs only once (per authorization role) for this template, and all instances of this template use the same result. Even when context variables are accessed, results based on the same set of context variable values are still shared. Since the post-processor can return different results for every task instance of a template, its staff query results are not eligible for sharing. Thus, sharing of post-processed staff query results is disabled by default.
If you use the post-processor plug-in to perform full staff resolution (instead of, for example, load balancing), and you do not want to return different results for each task instance, you can also enable sharing for post-processor results. This results in less invocations of the post-processor plug-in. You can enable sharing using the Human Task Container custom property Staff.PostProcessorPlugin.EnableResultSharing. Be aware that you need to install either interim fix IZ07326, or a service level of at least 18.104.22.168 to have support for this property.
To configure this property, use the WebSphere administrative console. If you configured Business Process Choreographer on a server, go to Servers => Application servers => serverName => Human task container settings => Human task container => Custom Properties. If you configured Business Process Choreographer on a cluster, go to Servers => Clusters => clusterName => Human task container settings => Human task container => Custom Properties. Change the value of the Staff.PostProcessorPlugin.EnableResultSharing custom property from its default "false" to "true". Save your changes, then restart the affected application server(s). You have to change the value of this property before you deploy human tasks or business processes. You must not change the value of this property after deploying or using human task or business process module templates, either in development or production environments. (Changing the value of this property in production can cause unpredictable results during a staff query result refresh.)
Also, when setting this property to true, the post-processor plug-in will be invoked differently, since it now behaves like a staff resolution plug-in. The value of the method parameters task, escalation, template (escalation or task template), and applicationComponent is null. The value of the parameter role is com.ibm.task.api.WorkItem.REASON_NONE (-1). During staff query result refresh, the method:
StaffQueryResult processStaffQueryResult(StaffQueryResult originalStaffQueryResult, Task task, int role, java.util.Map context)
is also invoked to refresh results for escalations, task and escalation templates, and application components as well. The other methods are not invoked during staff query result refresh.
Human Task Manager provides powerful instance- and business context-based authorization for people involved in business processes and Service Oriented Architectures. Human Task Manager performs staff resolution queries based on flexible authorization rules called staff verbs.
This article described how you can customize Human Task Manager staff resolution to better fit your needs by exploring how you can adapt existing staff verbs, how to create additional verbs, and how you can access the business context for staff resolution. Integrating proprietary staff repositories with Human Task Manager and performing workload balancing for the people involved in your business processes was also explained.
More in this series
- Part 1: Understanding the concepts and components of staff resolution
- Part 2: Understanding the programming model for staff resolution
I would like to thank my colleagues Thomas Bernhardt, Gabriel Dermler, and especially Hans Schoen for their help in preparing this article.
- In the WebSphere Process Server Information Center you can find further information on WebSphere Process Server.
- More details on Snippet activities can be found using the following links, or by searching for "snippet activity" in the WebSphere Process Server Information Center
- The Business Process Choreographer samples page offers you various examples for how to implement human tasks and business processes.
- In the WebSphere Application Server Information Center you can find further information on WebSphere Application Server.
- In the WebSphere Portal Information Center search for "Member Manager staff plug-in provider" to find more information on the WebSphere Member manager Staff resolution plug-in.
Dig deeper into Business process management on developerWorks
Get samples, articles, product docs, and community resources to help build, deploy, and manage your cloud apps.
Keep up with the best and latest technical info to help you tackle your development challenges.
Software development in the cloud. Register today to create a project.
Evaluate IBM software and solutions, and transform challenges into opportunities.