IBM®
跳转到主要内容
    中国 [选择]    使用条款
 
 
Select a scope:Search for:    
    首页    产品    服务与解决方案     支持与下载    个性化服务    
跳转到主要内容

developerWorks 中国  >  WebSphere  >

IBM WebSphere 开发者技术期刊: 在 Common Event Infrastructure 中使用 Common Base Event

WebSphere Business Integration 技术预览

developerWorks
文档选项

未显示需要 JavaScript 的文档选项


级别: 初级

Amanda Watkinson (amanda.watkinson@uk.ibm.com), 软件工程师, IBM

2004 年 10 月 01 日

本文演示了如何从业务事件和系统事件中创建通用基础事件 (Common Base Event),Common Event Infrastructure 可以消费这两种事件,它是作为 IBM® WebSphere® Business Integration Server Foundation V5.1 中的技术预览发布的。

引言

IBM WebSphere Business Integration Server Foundation V5.1 包括 Common Event Infrastructure 技术预览版,它可以用来创建、存储和分布事件。其内部的通用基础事件提供了捕捉关于重要系统或业务事件信息的方法。例如:

  • 重要的 系统事件可能会发生在特定服务器的性能降低到临界阈值以下的时候。
  • 重要的 业务事件封装了针对特定业务的信息,例如,当一位重要的客户下订单时,您可能需要存储额外的信息或提示某人该事件已经发生。

虽然通用基础事件提供了特定的标准信息,但是编程 API 使得用户可以用针对他们自己业务需要的信息来填充事件。本文介绍了通用基础事件 (CBE),它是 Common Event Infrastructure (CEI) 服务的一部分,并演示了创建和填充事件来捕捉并关联系统行为和业务行为的不同方法。





回页首


Common Event Infrastructure 和 Common Base Event API

图 1 概括描述了 Common Event Infrastructure:

  • 应用程序从 JNDI 获取 EventFactory 对象。该对象是通用基础事件的访问点,并为创建空事件提供了 API。
  • 用数据填充空通用基础事件并将其传送给 CEI 服务器(通过发射器),事件可以持久存储在 CEI 服务器上或分发给消费者。
  • 发射器是从绑定在 JNDI 中的 EmitterFactory 对象创建的。根据发射器如何过滤事件、如何处理事务以及他们的发送方式,可以将发射器配置为拥有不同的行为。(本文没有详细描述 EmitterFactory 和 CEI 服务器的行为和功能。只大致的描述了如何使 CBE 适合 CEI 服务。)


图 1.Common Event Infrastructure 概览
Common Event Infrastructure 概览

CEI 为创建事件提供了 Java 编程接口。接下来的部分说明了如何创建通用基础事件、用系统信息和业务信息填充该事件,还描述了一些用于创建应用程序和特定于业务的数据的 CBE 属性和方法。接下来的信息全部用来演示如何创建通用基础事件。





回页首


获取 EventFactory 对象

EventFactory 是通用基础事件的起始点。有三种不同的方法可以获取并利用 EventFactory 生成通用基础事件。下面是这些方法间的区别:

  • 第一个方法描述了如何获取一个简单的 EventFactory 对象,而第二个和第三个方法描述的是如何用 ContentHandler 获取 EventFactory 对象,ContentHandler 对象提供了一个完成事件填充的方法,当用户显式调用 CBE 上的 complete() 方法时,调用该方法,或在将事件发送到 CEI 服务器之前通过发射器调用该方法。
  • 第二个方法着眼于特定于 WebSphere 的 EventFactory,而第三个方法则显示了一个运行于 WebSphere 环境之外的应用程序是如何用 ContentHandler 来创建它自己的 EventFactory 的。

每种方法的信息如下所示:

  1. 获取一般的 EventFactory
    这种 EventFactory 提供了用于产生通用基础事件及其相关属性的 API。清单 1 显示了如何获取这种 EventFactory 对象。EventFactory 被绑定到 com/ibm/events/EventFactory 下的 JNDI 中。

    清单 1.

    import com.ibm.events.cbe.*;
    EventFactory eventFactory = (EventFactory)javax.rmi.PortableRemoteObject.narrow
    	(initialContext.lookup("com/ibm/events/EventFactory"), EventFactory.class);
    

  2. 获取特定于 WebSphere 的 EventFactory
    除了与 ContentHandler 对象相关联以外,这种 EventFactory 和一般的 EventFactory 是相似的。当通用基础事件被发送给 CEI 服务时,它自动完成 SourceComponentId 属性,除非应用程序明确指定要覆盖该属性值。(有关 SourceComponentId 属性的详细信息,请参阅 填充通用基础事件。)但是,使用这种 EventFactory,SourceComponentId 字段是用特定于 WebSphere 环境的信息填充的。WebSphere EventFactory 对象被绑定到 com/ibm/websphere/events/factory 下的 JNDI 中。为了确保 SourceComponentId 始终被填充,这种 EventFactory 应该供运行在 WebSphere 服务器环境中的所有应用程序使用。

    清单 2.

    EventFactory eventFactory = (EventFactory)javax.rmi.PortableRemoteObject.narrow
    	(initialContext.lookup("com/ibm/websphere/events/factory"), EventFactory.class);
    

  3. 获取用户定制的 EventFactory
    对于运行于 WebSphere 环境之外的应用程序,可以创建自定义 ContentHandler,并将其联系到 EventFactory。下面的代码样本显示了应用程序是如何生成 ContentHandler 对象的,并用 EventFactoryFactory 类生成 EventFactory。然后可以将这个 EventFactory 对象绑定到 JNDI 中,使得其它的应用程序可以访问它。(有关 JNDI 的详细信息请参阅 参考资料。)

    清单 3.

    /* Create a custom class which holds the implementation needed to populate the Common Base Event */
    CustomContentHandler implements ContentHandler{
    	
    	public CustomContentHandler(){}
    	public void completeEvent() {
    		
                    
                    // Add code to populate the event with desired values
    	}
    }
    /* Create a new CustomerContentHandler and associate it with an EventFactory */
    ContentHandler myCustomContentHandler = new CustomContentHandler();
    EventFactory eventFactory = EventFactoryFactory.createEventFactory(myCustomContentHandler);
    /* Bind the EventFactory object into JNDI */
    Context myContext = new InitialContext();
    myContext.bind("eventFactory/myCustomEventFactory");
    /* Obtain the EventFactory from JNDI to be used to generate Common Base Events */
    EventFactory = (EventFactory)javax.rmi.PortableRemoteObject.narrow
    	(initialContext.lookup("eventFactory/myCustomEventFactory"), EventFactory.class);
                  
                  





回页首


创建通用基础事件

EventFactory 对象提供了三种创建 CommonBaseEvent 对象的方法,如清单 4 所示:


清单 4.
CommonBaseEvent event = eventFactory.createCommonBaseEvent();
CommonBaseEvent event = eventFactory.createCommonBaseEvent
			(java.lang.String extensionName);
CommonBaseEvent event = eventFactory.createCommonBaseEvent
			(java.lang.String extensionName, long creationTime);

在通用基础事件被发射器发送到 CEI 服务器之前,必须要对其进行有效性验证,确保已经设置了所有必需的字段。表 1 列出了有效通用基础事件至少要包括的字段。

表 1.必需的 CBE 字段

字段名称 描述
ExtensionName 这个字段可以放在 CBE 构造函数中,用来标识事件的类型。
CreationTime 创建时间可以放在 CommonBaseEvent 构造函数中或者用 CBE 方法 setCreationTime(java.lang.String creationTimeValue), setCreationTimeAsLong(long creationTime) 显式声明。
SituationType 有效的 SituationType 有: AvailableSituation、ConfigureSituation、ConnectSituation、CreateSituation、DependancySituation、DestroySituation、FeatureSituation、OtherSituation、ReportSituation、RequestSituation、StartSituation、StopSituation
SourceComponentId 这个字段表示 ComponentIdentification 类型。属性包括,例如,组件类型、位置、流程以及线程信息。
Version CBE 必需有一个有效的版本号码。这是自动创建的。

表 1 中列出的 SituationType 是用于描述事件发生时的状态的。例如,StartSituation 用于标识组件启动时的事件。EventFactory 有创建每种状态类型的帮助方法,然后在被传送到通用基础事件之前用附加信息填充。在每种 SituationType 中,可以指定 reasoningScope、situationQualifier 和 situationDisposition。(有效字段的详细描述请参阅 API 文档。) 通用基础事件实例显示了如何填充这些字段。

特定于 WebSphere 的 EventFactory 自动设置 CreationTime,并且如果没有指定的话,还自动创建 OtherSituation 的 SituationType 属性。另外,SourceComponentId 也是自动创建和填充的。因此,如果使用特定于 WebSphere 以外的 EventFactory,应用程序只需要指定这些字段即可。表 2 描述了特定于 WebSphere 的 ContentHandler 对象创建的 ComponentIdentification 值。

表 2.用 WebSphere ContentHandler 对象创建的 ComponentIdentification 值

ComponentIdentification 字段 特定于 WebSphere 的值
componentIdType 固定值设为 ProductName
component WebSphere 平台标识符,例如: Platform 5.0 [BASE 5.0.2 ptf2O0320.06] [ND 5.0.2[ptf2O0320.06]
componentType 固定值设为 WebSphereApplicationServer
subComponent 值可以为:
  • J2EE_Application (默认的)
  • WebAppServer_EJB_Container
  • Workflow_Engine
locationType 固定值设为 Hostname
location 服务器或服务器区的主机名。
instanceId 值可以为:
  • cell.node.server
  • node.server
  • server
单元、节点和服务器与 WebSphere 单元名称、节点名称和服务器名称是相对应的。
executionEnvironment 运行 WebSphere application server 的操作系统。该信息是从 Java 虚拟机 (Java Virtual Machine,JVM) 中提取出来的。
processId JVM 标识。
threadId 最初创建 CBE 的线程标识。





回页首


填充通用基础事件

这一部分详细描述了在 创建通用基础事件部分中描述的字段,并说明了用数据填充通用基础事件的一些方法。对于通用基础事件中的大多数字段来说,添加数据的方法不只一种。下面列出了一些最常用的属性,要了解完整的字段和方法请参阅 API 文档。

  • ContextDataElement:用于关联作为操作的相同片段或单元出现的事件。下面的 Java 代码显示了向事件中添加 ContextDataElement 的两种不同的方法。上下文的名称用将成为它的类型内的那个上下文的具体实例的 contextId 定义类型。如果指定了 contextValue,就不用指定 ContextId 了,反之亦然。

    清单 5.

    ContextDataElement contextDataElement = eventFactory.createContextDataElement();
    contextDataElement.setContextId("1234");
    contextDataElement.setName("Order");
    contextDataElement.setType("string");
    

    清单 6.

    event.addContextDataElementWithValue("string", "Order", "newOrder1");
    

  • CreationTime:必需的字段,用于显示事件发生的时间。在 WebSphere EventFactory 中,该值精确到毫秒。如果应用程序需要更高的精确度,应该使用 SequenceNumber 来显示事件的顺序,看他们是否发生在同一毫秒时间段中。
  • ElapsedTime:可选字段,但是如果使用了 RepeatCount,则必需指定该字段。这个字段定义了同一情形重复发生所间隔的时间。下面的 Java 代码显示了如何将 ElapsedTime 添加到事件中。

    清单 7.

    event.setElapsedTime(time); // Set time as a long
    

  • ExtensionName:必需的字段,用于标识事件的类型,例如,订单、交付等等。指出事件中 ExtendedDataElement 的类型,可以放在 CommonBaseEvent 构造函数中,如在 创建通用基础事件中所描述的。
  • ExtendedDataElement:用于存储应用程序数据。ExtendedDataElement 可以嵌套在其它的 ExtendedDataElement 中,从而构建应用程序信息树。下面的 Java 代码显示了一个如何在事件中嵌套这些 ExtendedDataElement 的实例。用 TYPE_NO_VALUE 表明 OrderInformation 包含子元素 OrderNo 和 OrderLocation。

    清单 8.

    ExtendedDataElement extendedDataElement = 
    event.addExtendedDataElement("OrderInformation");
    extendedDataElement.addType(ExtendedDataElememt.TYPE_NO_VALUE);
    extendedDataElement.addChildWithIntValue("OrderNo", 30);
    extendedDataElement.addChildWithStringValue("OrderLocation", "LondonBranch");
    

  • GlobalInstanceId:必需有一个唯一值。如果没有设置该字段,当事件被发送到 Common Event Infrastructure Server 时,会自动添加。

    清单 9.

    event.setGlobalInstanceId("uniqueValue");
    

  • LocalInstanceId:和 GlobalInstanceId 不一样,该字段不用是唯一的。它让用户设置 ID,ID 对应用程序或用户都有非常重要的意义。

    清单 10.

    event.setLocalInstanceId("value");
    

  • Msg:可选字段,让应用程序指定用户消息。

    清单 11.

    event.setMsg("userReadableValue");
    

  • Priority:用于指定将被处理的事件的优先级。如果设置了严重性,优先考虑优先级字段。表 3 列出了一些优先级值,最高的可能值为 100,0 到 100 间的任何值也都可以用来表示优先级。

    清单 12.

    event.setPriority(priority); // Set priority as a short
    

    表 3. 事件优先级

    优先级值(短整型) 描述
    100 这种事件必须最先处理,它的优先级最高。
    90 紧急事件,应该尽可能快地处理。
    70 重要事件。
    50 一般事件。
    10 优先级较低的事件。
    1 最后处理这种事件。

  • Severity:描述事件的严重性。如果与优先级一起使用,那么优先考虑优先级值。表 4 列出了一些严重性值,0 到 60 之间的任何数字都可以用来表示严重性。

    表 4.事件严重性

    严重性值(短整型) 描述
    60 致命错误 - 用于表示发生了错误,补救措施也无能为力。
    50 紧急 - 用于表示发生了错误,需要紧急补救措施。
    40 小错误 - 用于表示需要采取措施,但是情形不是很危急。
    30 警告 - 用于向用户发出警告。然后用户决定是否需要采取措施。
    20 无害 - 发生了错误,但是不会对应用程序或系统造成损害。
    10 信息 - 用于表示只是信息事件,没有发生错误。
    0 未知

  • SequenceNumber:可以用来表示事件的顺序。有关详细信息请参阅 CreationTime
  • SourceComponentId:用 ComponentIdentification 类型创建的,并用 setSourceComponentId(ComponentIdentification value) 方法将其传送到通用基础事件。表 5 列出了 ComponentIdentification 字段。

    表 5.ComponentIdentification 字段

    ComponentIdentification 字段 描述
    Application 表示创建该事件的应用程序。
    Component 标识组件,例如,应用程序所使用的 WebSphere 平台。
    ComponentType 与 ComponentIdType 结合使用,指定组件的类型,例如,WebSphereApplicationServer。
    ComponentIdType 指定 ComponentType,例如,ComponentIndentification.COMPONENT_ID_TYPE_PRODUCT_NAME
    ExecutionEnvironment 关于环境的信息,例如,操作系统和版本号。
    InstanceId 定义实例标识,例如,WebSphere 单元名称。
    Location 与 LocationType 结合使用。例如,如果有一个 LocationType 为 ComponentIdentification.LOCATION_TYPE_HOSTNAME,那么 Location 字段表示主机名。
    LocationType 表示 Location 字段的类型。
    ProcessId JVM 流程标识符。
    SubComponent 生成事件的子组件名称,例如,EJB 或 J2EE 应用程序。
    ThreadId 线程标识符。

  • Situation:必需的字段,如同在 创建通用基础事件中所描述的那样。表 6 描述了每种状态类型。

    表 6.状态类型

    状态类型 描述
    AvailableSituation 表示组件的可用状态。
    ConfigureSituation 表示正在配置组件。
    ConnectSituation 表示一个组件正在连接另一个组件。
    CreateSituation 表示正在创建组件。
    DependancySituation 表示非独立组件的可用性。
    DestroySituation 表示正在销毁组件。
    FeatureSituation 表示特定特性的状态。
    OtherSituation 其它状态类型。
    ReportSituation 表示来自组件的报告数据。
    RequestSituation 表示来自组件的请求数据。
    StartSituation 表示组件正在启动。
    StopSituation 表示组件正在停止。

  • RepeatCount:与 ElapsedTime 结合使用,指定某一个特定状态重复的次数。





回页首


通用基础事件实例

这一部分集中了上面描述的信息来显示通用基础事件是如何创建的,以及如何被发送到 CEI 服务器的。图 2 和下面的代码样本演示了当提交新的 Web 订单时,如何创建两个事件,以及这些事件是如何说明如何将具体数据存储到通用基础事件内。第一个事件记录订单数据,第二个事件用于标识重要的客户。该实例用的是特定于 WebSphere 的 EventFactory。(结尾部分提供了一个 实例,显示了如果用一般的 EventFactory 将会是什么样子的。)


图 2.订单应用程序事件
订单应用程序事件

  1. 从 JNDI 获取 EventFactory。

    清单 13.

    EventFactory eventFactory = (EventFactory)javax.rmi.PortableRemoteObject.narrow
    	(initialContext.lookup("com/ibm/websphere/events/factory"), EventFactory.class);
    

  2. NewOrderImportantCustomer 的扩展名创建两个 common base event。

    清单 14.

    CommonBaseEvent newOrderEvent = EventFactory.createCommonBaseEvent("NewOrder");
    CommonBaseEvent importantCustomer = EventFactory.createCommonBaseEvent("ImportantCustomer");
    

  3. 用作为一个有效的通用基础事件所需的必需字段填充每个事件。(本实例使用特定于 WebSphere 的 EventFactory,自动完成 SourceComponentId。)在这个实例中,我们重载了 Situation,并提供了我们自己的唯一的 GlobalInstanceId。

    清单 15.

    /* Set the rest of the required fields for globalInstanceId, and situation */
    OtherSituation situation = eventFactory.createOtherSituation();
    situation.setReasoningScope("EXTERNAL");
    situation.setAny("Application Event");
    newOrderEvent.setSituation(situation);
    importantCustomer.setSituation(situation);
    newOrder.setGlobalInstanceId("0348yufgfgdgvc");
    importantCustomer.setGlobalInstanceID("vgnruisw74yd");
    

  4. 为新订单事件设置业务数据。

    清单 16.

    newOrderElement.addContextDataElementWithValue("string", "OrderEJB_J2EE", "order_number1");
    ExtendedDataElement extendedDataElement = 
    		newOrderEvent.addExtendedDataElement("OrderInformation");
    extendedDataElement.addType(ExtendedDataElememt.TYPE_NO_VALUE);
    extendedDataElement.addChildWithIntValue("OrderNo", 1);
    extendedDataElement.addChildWithIntValue("Quantity", 1000);
    extendedDataElement.addChildWithIntValue("OrderValue", 250000);
    ExtendedDataElement extendedDataElement = 
    		newOrderEvent.addExtendedDataElement("CustomerInformation");
    extendedDataElement.addType(ExtendedDataElememt.TYPE_NO_VALUE);
    extendedDataElement.addChildWithStringValue("CustomerName", "Fred Bloggs");
    extendedDataElement.addChildWithStringValue("Address", "1 High Street, L1 1OH");
    extendedDataElement.addChildWithStringValue("ImportantCustomer", "Y");
    newOrderEvent.setPriority(70);
    importantCustomer.setPriority(90);
    

  5. 获取发射器并将事件发送到 CEI 服务器。

    清单 17.

    EmitterFactory emitterFactory = (EmitterFactory)javax.rmi.PortableRemoteObject.narrow
    	(initialContext.lookup("com/ibm/events/configuration/emitter/Default"), EmitterFactory.class);
    Emitter emitter = emitterFactory.getEmitter();
    emitter.sendEvent(newOrderEvent);
    emitter.sendEvent(importantCustomer);
    

上面的实例使用特定于 WebSphere 的 EventFactory,自动完成了 SourceComponentId 和 CreationTime 字段。下面的代码显示了如果使用一般的 EventFactory 这个信息是如何完成的:

清单 18.

/* Specify the CreationTime */
newOrderEvent.setCreationTime((new Date()).getTime());
importantCustomer.setCreationTime((new Date()).getTime());
/* Specify the ComponentIdentification */
ComponentIdentification componentID = eventFactory.createComponentIdenticiation();
componentID.setComponentIdType(ComponentIdentification.COMPONENT_ID_TYPE_PRODUCT_NAME);
componentID.setComponent("WebSphere 5.1");
componentID.setComponentType("WebSphereApplicationServer");
componentID.setSubComponent("OrderEJB");
componentID.setLocationType(ComponentIdentification.LOCATION_TYPE_HOSTNAME);
componentID.setLocation("Machine2");
componentID.setInstanceId("123");
componentID.setExecutionEnvironment("Windows 2000");
componentID.setProcessId("4657A3");
componentID.setThreadId("564");
/* Set the ComponentIdentification for each of the CBEs using the setSourceComponentId method */
newOrderEvent.setSourceComponentId(componentID);
importantCustomer.setSourceComponentId(ComponentID);





回页首


结束语

Common Event Infrastructure 技术预览版让我们知道了业务信息和系统信息是如何作为通用基础事件被捕捉、持久存储和分布的。虽然编程 API 需要填充特定的字段,但是 API 使用户能根据他们自己的业务需要来捕捉数据。这篇入门文章介绍了一些用来描述系统信息和业务信息的重要字段,并描述了获取和填充事件的不同方法。当 Common Event Infrastructure 作为产品发行时,这些概念将更加让人兴奋,使用户能够跨系统关联和集成信息。



参考资料



关于作者

Amanda Watkinson 是英国温彻斯特市 IBM Hursley 实验室的一位软件工程师。Amanda 已经开发了大量的 WebSphere 项目,包括 Common Event Infrastructure 技术预览版的配置管理。




对本文的评价

太差! (1)
需提高 (2)
一般;尚可 (3)
好文章 (4)
真棒!(5)

建议?







回页首


IBM 公司保留在 developerWorks 网站上发表的内容的著作权。未经IBM公司或原始作者的书面明确许可,请勿转载。如果您希望转载,请通过 提交转载请求表单 联系我们的编辑团队。
    关于 IBM 隐私条约 联系 IBM 使用条款