级别: 中级 Kurt Lind (klind@de.ibm.com), 顾问软件工程师, IBM
2008 年 4 月 23 日
本文介绍 Business Process Choreographer 人员解析的自定义选项,并说明如何创建和自定义人员谓词、如何对人员解析结果进行后期处理,以及如何为人员解析动态地分配员工。
来自 IBM WebSphere Developer Technical Journal.
引言
Human Task Manager 是一个 IBM® WebSphere® Process Server 组件,它支持人与 Web 服务和业务流程之间的交互。人们可以使用发起任务来调用 Web 服务,使用参与任务充当 Web 服务本身,并通过调用或使用纯人工任务与他人协作。通过与用于编排业务流程的 Business Flow Manager 结合,Human Task Manager 为执行涉及人工的业务流程提供了强有力的支持。这两个组件共同构成了 Business Process Choreographer。
Business Process Choreographer 的主要功能之一是能够为业务流程和人工任务提供基于实例的授权。该功能基于 Human Task Manager 人员解析(也称为员工解析),在将人工任务分配给拥有多个授权角色的员工时可以考虑业务上下文。
Human Task Manager 提供了强大的缺省人员谓词集,在授权规则建模方面为您提供支持。这些规则提供的功能远远超出了 J2EE™ 授权所提供的可用功能。例如,可以对类似于四眼原则这样的复杂规则进行建模,或者授权某位员工的管理员。但是,要调整缺省的 LDAP 配置以适应组织的 LDAP 服务器和模式,或者将您的专有人员目录与 Human Task Manager 人员解析相集成,您可能希望扩展缺省的人员谓词集。
本文介绍 Human Task Manager 人员解析的自定义选项。您将了解在创建或自定义人员谓词时使用的 XML 构件、受支持人员查询的语法,以及 Human Task Manager 所提供的人员解析自定义插接点:
- 通过创建新的人员插件配置来调整现有人员谓词,以适应您的 LDAP 模式。
- 在谓词集和 XSLT 谓词映射文件中创建新的人员谓词。
- 通过输入消息或其他流程上下文数据提供人员解析结果。
- 将专有人员存储库与 Human Task Manager 集成。
- 使用人员解析后处理器插件对 Human Task Manager 执行工作负载平衡。
本文假定您已熟悉以下白皮书所述的 Business Process Choreographer 概念、体系结构和编程模型:WebSphere Process Server V6 Business Process Choreographer:Concepts and Architecture 和 WebSphere Process Server V6.0 Business Process Choreographer Programming Model。此外,在继续阅读本文之前强烈建议您阅读本系列的第 1 部分和第 2 部分。
了解人员解析 XML 构件
在开始编写新的人员查询谓词(也称为人员分配条件)之前,您需要进一步了解人员谓词集格式、用于将参数化的谓词转换为本机人员插件语言的 XSLT 模板,以及您所选择的人员解析插件正在使用的 XML 语言。我们将在接下来的部分中介绍这些元素。
人员谓词集
人员查询谓词是抽象的人员查询定义,在建模时可用于对授权规则进行建模。WebSphere Integration Developer Task Editor 使用这些谓词定义来呈现谓词建模面板(图 1),您在此可以通过选择所需谓词并输入参数值来定义授权规则。
图 1. 人员谓词建模
每个人员查询谓词都包含名称、描述和参数集。参数可以是可选或强制的。通过选择谓词并输入参数值来定义授权规则。
所有人员查询谓词组合在一起,构成所谓的谓词集,在 WebSphere Integration Developer 中作为 XML 文件提供。缺省谓词集是 WebSphere Integration Developer 的组成部分,其中列出由 Human Task Manager 提供的所有谓词。您会在 <WebSphere Integration Developer 安装目录>/wstools/eclipse/plugins/com.ibm.wbit.tel.ui_6.0.2/xml/ 目录中找到 VerbSet.xml 文件。(如果您使用的是除 WebSphere Integration Developer V6.0.2 以外的版本,则版本部分 (ui_6.0.2) 会有不同。如果可以选择,请使用包含最高版本号的目录。)
通常由管理员来定义或自定义谓词集。Task Modeler 不修改谓词集,但使用 Task Editor 基于此文件呈现的屏幕。人员查询谓词与编程语言方法类似。它包含名称和参数集。下列谓词示例来自缺省谓词集:
清单 1
<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>
|
谓词定义主要由其名称、描述和一组参数定义构成。对于每个参数,可以为其指定名称、类型和一组提示。
谓词集 XML 文件的结构如下:
清单 2
<?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>
|
谓词集文件包含常规的 XML 序言、命名空间声明、谓词集描述和谓词定义(在 <vs:DefineVerb ...> 内)。
谓词定义具有如下结构:
清单 3
<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>
|
根元素包含用于标识谓词的属性名称,该名称在您选择的人员插件配置的 XSLT 谓词映射文件中必须有对应项。接下来是谓词描述和强制参数集。强制参数集之后是可选参数集。每个集合中的参数数目可以是从零到很多。
可选参数和强制参数的参数定义是相同的。参数定义包含参数名称、数据类型以及一些可选提示。这些参数显示在 Task Editor 谓词建模屏幕中,可以在此输入参数的值。提示显示在建模屏幕的下拉框中,并且是只读的,如图 2 所示。您可以选择其中之一作为参数值。
图 2. 谓词参数提示
参数化人员谓词
当您在 Task Editor 谓词建模面板中已完成授权规则建模时,所收集的数据将作为参数化谓词存储在模块 EAR 文件中,该文件具有如下结构:
清单 4
<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>
|
参数化谓词包含名称和参数集。两者在 XSLT 映射文件中都需要有各自的对应项,因为参数化谓词 XML 代码片段是 XSL 转换步骤的输入。XSLT 映射将参数化人员查询谓词转换为所选人员解析插件(也称为员工目录插件)的查询语言。用于呈现建模屏幕的信息(如描述、参数类型和提示)不属于参数化谓词语法的一部分。
XSLT 映射文件
参数化人员谓词是在任务部署过程中执行的 XSLT 谓词映射的输入。XSL 转换将此输入映射到您选择的人员解析插件所支持的 XML 语言,并将人员存储库特性视为与 LDAP 模式类似。作为 WebSphere Process Server 的一部分,预配置人员插件配置(也称为员工目录配置)提供了示例谓词映射 XSLT 文件。请不要编辑这些文件,而应基于这些文件修改后的副本创建新的人员插件配置,因为产品更新可能会替换示例 XSLT 文件。
谓词映射 XSLT 文件不是由人工任务建模器或人工任务部署器编辑的,而是由创建或调整人员谓词集的管理员编辑的,管理员对于谓词映射 XSLT 文件所访问的人员存储库(也称为员工目录)有更深入的了解。每个新建(或调整)的谓词在谓词映射文件中都需要有作为 XSLT 模板的对等项。XSLT 模板需要支持谓词的每个参数,至少应忽略参数而不报告错误。
清单 5 显示了两个 XSLT 模板,用于为用户注册中心人员解析插件转换“Users by user ID”谓词。
清单 5
<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>
|
对应于上面所示参数化谓词的转换输出为:
清单 6
<sur:staffQueries>
<sur:userID name="sarah"/>
<sur:userID name="bill"/>
</sur:staffQueries>
|
Human Task Manager 附带的示例映射 XSLT 文件的结构针对模块化中等大小的映射样式表进行了优化。对于更大的映射样式表,使用导入和将模板分散到许多文件中会提供更优化的模块化和更好的概览。
Global 部分
在样式表的开头,声明一组可在整个文档中用作常量的变量。阈值参数是此类变量的一个很好的示例,因为对于所有查询返回的用户 ID 而言,都可能具有相同的上限。另一个很好的示例是要在 LDAP 目录中寻址的对象类和属性集。
清单 7 显示了 LDAP 人员解析插件的示例映射 XSLT 文件的表示部分。
清单 7
<?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 -->
|
所有示例映射 XSLT 文件都使用根调度程序模板,根据谓词名称将谓词转换委派给专用模板。未知谓词或此插件不支持的谓词应利用消息表明此事实。
清单 8
<!-- 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 -->
|
请注意,示例 LDAP XSLT 文件另外使用一个部分将用户 ID 属性或电子邮件属性映射到 returnAttribute 变量,具体取决于谓词类型。一般人员谓词将返回用户 ID,而只有针对电子邮件地址的特殊人员查询谓词会返回电子邮件地址。
样式表的其余部分由谓词映射模板组成,在接下来的部分中将描述这些模板。请注意,XSLT 输入的命名空间与任务执行语言 (TEL) 命名空间不同。这是由历史原因造成的,这是支持基于以前产品版本编写的自定义 XSLT 文件所必需的。
谓词特定映射模板
实际的谓词映射是由创建人员插件特定查询的专用模板执行的。这些模板提取谓词参数并将其复制到查询参数,然后在需要时调整查询以适应人员存储库的模式。要更改模板或编写新模板,需要完全了解目标 XML 查询语法。下列示例显示了一组谓词映射 XSLT 模板。
最简单的模板仅创建一个不变的 XML 文档,即 everybody 查询。它不含映射到输出文档的参数:
清单 9
<xsl:template name="Everybody">
<sldap:staffQueries>
<sldap:everybody/>
</sldap:staffQueries>
</xsl:template>
|
此模板仅创建输出查询,不复制任何参数值。
一个更为复杂的示例是为“Users by user ID”谓词设计的模板。此查询的示例映射模板具有如下结构:
清单 10
<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>
|
模板的第一部分将相关参数内容从谓词中提取出来,然后将其复制到变量 Name0 和 Name1 中。
代码生成仍然从打开查询开始。从样式表开头定义的常量中复制 staffQueries 元素的阈值属性值。
第一个查询参数 Name0 是强制的,因此可以无条件生成。第二个查询参数 Name1 是可选的,因此只有设置了该参数时才会生成。userID 查询的输出生成委派给参数化 GetUserByID 模板。
最后是关闭查询变量 </sldap:staffqueries>。
调用的 GetUserByID 模板具有如下结构:
清单 11
<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>
|
输入参数 username 被声明为用于下面的输出生成。查询输出是静态的,但 name 属性例外,该属性接收模板输入参数 username 的值。
因此,假定样式表的输入文档如下:
清单 12
<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>
|
这两个模板将生成如下输出:
清单 13
<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>
|
人员查询
上述示例生成将由 LDAP 人员解析插件执行的人员查询(也称为员工查询)。查询语言特定于各个插件,稍后将进行说明。
这些查询的结果将传递给人员解析后处理器插件(如果可用),或者直接传递给授权管理,授权管理基于该结果创建工作项,并将其存储在 Business Process Choreographer 数据库中,以便以后进行授权检查。
StaffQueryResult 接口
人员查询的结果可以通过 com.ibm.task.spi.StaffQueryResult 接口很好地说明。该接口用于将人员查询结果传递给后处理器插件,以及将后期处理结果传递给授权管理。该接口有一个结果类型,可以是下列四个值之一:
- Everybody (RESULT_TYPE_EVERYBODY) 确定每个经过身份验证的用户都获得授权。
- Nobody (RESULT_TYPE_NOBODY) 确定未向任何用户授予此角色,并且只应用授权继承。
- User IDs (RESULT_TYPE_USERIDS) 确定返回一组用户。
- Group IDs (RESULT_TYPE_GROUPIDS) 确定返回一个组 ID 以创建组工作项。为了将来方便扩展,组 ID 作为字符串数组的元素返回。
如果结果类型为类型 user IDs,则提供用户记录集合。这些用户记录是接口 com.ibm.task.spi.UserData 的实例,包含三个属性:
- 用户的用户 ID(在此接口中称为用户名称)。
- 用户的电子邮件地址。此属性并非总包含值。在版本 6.0.2 中,只有当每个返回用户都恰有一个电子邮件地址时,人员解析才能正确地填充此字段。
- 用户的首选区域。此属性并非总包含值。(在版本 6.0.2 中尚未使用此属性,因为其始终为空。)
如果结果类型为类型 Group IDs,则提供包含组 ID 的字符串数组。在版本 6.0.2 中,此数组不能包含一个以上的元素,引入数组的目的是方便将来扩展。
独立于结果类型,接口还包含一个只读属性,即失效日期 (valid-until date)。此属性是在对象创建时初始化的,用于确定结果将在多长时间内保持有效。在此时间之后,此属性可用于人员查询刷新操作。要计划失效日期,应考虑人员查询结果的任务容器属性超时值。
Human Task Manager API 使用类似的接口返回 getUsersInRole() 方法的结果。此接口 (com.ibm.task.api.StaffResultSet) 与 StaffQueryResult 接口在以下方面存在差异:
- 结果类型也可以包含值 RESULT_TYPE_USERIDS_AND_GROUPIDS。如果由于授权角色继承而考虑多个工作项,则使用此类型,从而使结果同时包含用户 ID 和组 ID。
- 对于结果类型 user IDs,只提供包含这些用户 ID 的字符串数组,而不提供完整的用户记录。
- valid-until 属性不可用。
人员解析插件及其查询
由于 Business Process Choreographer 将人员解析委派给插件,因此您可以使用多种类型的员工目录。人员解析插件负责从外部员工目录(如 LDAP 目录)检索员工信息。人员解析插件查询人员存储库并检索分配给某个工作项的员工集。它们还参与部署时,以创建在运行时执行的最佳格式的授权规则。
如果在部署时调用人员解析插件,则会接收 XSL 转换输出的 XML 文档,并将其转换为最佳格式,以存储在 Process Choreographer 运行时数据库中。
在运行时,插件对与其关联(使用人员插件配置)的人员存储库执行查询,并返回人员查询结果,如用户 ID 的列表。Process Choreographer 授权管理器基于此结果创建工作项。
人员解析插件在运行时系统中表现为人员插件提供程序(也称为员工目录提供程序),并且可以附带多个人员插件配置,每个配置都有不同的 JNDI 名称(在对人工任务建模时使用)并连接到员工目录服务器。
人员解析插件查询语言
在编写或自定义人员谓词映射 XSLT 文件时,需要了解有关其 XML 输出格式的详尽知识。XSL 转换输出的是特定人员解析插件可以执行的查询语言。本部分介绍多种人员解析插件所支持的查询的语法。
Process Choreographer 附带的所有插件具有类似的 XML 查询语言,并采用如下语法:
清单 14
<staff:staffqueries threshold="positive nonzero integer number">
staff query element *
</staff:staffqueries>
|
<staffqueries> 说明可以包含一个或多个人员查询元素,查询 <everybody/>、<nobody/> 和 <groupID/> 除外,它们只能单独使用。
所有人员解析插件都支持可选阈值属性。使用该参数可以限制由人员查询返回的用户总数。在人工工作流中,通常不需要为人工任务分配非常多的用户。如果人员查询返回大量用户,则查询很可能没有以可控制的方式定义,而分配给某个任务的大量用户将使系统变慢,而不会有助于加快工作执行速度。独立于阈值属性,员工目录可以将自己的限制施加于潜在的结果集大小。
简单人员查询
下列简单人员查询不需要目录的访问权限,Business Process Choreographer 附带的所有人员解析插件都支持它们。
-
Everybody
经过 WebSphere Application Server 身份验证的每个用户都可以访问基于此查询创建的工作项。
<staff:staffQueries>
<staff:everybody/>
</staff:staffQueries>
|
-
Group ID
此查询按其 WebSphere Application Server 组 ID 分配整个组,而不解析其成员。基于此查询结果创建了一个组工作项。
<staff:staffQueries>
<staff:groupID name="group ID"/>
</staff:staffQueries>
|
名称属性是强制的,并且可以包含上下文变量。包含上下文变量的表达式的计算结果必须等于有效的 WebSphere Application Server 安全组 ID。此查询还支持使用自定义 JAAS 登录模块添加的 WebSphere Application Server 安全动态组。
-
Nobody
没有为此工作项分配用户,只应用角色继承。您很少需要此查询。
<staff:staffQueries>
<staff:nobody/>
</staff:staffQueries>
|
-
Remove
从人员查询结果集中删除一个条目。在此执行四眼原则非常有用。它只能与返回用户 ID 的查询结合使用。
<staff:staffQueries>
<staff:remove value="user ID to remove"/>
</staff:staffQueries>
|
该值属性是强制的,并且可以包含上下文变量,如 %htm:property.myProperty%。支持多值上下文变量。包含上下文变量的表达式的计算结果必须等于一个或多个 WebSphere Application Server 安全用户 ID。
-
User ID
此查询表示显式分配到特定的 WebSphere Application Server 用户 ID。
<staff:staffQueries>
<staff:userID name="valid WebSphere user ID"/>
</staff:staffQueries>
|
即使此查询允许按名称分配到用户,您也应当避免在人工任务模块中对用户 ID 进行硬编码。但是,将工作项按 ID 分配到用户的能力对于基于上下文数据的分配非常有用;例如,分配流程启动者。
名称属性是强制的,并且可以包含上下文变量,如 %wf:process.starter%。
例如:
<staff:staffQueries>
<staff:userID name="Billy"/>
<staff:userID name="%wf:process.starter%"/>
</staff:staffQueries>
|
复杂人员查询
-
类型 user 查询
类型 user 查询可以基于其专有名称或用户 ID 查找员工。此类型的查询与上下文变量或中间结果联合使用时非常有用。以下是 LDAP 插件的示例:
<sldap:staffQueries>
<sldap:user dn="cn=Mary Smith, ou=mydivision, o=acme, c=us"
objectclass="person" attribute="uid"/>
</sldap:staffQueries>
|
-
类型 usersOfGroup 查询
此查询类型基于组专有名称或组 ID 检索组成员。下列示例演示 LDAP 和用户注册中心插件的查询:
<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>
|
-
类型 search 查询
要查找员工或组,可以使用 search 查询。LDAP 和用户注册中心插件的下列示例描述了此查询的语法:
<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>
|
-
类型 intermediateResult 查询
对于一些查询,所需的结果只能通过一系列查询语句完成。例如,要检索流程启动者的管理员的用户 ID,首先必须解析管理员用户对象,并且只有在后续查询中才能解析管理员的用户 ID。
查询类型 intermediateResult 支持此类复杂查询。它支持封装类型 user、usersOfGroup 或 search 的单个查询,并将其结果存储在变量中,该变量在后续查询中的用法与上下文变量类似。intermediateResult 查询元素的结果不存储在全局人员查询结果集中。
此示例简要说明如何使用 LDAP 人员解析插件来检索流程启动者的管理员:
<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>
|
在上述示例中:
- 检索流程启动者的管理员的 LDAP dn。假定每个用户的管理员属性包含其管理员的 dn,并且 uid 属性包含 WebSphere Application Server 用户 ID。
- 查询结果存储在上下文变量管理器中,并包含管理员的 dn。
- 由用户查询检索查询结果,其中包含管理员的用户 ID。中间结果管理员的用法与上下文变量类似。假定 uid 属性包含 WebSphere Application Server 用户 ID。
人员解析插件的查询支持
取决于查询 API 的灵活性和人员解析插件所访问的员工目录的功能,插件自身可以支持上述人员查询的特定子集。
-
系统人员解析插件
系统人员解析插件仅支持简单查询。
由于此插件仅支持硬编码的人员分配,因此不适用于生产环境。但是,它被预配置为开箱即可运行,因此对于测试场景非常有用。
-
用户注册人员解析插件
可以使用用户注册人员解析插件来引用 WebSphere Application Server 已知的用户和组。该实现是基于 WebSphere Application Server 安全组件的 UserRegistry 接口。通常将其配置为使用外部员工目录对用户进行身份验证,以及检索可以映射到 J2EE 安全角色的用户和组。
该插件支持所有简单查询和查询类型 user、usersOfGroup 和 search。
此查询示例解析用户注册中心已知的组成员:
<sur:staffQueries>
<sur:usersOfGroup groupName="Administrators"/>
</sur:staffQueries>
|
更复杂的示例解析 Administrators 组的所有成员的用户 ID,以及其 ID 以“Mi”开头的所有用户的 ID:
<sur:staffQueries>
<sur:usersOfGroup groupName="Administrators"/>
<sur:search type="user" name="Mi*"/>
</sur:staffQueries>
|
-
LDAP 人员解析插件
LDAP 人员解析插件通过 LDAP 目录查询可用的组织信息。例如,它可以计算 LDAP 组的所有成员,或检索 LDAP 对象的属性,如某个员工对象的管理员属性。
LDAP 人员查询不完全限于为 WebSphere Application Server 用户注册中心(安全)配置的目录。但是,在 LDAP 目录中管理的用户 ID 必须与 WebSphere Application Server 安全进行身份验证使用的 ID 匹配。否则,或者 Human Task Manager 人员解析检索的员工不能通过 WebSphere Application Server 的身份验证,或者经过身份验证的员工无法看到其工作项。(用于身份验证的用户 ID 区分大小写。)
该插件是功能最强大的人员解析插件,因此可用于生产环境。该插件支持所有简单查询和查询类型 user、usersOfGroup、search 和 intermediateResult。
下列示例代码显示 usersOfGroup 和 search 查询:
<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>
|

 |

|
自定义 LDAP 人员解析插件
LDAP 标准不对 LDAP 目录管理的对象和属性施加任何限制,因为 LDAP 模式是可变的。相应地,无法为 LDAP 人员解析插件提供适合所有用户需求的标准配置。但是,为了帮助您创建适合企业目录的人员插件配置,Human Task Manager 提供缺省的 LDAP 插件配置,可用作您自己的配置和修改 XSLT 文件的示例。
在创建您的自定义 LDAP 插件配置时,您应当:
- 创建新配置并为其提供唯一的 JNDI 名称。在您的任务模型中使用此新 JNDI 名称代替缺省的名称。
- 请不要编辑和重用缺省的 LDAP XSLT 映射文件,而应创建此文件的自有副本并对其进行更改。
- 在您的新配置的自定义属性面板中,请确保:
-
ProviderURL 必须指向您的 LDAP 服务器。请确保同时使用了正确的端口。如果您的 LDAP 服务器需要 SSL 连接,请确保在 WebSphere Application Server 和 LDAP 服务器中启用了 SSL。
-
BaseDN 必须与您的 LDAP 服务器配置相匹配。
- 如果您的 LDAP 服务器要求经过身份验证的连接,则将
AuthenticationType 更改为“simple”。创建一个 J2C 身份验证别名,并使用 AuthenticationAlias 参数注册其名称。
- 对于其他强制参数,可以复制缺省值。
- 如果到您的 LDAP 服务器的 JNDI 连接要求其他参数,则可以使用其他参数作为名称-值对。然后,将在建立到您的 LDAP 服务器的 JNDI 连接之前设置这些属性。可以使用最多五个其他 JNDI 属性。
LDAP 的示例 XSLT 映射文件 LDAPTransformation.xsl 设计为可以方便地进行调整,以适应其他 LDAP 模式。缺省 XSL 模板使用需要 LDAP 模式特定参数的变量。在大多数情况下,调整这些变量的值足以满足需求。缺省情况下,LDAP XSLT 文件对于员工对象支持 LDAP 对象类 inetOrgPerson,对于组对象支持 groupOfNames。
下列变量可用,因此可以调整 LDAP XSLT 文件以适应您的 LDAP 模式:
-
DefaultPersonClass 缺省为“"inetOrgPerson”,并确定将为员工对象使用哪个 LDAP 对象类。
-
DefaultUserIdAttribute 缺省为“uid”,并确定哪个员工对象属性包含员工的用户 ID。
-
DefaultMailAttribute 缺省为“mail”,并确定哪个员工对象属性包含员工的电子邮件地址。
-
DefaultManagerAttribute 缺省为“manager”,并确定哪个员工对象属性包含员工的管理员专有名称 (dn)。
-
DefaultGroupClass 缺省为“groupOfNames”,并确定哪个 LDAP 对象类将用于组对象。
-
DefaultGroupClassMemberAttribute 缺省为“member”,并确定哪个组对象属性包含组成员专有名称 (dn)。
-
DefaultRecursivity 缺省为“yes”,并确定是否也解析子组的组成员。
-
Threshold 缺省为“20”,并确定人员查询最多将检索多少用户 ID 记录。可以更改此值,但需要考虑的是,大量的分配员工(例如,潜在所有者)通常不会加快工作速度,却很有可能使系统变慢,因为在数据库中存在更多的数据。
提供了用于调整 XSLT 模板 PersonSearch 和 GroupSearch 的其他变量。如果使用这两个谓词,还要考虑调整相应的变量。
编写新的人员谓词及其 XSLT 模板
Human Task Manager 提供了强大的缺省人员谓词集,以便您能对复杂的授权规则进行建模。但是,有时会需要其他谓词,而 Human Task Manager 允许您自定义和扩展缺省的人员谓词集。要编写自定义谓词,您必须:
- 编辑缺省的谓词集 XML 文件并添加新谓词。
- 编辑与您希望使用的人员插件提供程序相关联的缺省 XSLT 文件的副本,通常是 LDAPTransformation.xsl 文件。向此文件添加对您的新人员谓词的支持。
- 向您配置了 Business Process Choreographer 的每个节点部署新 XSLT 文件,包括 WebSphere Application Server Network Deployment 安装的部署管理器。
- 如果尚未完成,则创建与您已调整的 XSLT 文件相关联的自有人员插件配置。
现在,在对人工任务进行建模时可以使用新的人员谓词。请确保您的任务模型与新配置的 JNDI 名称关联。
您可以按照以下示例创建新的人员谓词。在本例中,将创建一个新的谓词,名为“Manager and employee by employee user ID”。此谓词与“Manager of Employee by user ID”谓词很相似,但除了管理员的 ID 之外,它还会返回员工的用户 ID。
编辑缺省的谓词集
-
创建新人员谓词的第一步是将其模板添加到缺省谓词集。在 <WebSphere Integration Developer 安装目录>/wstools/eclipse/plugins/com.ibm.wbit.tel.ui_6.0.2/xml/ 目录中找到 VerbSet.xml 文件。(如果使用其他 WebSphere Integration Developer 版本,则版本部分 (ui_6.0.2) 会有不同。如果可以选择,请使用包含最高版本号的目录。)
-
在文件的末尾添加新谓词定义:
清单 15
<?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='Manager and employee by employee user ID'>
<vs:Description>Assigns employye's manager
<together with the employee,
given the employee 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>
<!-- ... additional hints ... -->
<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>
</vs:VerbSet>
|
此谓词的定义与“Manager of Employee by user ID”谓词相同(从技术角度而言),但其描述指出了在应用参数值方式上的差异。
-
保存该文件后,新谓词已准备好在 Task Editor 中使用,但是在可以部署使用该谓词的任务模板之前,必须确保在您的人员插件配置中支持此谓词。请确保为您的新谓词集文件创建备份。
编辑 XSLT 文件
-
在编辑新版本的 XSLT 文件时,首先必须确保新谓词模板 ManagerAndEmployeeByEmployeeUserID 包含在全局调度程序模板中,并且将被调用:
清单 16
...
<!-- Begin global dispatching -->
<xsl:template match="/staff:verb">
...
<xsl:choose>
<xsl:when test="$verb='Users by user ID'">
<xsl:call-template name="UsersByUserID"/>
</xsl:when>
...
<xsl:when test="$verb='Manager and employee by employee user ID'">
<xsl:call-template name=
<"ManagerAndEmployeeByEmployeeUserID"/>
</xsl:when>
<xsl:otherwise>
<xsl:message >Unknown verb:'<xsl:value-of select="$verb"/>'</xsl:message>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<!-- End global dispatching -->
...
|
-
添加实际 XSLT 模板,可以在文件结尾处添加:
清单 17
...
<!-- Begin template ManagerAndEmployeeByEmployeeUserID-->
<xsl:template name="ManagerAndEmployeeByEmployeeUserID">
<sldap:staffQueries>
<xsl:attribute name="threshold">
<xsl:value-of select="$Threshold"/>
</xsl:attribute>
<sldap:intermediateResult>
<xsl:attribute name="name">manager</xsl:attribute>
<sldap:search>
<xsl:attribute name="filter">
<xsl:value-of
select="$DefaultUserIdAttribute"/>=<xsl:value-of
select="staff:parameter[@id='EmployeeUserID']"/>
</xsl:attribute>
<xsl:attribute name="searchScope">subtreeScope</xsl:attribute>
<xsl:attribute name="recursive">no</xsl:attribute>
<sldap:attribute>
<xsl:attribute name="name">
<xsl:value-of select="$DefaultManagerAttribute"/>
</xsl:attribute>
<xsl:attribute name="objectclass">
<xsl:value-of select="$DefaultPersonClass"/>
</xsl:attribute>
<xsl:attribute name="usage">simple</xsl:attribute>
</sldap:attribute>
</sldap:search>
</sldap:intermediateResult>
<sldap:user>
<xsl:attribute name="dn">%manager%</xsl:attribute>
<xsl:attribute name="attribute">
<xsl:value-of select="$returnAttribute"/>
</xsl:attribute>
<xsl:attribute name="objectclass">
<xsl:value-of select="$DefaultPersonClass"/>
</xsl:attribute>
</sldap:user>
<xsl:call-template name="GetUserByID">
<xsl:with-param name="username">
<xsl:value-of select=
<"staff:parameter[@id='EmployeeUserID']"/>
</xsl:with-param>
</xsl:call-template>
</sldap:staffQueries>
</xsl:template>
<!-- End template ManagerAndEmployeeByEmployeeUserID-->
...
</xsl:transform>
|
新模板与“ManagerOfEmployeeByUserID”模板非常相似。它具有不同的名称,而且额外调用 GetUserByID 模板,该模板确保将员工的用户 ID 添加到查询结果集中。
(对于此谓词,不需要相应的电子邮件谓词。因为它只返回两个用户 ID,相对于电子邮件解析的缺省谓词“Email Address for Users by user ID”,它在性能上没有显著的优势。)
保存更改之后,XSLT 映射文件已做好部署的准备。
部署 XSLT 文件
-
要部署新 XSLT 文件,必须将其安装在配置了 Business Process Choreographer 的每个节点上。对于 Network Deployment 安装,还必须将其安装在部署管理器上。请确保将 XSLT 文件安装到所有节点上的同一相对目录下。
-
还要考虑将其安装到缺省 Human Task Manager XSLT 文件安装所在的同一目录:<WebSphere Process Server 安装目录>/ProcessChoreographer/Staff/。其中,WebSphere Process Server 安装目录还包含 WebSphere bin、java 和 lib 目录。请确保不使用该处已安装的缺省 XSLT 文件的名称。
-
如果尚未完成,则创建自有人员插件配置,并将其与您的已调整和已安装的 XSLT 文件相关联。对于 Network Deployment 环境的情况,在部署管理器上创建配置并使用节点范围。对于托管集群成员的每个节点,重复此步骤。
现在,在对人工任务进行建模时可以使用新人员谓词。请确保您的任务模型与新人员插件配置的 JNDI 名称关联,而不是与缺省的 bpe/staff/userregistryconfiguration 关联。
通过自定义属性、流程变量或输入消息分配员工
在一些业务场景中,可能希望通过覆盖 Human Task Manager 人员解析来动态地分配人员查询结果(也称为员工分配)。在始终希望执行自有人员解析的场景中(例如,由于您希望为自定义人员存储库加入高级查询功能),您将使用人员解析后处理器插件。但是对于只希望为业务流程中的某一人工任务活动动态地提供自有人员解析结果的场景,则可能希望选择下述选项之一。
Human Task Manager 人员解析利用上下文变量能够提供动态和基于实例的人员解析结果,使您可以包含来自输入消息、自定义属性或流程变量的数据。通过使用此功能,可以创建包含希望动态分配的组名称或用户 ID 列表的自定义属性或业务对象 (BO) 消息,并在 Human Task Manager 提供的人员谓词或您的自有自定义谓词中对其进行引用。
下面两个示例演示如何为自定义属性分配组名称、动态地解析组成员,以及动态地提供一组用户 ID,从而完全在 Human Task Manager 人员解析之外执行人员解析。当然,您也可以使用其他上下文变量和人员谓词的组合。
动态地分配组成员
要动态地分配组成员,可以使用人员谓词“Group members”,并使用业务流程自定义属性“myGroup”来填充组名称。
在对内联人工任务进行建模时,请输入值 %wf:property.myGroup% 作为 GroupName 参数的值。
在您的业务流程中创建使用自定义属性的代码片段活动,该活动在人工任务之前执行。使用下列语句设置自定义属性 myGroup:
清单 18
setProcessCustomProperty( "myGroup", "cn=managers,ou=austin,o=mycompany,c=us" );
|
您通常会使用预先初始化的程序变量,而不是赋予静态值 cn=managers,ou=austin,o=mycompany,c=us。(有关代码片段活动的详细信息,请参见 WebSphere Process Server 信息中心。)
(本示例仅适用于内联人工任务。对于独立任务,您将必须使用其输入消息提供来自流程上下文的动态内容。)
动态地分配一组用户 ID
要动态地分配一组用户 ID,可以使用人员谓词“Users by user ID”,并使用上下文变量来填充“UserID”参数,该上下文变量引用包含用户 ID 集的字符串数组的流程变量。
在对内联人工任务进行建模时,请输入值 %wf:variable.PotOwnersVar\\potOwners% 作为 UserID 参数的值。这里假定您已创建了名为“PotOwnersVar”的数据类型化变量,该变量不包含任何部分。它包含解析为字符串数组的消息元素 potOwners,该字符串数组包含用户 ID 集。
图 3 显示如何为人工任务指定上下文变量表达式。
图 3. 指定潜在所有者
图 4 显示如何指定要访问的业务对象数据类型。
图 4. 潜在所有者业务对象
可以在之前的分配或代码片段活动中填充用户 ID 集。
图 5 显示如何在分配活动中指定上下文变量值。
图 5. 分配活动
在您的场景中,很可能会从另一个流程变量中分配用户 ID,而不像本例中那样静态地分配。(本示例仅适用于内联人工任务。对于单独的任务,则必须使用任务输入消息提供来自流程上下文的动态内容。)
对于流程管理任务,也可以分配来自流程输入消息的用户 ID,例如,使用 %wf:variable.\operation1Parameters\reader%,其中,不指定用于访问流程输入消息的变量名称,而且“operation1Parameters”是输入消息部分名称;而“reader”是解析为字符串的消息元素,并包含读取者用户 ID。但是,请注意如果可以通过非安全源提供流程输入消息,则填充来自流程输入消息的授权数据可能导致安全漏洞。
将专有人员存储库与 Human Task Manager 集成
如果要将专有人员存储库与 Human Task Manager 集成,则应为其实现自定义用户注册中心。这会将您的存储库与 WebSphere Application Server 安全相集成,并且通过使用用户注册中心人员解析插件,将通过 WebSphere 用户注册中心组件自动查询您的存储库。图 6 演示了此选项。
图 6. 使用自定义用户注册中心
有关创建和配置自定义用户注册中心的详细信息,请参见 WebSphere Application Server 信息中心。如果使用应用服务器注册和配置您的自定义注册中心,并使用 bpe/staff/userregistryconfiguration 作为您的人工任务的人员插件配置 JNDI 名称,将自动从您的存储库中查询用户和组。
如果希望使用比用户注册中心插件支持的更为复杂的查询,则可以实现人员查询结果后处理器插件(在下一部分),以完全替代原始的人员查询结果,从而执行完整的人员解析。原始人员解析插件成为虚拟部件,仅为后处理器插件准备输入数据。后处理器插件访问您的专有人员存储库并执行完整的人员解析。图 7 显示后处理器插件如何参与人员解析过程。
图 7. 使用后处理器插件进行人员解析
如果希望使用比用户注册中心插件支持的更为复杂的查询,并且将 Human Task Manager 与 WebSphere Portal 结合使用,则也可以实现 WebSphere Member Manager 存储库适配器,并使用 WebSphere Member Manager 人员解析插件进行人员解析,如图 8 所示。
图 8. 使用 WebSphere Member Manager 存储库适配器
WebSphere Member Manager 人员解析插件的压缩包和文档在 WebSphere Portal 中提供。请注意,为 WebSphere Member Manager 实现自定义存储库适配器要求来自您的 WebSphere Portal 销售代表的许可。
对人员查询结果进行后期处理
Human Task Manager 提供的人员解析插件为创建授权规则提供了强大的查询功能。但是对于某些特殊情况,您可能需要修改由人员解析插件提供的结果。例如,为了实现工作负载平衡,可能希望从结果集中删除已拥有高工作负载的用户,或者在整个返回用户集的工作负载都已很高时添加额外的用户。
为了帮助您实现此类工作负载平衡场景,Human Task Manager 提供了 StaffQueryResultPostProcessorPlugin 服务提供程序接口,您可以实现该接口,从而改变由人员解析插件返回的人员查询结果。(如果您希望将自定义人员存储库与 Human Task Manager 集成,并且需要比自定义用户注册中心所能提供的更多的查询功能,则此插件接口也非常有用,但不能使用 WebSphere Member Manager。)
如 本系列文章的第 2 部分所述,在执行 Human Task Manager 人员解析之后调用后处理器插件(也称为员工分配后处理器插件)。插件接口由五个方法组成,所有这些方法都有相似的签名,但是为不同的对象类型所调用:人工任务实例、任务模板、升级实例、升级模板和应用程序组件。由于任务实例的方法是最重要的,我们将介绍基于该方法的编程模型:
清单 19
StaffQueryResult processStaffQueryResult( StaffQueryResult originalStaffQueryResult,
Task task,
int role,
java.util.Map context );
|
该方法接收由人员解析插件执行的人员查询的结果,该插件是预先使用参数 originalStaffQueryResult 运行的。此参数是实现 StaffQueryResult 接口的对象。作为附加的上下文信息,该方法还接收人工任务的 API 对象表示形式,以及为其执行人员解析的授权角色。授权角色(分配原因)int 值的设置是由 com.ibm.task.api.WorkItem 接口定义的。更多的上下文信息(如上下文变量及其值)在上下文 map 中提供。如果您的人员谓词参数包含(举例来说)变量 %wf:process.starter%,那么 map 将包含项“wf:process.starter”和值“jim”,其中“jim”是流程启动者的用户 ID。在此方法中,可以通过调用如下方法来提取 com.ibm.task.spi.UserData 记录的集合:
originalStaffQueryResult.getUserData();
此方法返回 UserData 记录的 java.util.Collection,您可以向其添加记录或从中删除记录。如需添加新的 UserData 记录,则可以使用 com.ibm.task.spi.StaffQueryResultFactory 工厂方法来创建它们:
清单 20
StaffQueryResultFactory factory = StaffQueryResultFactory.newInstance();
factory.newUserData( java.lang.String userID,
java.util.Locale preferredLocale,
java.lang.String eMailAddress );
|
如需做出更大的更改,或者希望完整替换原始的人员查询结果,则可以使用其他工厂方法之一创建新的 com.ibm.task.spi.StaffQueryResult 对象:
清单 21
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);
|
在实现后处理器插件时,请考虑:
- 如果人员解析插件已使用删除查询从结果集中删除了一些用户,则后处理器插件负责确保不会将这些用户之一再次添加到结果集中。否则,可能会违反四眼原则或其他安全策略。上下文 map 提供一组已删除用户 ID,作为项 HTM_REMOVED_USERS 的字符串数组值。
- 通过 EJB 上下文来调用该插件方法。实现 EJB 方法的所有限制也都适用于插件代码。
- 通过任意用户的安全上下文调用该方法,您不能依赖于使用了流程启动者主题的事实,尽管这适用于大多数后处理器插件调用。
- 该方法在公开事务中调用。如果调用其他 Human Task Manager EJB API 方法和查询其他数据,您可能无法看到在运行事务过程中创建的数据,因为它尚未保留。
- 如果您的插件代码调用的 Human Task Manager API 方法导致 Business Process Choreographer 数据库的更新,则可能导致数据库死锁。
当您完成编程时,请组装插件:
- 将插件类及其 Helper 类组装到 JAR 文件中。
- 在您的 JAR 文件的 META-INF/services/ 目录中提供一个插件注册文件。注册机制遵循 Java 2 服务提供程序接口规范。
- 创建名为“com.ibm.task.spi.plug-in_nameStaffQueryResultPostProcessorPlugin 的文件,其中 plug-in_name 是插件的名称,该插件将由 Human Task Manager 调用。
- 文件的第一行既不是注释行也不是空白行,在此指定插件类的完全限定名。
以 Human Task Manager 应用程序(类加载器)可以访问它的方式安装插件 JAR 文件。可以选择如下几种安装方法之一:
- 将您的插件 JAR 文件添加到(任务或流程)应用程序 EAR 文件中。在 WebSphere Integration Developer 的部署描述符编辑器中,安装您的插件的 JAR 文件,作为主 EJB 模块的 J2EE 应用程序的项目实用工具 JAR 文件。这会使该插件恰好可用于此应用程序。
- 将 JAR 文件放在 WebSphere Application Server 共享库中,并将库与 Human Task Manager 企业应用程序相关联。要使 JAR 文件在 Network Deployment 环境中可用,将 JAR 文件手动分发到每个节点上,然后一次为所有单元安装共享库。请注意,此选项要求服务级别 6.0.2.2。
- 在 WebSphere Application Server 的 lib/ext/ 或 java/jre/lib/ext/ 目录中安装 JAR 文件(如果是网络部署环境,则在每个节点上安装)。
可以使用人工任务容器自定义属性 Staff.PostProcessorPlugin 注册您的插件(在 WebSphere Process Server 中,选择 Application servers => server_name => Human task container => Custom properties)。该属性的值是插件名称,正如在上面的 JAR 文件的 META-INF/services/ 目录中指定的名称 (plug-in_name)。请注意,只能为 Human Task Manager 注册单个后处理器插件。
有关如何组装和安装插件的详细信息,请参见 WebSphere Process Server 信息中心。
人员查询结果共享
共享符合条件的人员查询结果可在整体上改进 Human Task Manager 的性能。例如,对于不访问上下文变量的任务模板,其某个授权角色的所有人员查询结果为该模板的所有任务实例共享。这表示此模板的人员解析只发生一次(按授权角色),并且此模板的所有实例都使用相同的结果。即使访问了上下文变量,基于相同上下文变量值集的结果仍然共享。由于后处理器对于模板的每个任务实例可能返回不同的结果,其人员查询结果不适合共享。因此,后处理人员查询结果缺省为禁用共享。
如果使用后处理器插件执行完整的人员解析(而不是负载平衡,举例来说),并且对于每个任务实例,您不希望返回不同的结果,则也可以为后处理器结果启用共享。这会导致较少调用后处理器插件。您可以使用 Human Task Container 自定义属性 Staff.PostProcessorPlugin.EnableResultSharing 启用共享。请注意,您需要安装 Interim Fix IZ07326 或至少 6.0.2.3 的服务级别才能获得对此属性的支持。
要配置此属性,请使用 WebSphere 管理控制台。如果您在服务器上配置了 Business Process Choreographer,请转到 Servers => Application servers => serverName => Human task container settings => Human task container => Custom Properties。如果您在集群上配置了 Business Process Choreographer,请转到 Servers => Clusters => clusterName => Human task container settings => Human task container => Custom Properties。更改 Staff.PostProcessorPlugin.EnableResultSharing 自定义属性的值,从其缺省值“false”更改为“true”。保存您的更改,然后重新启动受影响的应用服务器。在部署人工任务或业务流程之前,必须更改此属性的值。无论在部署环境还是生产环境,在部署或使用人工任务或业务流程模块模板之后,您都不能更改此属性的值。(在生产中更改此属性的值会在人员查询结果刷新过程中导致不可预期的结果。)
同样,将此属性设置为 true 时,调用后处理器插件的方式会有不同,因为它现在的行为与人员解析插件类似。方法参数 task、escalation、template(升级或任务模板)和 applicationComponent 的值为空。参数 role 的值为 com.ibm.task.api.WorkItem.REASON_NONE (-1)。在人员查询结果刷新过程中,还要调用方法:
清单 22
StaffQueryResult processStaffQueryResult(StaffQueryResult originalStaffQueryResult,
Task task,
int role,
java.util.Map context)
|
以刷新升级、任务和升级模板的结果,以及应用程序组件。在人员查询结果刷新过程中,不会调用其他方法。
结束语
Human Task Manager 为业务流程和面向服务的体系结构所涉及的人员提供了功能强大的、基于实例和业务上下文的授权。Human Task Manager 执行基于灵活授权规则(称为人员谓词)的人员解析查询。
本文介绍如何自定义 Human Task Manager 人员解析以更好地符合您的需求,方法是探索如何调整现有人员谓词,如何创建附加谓词,以及如何访问人员解析的业务上下文。还介绍了如何将专有人员存储库与 Human Task Manager 集成,并为您的业务流程所涉及的人员执行工作负载均衡。
本系列的其他文章
致谢
非常感谢我的同事 Thomas Bernhardt、Gabriel Dermler,特别是 Hans Schoen 在准备本文的过程中提供的帮助。
参考资料
关于作者  | 
|  |
Kurt Lind 曾在德国曼海姆的应用科技大学就读通信工程专业。作为 WebSphere Process Server 团队的一名成员,他负责 Human Task Manager 和业务流程编排安全体系结构的工作。 |
对本文的评价
|