级别: 初级 Andy Brodie (AJBRODIE@uk.ibm.com), Solution Development Standards, SWG System House, IBM Amanda Watkinson (amanda.watkinson@uk.ibm.com), Software Engineer, IBM
2005 年 6 月 01 日 公共事件基础架构(Common Event Infrastructure)是作为 IBM WebSphere Business Integration Server Foundation V5.1 中的技术预览发布的,为开发者提供了创建和管理业务及系统事件的功能。随着 V5.1.1 中可用(production-ready)版本的发布,您可以使用公共事件基础架构在系统间关联和整合信息。
引言
随着 IBM® WebSphere® Business Integration Server Foundation V5.1.1 的发布,使公共事件基础架构 (以下称为 CEI) 得到充分的利用。 V5.1 的技术预览版让开发者看到了 CEI 在创建、管理和分布事件信息方面的潜力。
本文概述了公共事件基础架构从技术预览版到产品发布版的变更和新增的功能。同时,概括了新的特性,并说明了以前使用过技术预览的开发者需要注意的变更。
已经使用过技术预览版,并希望获取产品发布版的变更和新特性信息的开发者会发现本文非常有用。本文也让期望使用公共事件基础架构的人对其有大致的了解。
图 1. 公共事件基础架构概览
在 J2EE 和 J2SE 环境下运行的应用程序作为事件源创建事件,并将其发送到 CEI 服务器。当发生重要的业务或系统事件时,应用程序创建 公共基础事件(Common Base Event,以下称为 CBE) 以包含描述事件细节的数据。通过使用同步或异步事件发射器(emitter),将 CBE 发送到 CEI 服务器。CEI 服务器可能会持久保留和/或将这些事件分布到已注册的监听器。产品发布版增加了以下内容:
- 用来存储事件定义的 Event Catalog 组件。
- Event Access 组件,通过使用定义查询的 XPath 语言的子集来从 CEI 检索事件。
- ECSEmitter,能在 Application Server 环境中使用,以创建、关联和发送事件。
本文余下部分描述 CEI 的技术预览版与 5.1.1 版本中的产品发布版之间的差异和改进。
在 WebSphere Application Server 环境使用 CEI
CEI 的产品发布版增加了一个新的包,com.ibm.websphere.cem (以下称为 Common Event Model),它将事件的创建、关联和发射功能包含到单个类 com.ibm.websphere.cem.ECSEmitter 中。
在技术预览版中,CBE 实例通过使用 EventFactory 来创建,这没有改变,除非这个类已经移到 org.eclipse.hyades.logging.events.cbe.EventFactory。在技术预览版中,两个事件工厂被绑定到 WebSphere JNDI 命名空间:一个通用工厂和一个特定于 WebSphere 的工厂。
通用事件工厂不变。以下的代码例子描述如何获得通用事件工厂及创建 CBE 实例:
import org.eclipse.hyades.logging.events.cbe.*
EventFactory eventFactory = (EventFactory)
javax.rmi.PortableRemoteObject.narrow(
initialContext.lookup("com/ibm/events/EventFactory"),
EventFactory.class);
CommonBaseEvent cbe = eventFactory.createCommonBaseEvent();
|
在 Application Server 中运行的应用程序建议使用 ECSEmitte 来替代。以下的代码例子展示如何用这种方法创建 CBE 实例。
import com.ibm.websphere.cem.ECSEmitter;
import org.eclipse.hyades.logging.events.cbe.CommonBaseEvent;
ECSEmitter emitter = new ECSEmitter("com/ibm/events/emitter/Default", null);
CommonBaseEvent cbe = emitter.createCommonBaseEvent("eventName");
|
传递参数来创建 ECS 发射器将会在以下名为 Emitting Events 的部分讲解。
通用基础事件
技术预览版的事件实例会通过 com.ibm.events.cbe 包中的类来建模。例如,顶级 CBE 类名为 com.ibm.events.cbe.CommonBaseEvent。因为在 Eclipse Tools Hyades Project 中使用 CBE 类,这些类的位置在产品发布版中发生了改变。这些类如今在 org.eclipse.hyades.logging.events.cbe 包中能找到。使用过技术预览版的开发者,如果希望重新使用这些代码必须要修改包的导入语句:
import org.eclipse.hyades.logging.events.cbe.*;
CommonBaseEvent event = ...;
|
这些 Hyades 包中的类、方法和属性事实上是完全相同的,只是在写 XML 序列化代码的时候有微小的改动。要获取 CBE 规范和 Hyades 项目的更多信息,请参阅本文末尾部分的 参考资料。
填充事件
手工添加数据到事件的方法没有改变。但是,创建业务上下文数据及通过 Application Server 将其自动添加到事件的方式就不同了。
在技术预览版中,业务上下文数据服务(Business Context Data Service,BCDS) 使用户能够定义一系列的上下文,每个都包含和上下文相关的名值对(name-value pairs)。通过事件实例上特定于 WebSphere 的内容处理程序,将上下文数据插入到事件中。内容处理程序可以由用户调用事件实例的 complete() 方法来调用,或者是在发射器调用 complete() 方法时的发射点处调用。
例如,使用 BPEL 业务流程(该流程用于获取用户详细信息)的业务,通过网站定义业务上下文实例来"完成用户详细信息",并且插入上下文相关的名值对,这些名值对被复制到该流程中发射的每个 CBE 中。
在产品发布版中,用于事件关联的 BCDS 功能被集成到新的 ECSEmitter 类。ECSEmitter 引入了 Event Correlation Sphere (以下称 ECS) 的概念。 ECSEmitter 提供了设置当前和父关联 sphere ID 的方法。
Event correlation sphere 是一个字符串识别器,可以用来关联属于特定业务流程或上下文的事件。ECSEmitter 发送的事件可以包含两个 correlation sphere 识别器; 一个当前 sphere 和一个父 sphere。
ECSEmitter 提供以下方法来获取和设置这些 ID: getParentEcsId(), getCurrentEcsID(), setCurrentEcsID(String currentID), setParentEcsID(String parentID)。当前 ECS ID 也可以在构建 ECSEmitter 实例的过程中设置。
在当前相关性 ID 被设置时,之前的当前 ID 覆盖父 ID。如果 sphere ID 已设置,它们就会在上下文数据元素中 ECSEmitter 的 sendEvent(...) 方法执行期间被插入到事件,如下面所示:
<contextDataElements name="ECSCurrentID" type="ECSID">
<contextValue>current ECS ID</contextValue>
</contextDataElements>
<contextDataElements name="ECSParentID" type="ECSID">
<contextValue>parent ECS ID</contextValue>
</contextDataElements>
|
为了易于发送包含扩展数据元素的报告事件,ECSEmitter 也提供了addUserDataEvent(java.util.Properties)方法。这个方法通过将属性设置为 CBE 中的扩展数据元素,向 CEI 服务器发送事件。以下的图 2 展示了在使用这个方法时,事件中设置的其它数据。
表 1. 使用 ECSEmitter.addUserDataEvent(...) 方法时添加的事件数据。
|
Event Type
|
ECS:UserDataEvent
| |
Source Component.SubComponent
| J2EE_Application |
Situation:- Name
Reasoning Scope
| ReportSituation
External
| |
Report Category
| Status |
下面的代码段展示如何使用 addUserDataEvent(Properties) 方法。
Properties properties = new Properties();
properties.addProperty("MyPropertyNameA", "MyPropertyValueA");
properties.addProperty("MyPropertyNameB", "MyPropertyValueB");
emitter.addUserDataEvent(properties);
|
这段代码无需先创建 CBE 就可以将事件发送到 CEI 服务器。
发射事件
在填充 CBE 实例时,事件源使用发射器实例: com.ibm.events.emitter.Emitter的一种方法sendEvent(...) 向 CEI 发送事件。
技术预览版事件只支持通过 EJB 接口同步的向事件服务器发送事件。产品发布版本增加了通过 JMS 异步发送事件的功能。就是说,例如,允许事件源在发射事件后继续处理,而不是禁止发射直到事件成功传送并被事件服务器中处理完成。管理员为每个发射器配置同步模式以适应它们自身的应用程序要求。
图 2. 发射器传输模式
除了 EventBusTransmissionProfile 可实现同步传输外,现在还有 JMSTransmissionProfile ,它包含发射器所使用的 JMS 队列和队列连接工厂(Queue Connection Factory)的 JNDI 名称。如果需要异步传输,当然应用服务器必须配置适当的 JMS 队列和队列连接工厂。另外,CEI 服务器必须能够监听出现在指定 JMS 队列中的事件。名为event-message.jacl 的 JACL 脚本位于/event/application/,它可以用来创建发射器,以及异步发送事件时需要的所有适当的资源。
在 Application Server 环境中, ECSEmitter 不需要从 JNDI 查找 CEI Emitter。ECSEmitter 类在下面的图 3 中说明,并定义了构造函数:
ECSEmitter(String emitterJNDIName, String ecsId) |
ECSEmitter 通过使用构造函数中传入的 JNDI 名称,从 JNDI 获取 EmitterFactory 。它能创建 CBE 并提供将其发送到 CEI 服务器之前填充数据的方法。
图 3 ECSEmitter
下面的代码段展示如何创建 ECSEmitter 实例:
import com.ibm.websphere.cem.ECSEmitter;
ECSEmitter emitter = new ECSEmitter(
"com/ibm/events/emitter/Default",
"mySphereID");
|
如果您不想让事件源设置当前相关性的 sphere ID,您应该将第二个参数设置为空。要获取更多构造 ECSEmitter 的信息,请参阅 Infocenter 和 API 文档。
事件过滤
产品发布版使管理员能配置发射器来过滤事件,就是说,在发射器中丢弃事件,这样这些事件就不能发送到事件服务器。需要创建 Filter Factory Profile ,并以类似于 XPath 的方式配置,它用来决定 CBE 是否应该被发送到 CEI 服务器。例如,设置过滤器表达式为 CommonBaseEvent[@severity = 50] 会使发射器只将 severity 刚好为 50 的事件发送到事件服务器。
要让发射器使用 filter factory profile,在发射器 FilterFactoryProfileJNDIName 属性中输入 JNDI 名称,并配置为启用过滤功能。
除了使用以上提到的概要,用户还可以创建他们自己的过滤器并将它绑定到 JNDI。创建自定义事件过滤器:
- 通过实现 com.ibm.events.filter.Filter 接口创建过滤器。
- 通过实现 com.ibm.events.filter.FilterFactory 创建过滤器工厂。
- 将 FilterFactory 实例绑定到 JNDI 中。
- 在发射器的 Filter Factory JNDI Name 属性中输入 JNDI 名称。
发射器可以在事件源的初始化过程中获得工厂,并用其创建过滤器实例。注意事件源不能绕过由发射器配置的过滤器。
事件分布
产品发布版本引入了一个名为事件消费者(event consumers)的新概念。创建和发送事件到 CEI 服务器的应用程序称为事件源(event sources), 事件消费者预定和监听事件,管理员可以配置包含在事件组概要清单中的事件组概要。事件组概要对象定义了选择器(selector)字符串来决定哪些事件属于这个组。这些选择器字符串使用的类似于 XPath 的语法与过滤器配置中的语法相同。
每个事件组概要可以与一个 JMS 主题及多个 JMS 队列相关联。当 CEI 服务器接收到事件(假设事件分布已启用)时,它将会试图将事件匹配到事件组。如果匹配成功,则将 CBE 发布到为这个事件组而配置的 JMS 队列或主题中。用户可以监听适当 JMS 队列中的事件,或预订到 JMS 主题来处理事件信息。
图 4 展示包含一系列事件组概要的事件组概要清单的类和概念。每个事件组概要可以包含多个分布队列。
图 4 事件组概要清单类的概览
使用分布的例子
创建了两个事件组概要:
表 2.事件组概要
|
事件组概要
|
事件选择器字符串
| | EventGroup A |
CommonBaseEvent[@severity = 70]
| | EventGroup B |
CommonBaseEvent[@severity = 50 or @extensionName = 'ApplicationStarted']
|
EventGroupA 包含两个分布队列定义,但是 EventGroupB 一个都不含。
如果 CEI 服务器接收到 CBE,并启用分布,它将会检查该事件是否与 EventGroupProfileList 中配置的事件组相匹配。如果 CBE 的 severity 设为 70,它会与'EventGroupA'匹配,并发送 CBE 信息到为这个组而配置的任意 JMS 资源(这种情况下,DistributionQueue 资源中指定了两个 JMS 源)。
如果用户想监听特定资源中的事件,他们可以使用消息驱动 Bean(Message Driven Bean,MDB)。CEI 提供一个名为 NotificiationHelper 的助手对象,它包含从 JMS 资源获取的信息,并转换到 CBE 实例。NotificationHelper 的创建是通过 NotificationHelperFactory 对象绑定到 com/ibm/events/NotificationHelperFactory 下的 JNDI 来实现的。 当消息被 onMessage() 方法接收时,可以通过使用 getCreatedMessage(javax.jms.Message message) 方法获取 CBE。
事件访问 API
CEI 的产品发布版发布了完整的事件访问 API。提供了基于特定标准的强大功能的 API 来接收事件。
技术预览版支持通过事件组和 GUID 接收事件。产品发布版支持使用事件选择器来基于内容选择事件。事件选择器语法是 W3C XPath 的子集 (这与公共基础事件规范将事件序列化为 XML 文档来描述事件是不一致的).
例如,给出以下事件,用户可以使用事件选择器字符串 CommonBaseEvent/sourceComponentId/locationTtype='IPv4'; 来接收所有 IPv4 事件,或者使用 CommonBaseEvent/@creationTime > '2004-07-25T11:53:59.403Z' 来接收所有发生过的事件。
<?xml version="quot1.0" encoding="ASCII"?>
<CommonBaseEvent
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:="http://www.ibm.com/AC/commonbaseevent1_0_1"
creationTime="2004-07-24T11:53:59.403Z"
globalInstanceId="CE264B5C800D6811D884C5BF68E0F9AC22"
sequenceNumber="1"
>
<situation categoryName="OtherSituation">
<situationType xsi:type="OtherSituation" reasoningScope=
"EXTERNAL" any="Application Event"
/>
</situation>
<sourceComponentId
component="J2EE Component"
componentType="My Stateless Session EJB"
componentIdType="Stateless Session Bean"
location="127.0.0.1"
locationType="IPv4"
subComponent="None"
/>
</CommonBaseEvent>
|
访问事件访问 API 非常简单。技术预览版使用无状态会话 bean 与 JNDI 名称 /ibm/events/access/EventAccess 绑定来实现入口点的方法没有改变。返回的接口将是 com.ibm.events.access.EventAccessHome。假定所有的方法需要不同的查询类型,可以通过在 home 接口上的 create 方法来返回对象。上面描述的查询例子可以使用以下代码段执行:
EventAccessHome home = (EventAccessHome)
PortableRemoteObject.narrow(ctx.lookup(EVENT_ACCESS_JNDI_NAME),
EventAccessHome.class);
EventAccess eventAccess = home.create();
CommonBaseEvent results[];
results = eventAccess.queryEventsByEventGroup(
"All events",
"CommonBaseEvent/sourceComponentId/@locationType='aposIPv4'apos",
true);
results = eventAccess.queryEventsByEventGroup(
"All events",
CommonBaseEvent/@creationTime > '2004-07-25T11:53:59.403Z'pos,
true);
eventAccess.close();
|
事件目录
事件目录是事件元数据的存储库,它为用户提供指定事件定义的能力。它定义了一套 API,用户可以使用这些 API 来从存储库中添加、查询和删除事件定义。事件定义由名称、父事件定义名称、扩展数据元素和所包含的事件属性组成。事件定义也可以绑定到事件目录,该事件目录用于对事件定义逻辑分组进行定义。
事件目录通过使用无状态会话 bean 来实现,可以通过从 JNDI 查询 home 接口来进行访问,如下所示:
EventCatalogHome eventCatalogHome = (EventCatalogHome)
javax.rmi.PortableRemoteObject.narrow(
initialContext.lookup("quotejb/com/ibm/events/catalog.EventCatalog"),
EventCatalogHome.class)
EventCatalog eventCatalog = (EventCatalog) eventCatalogHome.create();
|
您可以使用事件定义来定义一个特定的事件需要包含哪些属性。但是,假如想让您的应用程序使用这些信息来确认事件,那么这些应用程序必须写出自身的确认逻辑。每当事件定义被修改或添加,事件都会被发送到 CEI 服务器。
本文仅作简短介绍,因为事件目录本身需要更多的文章来描述用户如何添加、删除和查询事件定义和类型。要获取更多的信息,请查阅 API 文档。
命令行实用工具
产品发布版增加了一些新的命令行实用工具和 JACL 脚本,位于 /event/bin 目录,可以在 CEI 上用它们来执行以下操作。
- 发射事件
- 查询事件目录
- 查询事件服务器上的事件
- 从事件服务器中清除事件
每个文件都列出了使用 JACL 脚本所需的参数,并提供了示例。要运行这些脚本,请使用位于 /bin 目录中的 WSAdmin 命令(wsadmin.bat 或 wsadmin.sh ,这取决于您选择的平台)行工具。
Example invocations:
wsadmin -f emitevent.jacl
WASX7209I: Connected to process "server1" on node ozona using SOAP connector;
The type of process is: UnManagedProcess
Successfully submitted event(s) with global instance id(s): CEFD55B434391C9FB9E62154D0E13511D8
wsadmin -f eventquery.jacl -globalinstanceid CEFD55B434391C9FB9E62154D0E13511D8
WASX7209I: Connected to process "server1" on node ozona using SOAP connector;
The type of process is: UnManagedProcess
<CommonBaseEvent
creationTime="2004-07-29T08:04:19.180Z"
globalInstanceId="CEFD55B434391C9FB9E62154D0E13511D8"
sequenceNumber="1" version="1.0.1">
<sourceComponentId component="emitevent.jacl" componentIdType="Application" location="ozona"
locationType="Hostname" subComponent="com.ibm.events.cli.util.EmitEventCliHelper"
componentType="http://www.ibm.com/namespaces/autonomic/Tivoli/EventInfrastructure"/>
<situation categoryName="ReportSituation">
<situationType xsi:type="ReportSituation" reasoningScope="EXTERNAL"
reportCategory="CLI"/>
</situation>
</CommonBaseEven>
1 Event(s) returned.
wsadmin -f eventpurge.jacl -group "All events" -seconds 10
WASX7209I: Connected to process "server1" on node ozona using SOAP connector;
The type of process is: UnManagedProcess
1 Event(s) deleted.
|

 |

|
结束语
CEI 的产品发布版本包含在 WebSphere Business Integration Server Foundation 中,从根本上说它是建立在技术预览版的基础上的,为技术和业务事件提供了完整的事件基础架构。
本文提供了技术预览版新功能的快速参考指南。特别针对之前有技术预览版实践经验的开发者。
参考资料
作者简介  | 
|  |
Andy Brodie致力于公共事件基础架构(Common Event Infrastructure)的开发, 尤其是发射器组件的设计和应用。他同时也协助进行 WebSphere Application Server Enterprise 的开发工作。 |
 | |  |
Amanda Watkinson是英国温彻斯特市 IBM Hursley 实验室的一位软件工程师。Amanda 已经开发了大量的 WebSphere 项目,包括公共事件基础架构技术预览版的配置管理。 |
对本文的评价
|