内容


在 WebSphere Integration Developer V7 中使用 Quality of Service 限定符,第 1 部分

在您的业务应用程序中管理事务和安全性

Comments

简介

IT 领域的企业非常复杂,因为各种系统需要各种不同的操作。要实现系统之间的无缝集成,业务应用程序的帮助是很重要的。

WebSphere Integration Developer(以下简称 Integration Developer)是一个创作工具(authoring tool )可以帮助您根据需求组成复杂的业务应用程序。它提供一种简单的方法来实现关键功能和非功能性需求,不需要编程,也不需要使用限定符 对服务实现代码进行修改。限定符是 Quality of Service (QoS) 规范 ,定义了一个应用程序所需要的一些通信特性,包括传输优先级、路经可靠性等级、事务管理以及安全级别等方面。

限定符定义了在运行时必须为一个组件提供多少管理。它们传播事务、管理质量和消息传递定时。您可以使用限定符来扩展组件的服务质量,有助于定位错误处理和负载以及执行业务服务需求。

这个两部分系列文章将讨论所有 Integration Developer 提供的限定符,本系列文章中我们选择 Developer V7.0,是因为这是最新版本,且支持 13 种不同类型的限定符。本系列的第 1 部分关注其中 6 种,涉及事务处理、安全性和数据验证,它将为每个限定符提供说明,实用价值和可能场景,来帮助您决定在您的业务应用程序中要使用哪一个。

理解限定符

Quality of Service 限定符是在 Integration Developer 的装配编辑器(assembly editor )中定义的,可以进行如下设置:

  • Interfaces:指定了目标服务提供的限定符,相当于服务和客户端之间的一个合同。
  • References:指定了异步调用的可靠性,以及一个目标组件的方法是否应该被组合成客户端事务的一部分。
  • Implementations:这些用于识别服务的权限,并向业务环境传达其需求。

以下是 Integration Developer V7.0 提供的所有限定符的列表,本文介绍前 6 个:

  1. 事务限定符
  2. 联接事务限定符
  3. 安全身份限定符
  4. 安全许可限定符
  5. 中止事务限定符
  6. 数据验证限定符
  7. 活动会话限定符
  8. 异步调用限定符
  9. 异步可靠性限定符
  10. 事件排序限定符
  11. 联接活动会话限定符
  12. 存储和转送限定符
  13. 中止活动会话限定符

默认情况下,Integration Developer 生成一些限定符来提供事务处理和可信任异步消息传递。您可以根据您的需求在装配图中编辑这些预设值。要查看和编辑模块中使用的限定符:

  1. 在画布空白区单击右键,选择 Show In > Properties View
  2. 单击 All Qualifiers 选项卡,显示模块中定义的所有限定符,如图 1 所示。
    图 1. 查看限定符设置
    查看限定符设置
    查看限定符设置

事务限定符

事务是一个活动单元,其中数据的多个操作可以被原子化(不可分),精确地说就是所有的活动都是永久的,或者没有一个活动永久的。事务限定符 用来定义一个逻辑界限或者工作单元,即,要不在此界限中的所有组件的更改作为一个整体全部被提交,要不有一个失败则整体全部回滚。当一组操作彼此独立时,可以使用事务限定符,规定所有全部成功,或者即使只有一个失败也全部回滚。

应用之处: 实现

可应用值:如图 2 所示,事务限定符 可有如下设置,具体根据业务应用程序的设计:

  • Global:全局事务是分布式事务处理环境中的一个工作单元,其中有多个资源管理程序。在一个全局事务中需要注意的是:
    1. 如果一个客户端传播一个事务,且组件被配置来加入该事务,那么这个组件将在同一个事务下运行。换句话说,当客户端提交事务时组件更新的资源同时被提交。
    2. 如果这些条件少一个,组件将在一个新全局事务下运行,在操作完成后提交。
  • Local(默认):当组件实现不能够遵循一个两阶段提交协议时,需要这一设置。在本地事务中需要注意的是:
    1. 如果客户端传播事务,且事务限定符被设置为本地的,那么组件将在一个本地事务下运行,因为在某个特定场景中,在本地事务下运行业务逻辑比在全局事务下运行表现更好。
    2. 本地事务不会传播到组件调用的服务。
    3. 如果一个活动会话是活动的,本地事务加入其中。如果一个活动会话目前不是活动的,那么将自动开始。
  • Any:如果一个本地事务上下文是从客户端传播的,那么在全局事务中运行时环境将从组件分派方法。负责运行时环境将建立在一个本地事务环境中。
  • Local application:在应用程序负责管理事务的场景中使用这个限定符。对于企业级 Java™ bean 来说,选中该选项相当于将事务描述符设置为 Not Supported,将 LocalTranResolver 设置为 application
图 2. 事务限定符可能的值
事务限定符可能的值
事务限定符可能的值

场景

考虑这样一个案例,您有一个 SCA 组件,提供一个重要的操作,由于业务需要必须要作为一个全局事务的一部分。在此例中,在这个组件的实现上将事务限定符设置为 “local”。在某些情况下,如果在本地环境下执行操作更好的话,您也可以将事务限定符设置为 “local”。组件的行为取决于针对事务的设置合并和如下所述的联接事务:

  • 如果 caller 事务限定符被设置为 “global”,called one 界面加入事务,调用的那个在同一个全局事务下执行。
  • 如果 called one 限定符被设置为 “local”,那么 called one 是在一个本地事务下执行。在这样的场景中,联接事务 不能在 called one 界面上设置为 “ture”。
  • 如果联接事务 限定符在 called one 上设置为 “false”,而且事务限定符被设置为 “global”,一个新的全局事务启动。
  • 如果在 called one事务限定符 设置为 “local”,那么事务不能传播到它调用的服务。

联接事务限定符

此限定符决定是否目标服务能够加入一个客户端传播(client-propagated)事务。因为事务只在异步调用期间传播,联接事务 限定符只有当客户端同步调用一个服务时方可应用。

应用之处:您可以在一个组件或者导入的 3 个阶段应用该限定符:

  • 所有界面
  • 一个单独界面
  • 一个界面的所有单独操作

可应用值:您可以将联接事务 限定符设置为 “true” 或者 “false”,具体根据业务需要,如果设置为:

  • True:如果该组件正好运行在一个全局事务下,那么它联接一个由其调用方传播的事务。
  • False:组件不能联接一个它的调用方传播的事务。

场景

考虑这样一个企业,使用一个 ERP 系统来维护 HR 相关信息(HR Services),使用另一个 ERP 来维护薪金相关的信息(Payroll Services)。在这个场景中,业务流将创建一个员工记录,这要在 HR 系统创建一个记录,还要在 Payroll 系统中创建一个记录。如果应用程序成功的话,肯定在这两个系统中都创建了记录,如清单 3 所示。

这两个模块都有 Java 实现,已经被编码来分别在 HR 和 Payroll 系统下创建记录。从理论上说,在连接此类企业应用程序时,您可以使用各自的适配器。Java 方法仅作为示范用。

图 3. 联接事务场景装配图
联接事务场景装配图
联接事务场景装配图

基于上述使用案例,很显然一个记录需要在两个系统中创建,只有两个操作都成功 才算成功。这给我们带来了一种事务概念,通过参与行动进行的更改要么全部被永久化,要么一个都不。换句话说,我们知道,如果两个操作中的一个失败,整个事务需要回滚。因此这两个操作都需要加入一个 “事务”。

为了达到这个目的,在 HR 和 Payroll 模块上使用 “联接事务” 限定符。将值设置为 “ture”,您就可以确保两个部件加入了一个 CreateEmploye 模块传播的全局事务,如图 7 所示。考虑这样一种情况,HR 模块成功而 Payroll 模块失败(可能是由于数据不充足、数据错误、网络问题等等)。HR 事务进行的更改也需要回滚。

图 4. 在界面上设置联接事务限定符
在界面上设置联接事务限定符
在界面上设置联接事务限定符

注意:“联接事务” 限定符也需要在实现时将事务限定符设置为 “global” 或 “any” 作为前提。如果事务被设置为 “local”,将出现错误(CWSCA8018E: The joinTransaction qualifier defined on the interface and the transaction qualifier on the implementation do not match),因为这两个设置是不兼容的。换句话说,对于一个组件来说联接一个恰好是本地的这务,这是不可能的。

中止事务限定符

这个限定符决定使用在同步调用期间调用者或者客户端将其事务传播到目标组件。这个限定符仅在全局事务中有效,如果在本地事务中或者调用是异步的,它则被忽略。当一个调用者想控制一个事务时,可以使用中止事务 限定符。如果调用方想要提交更改时,即使调用组件失败,也将其值设置为 “true”。

应用之处:引用

可应用值:您可以将中止事务限定符 设置为 “true” 或 “false”,具体取决于业务需求,如果设置为:

  • True:同步调用发生在客户端或者调用方的全局事务之外。目标组件的事务环境不受这个限定符的影响。
  • False:异步调用全部运行在客户端或者调用方全局事务之中。

场景

看这样一个企业应用场景,有两个模块来从 HR 和 Payroll 核心系统创建并检索员工信息,如图 5 所示。在这里,CreateEmployee 模块要求 HR 和 Payroll 模块加入前面所述的事务中。据说,即使两个操作只成功一个,RetrieveEmployee 模块都将完成。

图 5. 中止事务场景装配图
中止事务场景装配图
中止事务场景装配图

为了实现上述场景,我们需要在 CreateEmployee 模块上使用以下限制符设置,如图 6 所示:

  • 在 HRServices 引用中设置 Suspend Transaction = false
  • 在 PayrollService 引用中设置 Suspend Transaction = false
图 6. 在 CreateEmployee 模块的引用中设置中止事务限定符
在 CreateEmployee 模块的引用中设置中止事务限定符
在 CreateEmployee 模块的引用中设置中止事务限定符

在 RetrieveEmployee 模块中进行设置,如图 7 所示。

  • 在 HRServices 引用中设置 Suspend Transaction = true
  • 在 PayrollService 引用中设置 Suspend Transaction = true
图 7. 在 RetrieveEmployee 模块引用中设置中止事务限定符
在 RetrieveEmployee 模块引用中设置中止事务限定符
在 RetrieveEmployee 模块引用中设置中止事务限定符

注意:联接限定符在 HR 和 Payroll Service 模式下仍然设为 ture,RetrieveEmployee 所需的功能通过在 HR 和 Payroll 服务界面上设置 join transaction = false 可以实现。然而,这同 CreateEmployee 模块需求会发生冲突。因此,当客户端需要控制一个事务时,使用中止事务限定符,当服务提供商要控制时,可以使用联接事务限定符。

事务突出显示

装配编辑器突出显示事务被传播的地方。在装配图编辑器画布的空白区域单击右键,选择 Show Transaction Highlighting。显示所有和数据相关的事务,如图 8 所示。

  • 如果一个元素没有被突出显示,那么它不能联接或者传播一个事务。
  • 一个元素周围的粗绿线以及沿途线路表示元素加入事务,且线路在传播事务。
  • 绿色折线表示,一个事务可能被联接或传播,但是系统不能确认是否会发生。一个 Java 组件应用有一条虚线指向目标服务,因为系统不能确认 Java 组件是进行同步还是异步出站调用。
  • 组件周围的虚线表示组件至少加入一个事务,但是它可以加入多个事务。
    图 8. 事务突出显示
     事务突出显示
    事务突出显示

安全许可限定符

使用安全许可 限定符来限制一个用户或者组的指定集合的访问界面中的操作。

如果安全许可限定符是指定的,调用方的身份必须有指定角色来获得调用接口或操作许可。如果没有指定安全许可,则没有许可检查,所有调用方都允许调用接口和操作。

应用之处:您可以在 3 个不同级别的组件或导入上应用限定符:

  • 所有界面
  • 一个单独界面
  • 一个界面的单独操作

场景

我们来看一下这个场景,Payroll Service 需要加密,因此只有授权用户可以访问。因此,该服务只有那些有身份识别和授权的用户调用者可以访问。要整体定义操作的安全限制或界面,可是使用安全许可限定符。

如图 9 所示,通过定义一个 “Payroll Auth” 角色,我们已经在整个薪金服务上定义了安全许可限定符。这意味着只有这些调用者 - Payroll Auth 角色的一部分 - 才被允许访问服务,其他的将被拒绝。

图 9. 在 PayrollService 界面上设置安全许可限定符
在 PayrollService 界面上设置安全许可限定符
在 PayrollService 界面上设置安全许可限定符

通过在应用程序中使用 Security role to user/group mapping ,可以向这个角色添加用户:

  1. 一旦应用程序被部署,转到管理控制台中 Enterprise Applications 之下的特殊应用程序。
  2. 单击您的应用程序名,然后单击 Security role to user/ group mapping
  3. 选择一个角色,命名为 Payroll Auth,然后单击 Map users 为添加组添加特殊用户或者 Map groups

在我们的场景中,我们添加了一个特殊用户,如图 10 所示名为 payrolladmin。您也可以添加更多用户,取决于您的需求。这意味着只要是 Payroll Auth 角色,现在都可以成功地调用这些服务。

图 10. Security role to user/ group mapping
Security role to user/ group mapping
Security role to user/ group mapping

安全身份限定符

安全身份 限定符指定,以实现的身份在运行时通过提供一个逻辑角色名执行。

如果限定符不能指定,那么实现以其调用者的身份执行,如果没有调用者身份,则以托管容器的身份执行。角色与身份相关联,角色指定实现是否被授权调用其他组件。

应用之处:实现

场景

我们看一下之前使用的案例,其中 Payroll 服务是安全的,只有允许 Payroll Auth 角色用户访问。对于 CreateEmployee 组件,要访问 Payroll 服务,需要以一个 Payroll 服务定义的 “Payroll Auth” 角色的用户来访问它。为了定义这类身份用户,我们可以使用安全身份限定符。

如图 11 所示,我们已经在 CreateEmployee 组件上通过一个名为 “Payroll access” 角色的身份定义了 “安全身份”。这意味着 CreateEmployee 模块将以一个定义为 “Payroll access” 角色的特殊用户的身份运行。

图 11. 在 CreateEmployee 实现中设置安全身份限定符
在 CreateEmployee 实现中设置安全身份限定符
在 CreateEmployee 实现中设置安全身份限定符

类似于之前的案例,我们需要在 Admin Console 中再一次设置 security role to user/ group mapping

  1. 导航到 Administrative Console 中 Enterprise Applications 之下的这个应用程序。单击应用程序名,然后单击 Security role to user/ group mapping
  2. 选择角色,即 Payroll access,然后单击 Look up users。向这个角色分配一个用户,如图 12 所示。

要显示一个负面案例,可以向 Payroll 访问中添加一个名为 “noauth” 的用户。再一次,该角色被映射到多个用户或者一组用户。

图 12. 向用户或者组映射添加错误用户
 向用户或者组映射添加错误用户
向用户或者组映射添加错误用户

此外,在 Admin Console 中这个限定符也授权 User RunAs roles 的建立:

  1. 为了完成这一活动,打开服务器的 Administrative Console,导航到 Enterprise Applications
  2. 单击您的应用程序名,然后单击 User RunAs roles
  3. 提供您想要向角色中添加的用户的 usernamepassword。选择靠近 Payroll access 的复选框,然后单击 OK。如图 13 所示新用户被添加到所需的角色中。
    图 13. 设置 User RunAs 角色
    设置 User RunAs 角色
    设置 User RunAs 角色

依据上述配置,Create Employee 组件将以 “noauth” 身份执行。

执行应用程序

因为 “noauth” 用户不是 “Payroll Auth” 角色(Payroll Service 定义的)的一部分,服务访问失败,出现清单 1 所示错误。

清单 1. 安全身份限定符错误
Caused by: com.ibm.websphere.sca.ServiceRuntimeException: Fail to invoke 
 [CreateEmployeeImpl.public commonj.sdo.DataObject CreateEmployeeImpl.createEmployee
 (commonj.sdo.DataObject)] for component [{Article}CreateEmployee]: caused by: 
 com.ibm.websphere.sca.ServiceRuntimeException: Permission denied: User noauth 
 is not in role:Payroll Auth and does not have permission to invoke the method
	at com.ibm.ws.sca.internal.java.handler.JavaImplementationHandler.invokeSync
     (JavaImplementationHandler.java:473)
	at com.ibm.ws.sca.internal.java.handler.JavaImplementationHandler.processMessage
     (JavaImplementationHandler.java:195)
	at com.ibm.ws.sca.internal.message.impl.MessageDispatcherImpl.
     processMessageWithPCI(MessageDispatcherImpl.java:753)

因为在用户指定的角色中有一个匹配错误,不可能执行应用程序。解决方案是确保指定的用户以 RunAs 角色匹配所需服务的安全规范。

在我们的场景中,向 “Payroll access” 角色添加 “payrolladmin” ,图 14 显示以安全角色向用户或者组的新映射。图 15 显示了现在包含 payrolladmin 的 User RunAs 角色。

图 14. 映射 payrolladmin 到 Payroll 访问角色
 映射 payrolladmin 到 Payroll 访问角色
映射 payrolladmin 到 Payroll 访问角色
图 15. 添加 payrolladmin 到 User RunAs 角色
添加 payrolladmin 到 User RunAs 角色
添加 payrolladmin 到 User RunAs 角色

此外,如果您没有完成建立 RunA 数据的步骤,将会在运行时出现清单 2 所示的错误。

清单 2. 向一个空 RunAs 角色设置抛出异常
com.ibm.ws.sca.uow.UOWRolledBackException: caused by: com.ibm.websphere.sca.
 ServiceRuntimeException: The run-as authentication data is not configured 
 for role Payroll access
	at com.ibm.wsspi.sca.ejb.module.impl.ModuleSessionBean.processUOWMessage
     (ModuleSessionBean.java:348)
	at com.ibm.wsspi.sca.ejb.module.impl.ModuleSessionBean.
     transactionRequiredActivitySessionNotSupported(ModuleSessionBean.java:315)
	at com.ibm.wsspi.sca.ejb.module.EJSLocalStatelessModule_43132892.
     transactionRequiredActivitySessionNotSupported(EJSLocalStatelessModule_
     43132892.java:233)
	at com.ibm.ws.sca.internal.uow.handler.UOWStrategyImpl.
     transactionGlobalActivitySessionFalse(UOWStrategyImpl.java:311)
	at com.ibm.ws.sca.internal.uow.handler.JoinUOWHandler.processMessage
     (JoinUOWHandler.java:165)
	at com.ibm.ws.sca.internal.message.impl.MessageDispatcherImpl.processMessage
     WithPCI(MessageDispatcherImpl.java:726)
	at com.ibm.ws.sca.internal.message.impl.MessageDispatcherImpl.processMessage
     (MessageDispatcherImpl.java:1167)
	at com.ibm.ws.sca.internal.message.impl.ManagedMessageImpl.process
     ManagedMessageImpl.java:834)
	at com.ibm.wsspi.sca.ejb.module.impl.ModuleSessionBean.processMessage 
     (ModuleSessionBean.java:153)
	at com.ibm.wsspi.sca.ejb.module.EJSLocalStatelessModule_43132892.
     processMessage(EJSLocalStatelessModule_43132892.java:97)
	at com.ibm.wbit.comptest.controller.invocation.impl.AdhocInvoker.
     processMessage(AdhocInvoker.java:72)
	at com.ibm.wbit.comptest.controller.invocation.impl.Invoker.
     managedInvoke(Invoker.java:284)
	at com.ibm.wbit.comptest.controller.invocation.impl.Invoker.
     invoke(Invoker.java:175)

因此,从上述两个场景,我们可以理解,服务提供商想要限制访问,可以使用安全许可限定符,而客户端可以使用安全身份限定符来作为一个特定角色运行。

注意:服务提供商和客户也可以跨两个不同的模块或系统 。

数据验证限定符

数据验证限定符 确保传递到操作的数据和操作输入的 XSD 类型匹配。您可以使用它从一个业务对象验证实例数据。

应用之处:您可以在 3 个不同级别的组件或导入上应用该限定符:

  • 所有界面
  • 一个单独界面
  • 一个界面的单独操作

可应用值:您可以为数据验证限定符设置为以下值,取决于您的应用程序的设计和需求:

  • Log error and continue(默认):如果突然出现一个错误,记录错误并执行请求的操作。这不能保证服务可以处理无效数据,因此将出现一个运行时错误。
  • Throw exception:如果突然出现一个错误,抛出一个异常,操作不能执行。

场景

考虑到一个组件负责检索一个订单的详细信息,给定 Order ID 作为输入。这很可能也有订单 ID 元素模式的一些限制,有些应用程序定义约束条件,比如元素的最大长度、样式细节、拒绝字母表,等等。在这种情况下,传递一个 Order ID,这不符合标准,将会生成一个运行时错误。在此您可以通过使用数据验证限定符进行初步检查。

如图 16 所示,“RetrieveOrderDetails” BPEL 组件接受 Order 业务对象作为一个输入,并从一个外部系统获取订单详情。它也执行一些额外任务,比如记录和存储细节以为将来使用。OrderBO 是一个业务对象,其中包含 OrderID、Description 和一个 Items 清单。

图 16. RetrieveOrderDetails BPEL 和 OrderBO
RetrieveOrderDetails BPEL 和 OrderBO
RetrieveOrderDetails BPEL 和 OrderBO

对于上述条件,您可以在接口上设置数据验证限定符,如图 17 所示。您将该值设置为 “Throw exception”,因为这是一个严重错误,将来处理是没有意义的,不需要详细订单。验证基本上是违背业务对象定义的,作为一个参数为这个接口提供的。

图 17. 数据验证限定符
数据验证限定
数据验证限定

在这个例子中,在 OrderBO 中有一个关于 “OrderId” 最大长度限制集合,如清单 18 所示。其他一些限制条件也可以进行设置,比如容许值、最大长度、模式等等。

图 18. 设置 OrderID 元素的最大值
设置 OrderID 元素的最大值
设置 OrderID 元素的最大值

如果向 Order 界面的输入违反了事务对象建立规则,将出现一个异常,这个进程的异常将阻碍之前的限定符设置,并记录异常详情。考虑到传递的 OrderID 长度远大于 10 个字符,在这种情况下,将出现如清单 3 所示的异常。

清单 3. 数据验证限定符抛出的异常
[3/2/10 14:44:16:765 IST] 00000054 Core          E   CWSCA2001E: 
 The SCA message-driven bean returned the following exception: 
 "com.ibm.websphere.sca.ServiceRuntimeException: com.ibm.ws.bo.handler.
 BOInstanceValidationException: wsdl:http://DataValidation_Interface/
 OrderInterface:processOrder_._type validation returned the following errors:
Property: OrderID has error: CWLBN1010E: The value '78458475874' with 
 length 11 may have at most length 5/n: caused by: com.ibm.ws.bo.handler.
 BOInstanceValidationException: wsdl:http://DataValidation_Interface/
 OrderInterface:processOrder_._type validation returned the following errors:
Property: OrderID has error: CWLBN1010E: The value '78458475874' with length 
 11 may have at most length 5/n".

注意:此限制符的使用将会加大性能开销。因此,尽量避免过度使用该限定符。当给定的业务对象用于大量组件时,该限定符很有用。在这种情况下,与其在每个组件中包含代码片段来检查,还不如强制实行一个全局标准更为容易。

结束语

本文展示如何使用 QoS 限定符来提供事务处理、安全处理和数据验证,以及何时使用。讨论了几个样例场景,其中这些限定符对一个业务应用程序的性能和功能都有帮助。当您对这些限定符的功能和优势有一个清楚明确的理解之后,它们将能够极大地帮助您设计复杂的业务应用程序。

本系列的第 2 部分将介绍活动会话、可靠性和事件排序限定符,以及一些样例场景。


相关主题


评论

添加或订阅评论,请先登录注册

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=10
Zone=WebSphere
ArticleID=620215
ArticleTitle=在 WebSphere Integration Developer V7 中使用 Quality of Service 限定符,第 1 部分
publish-date=01312011