在公共信息模型(Common Information Model,CIM)中,客户机应用程序可以订阅 CIM 事件通知。通常,应用程序可以通过不同的连接端口用多个事件处理程序创建事件过滤器,但是这将消耗大量网络资源并增加维护复杂度。在本文中,查看如何用一个特定连接端口注册多个 CIM 事件处理程序。另请查看如何用 SBLIM CIM 客户机库编写代码的一些提示。
让我们首先来查看一些关键词。分布式管理任务工作组(Distributed Management Task Force,DMTF)公共信息模型(Common Information Model,CIM)是描述企业环境和 Internet 环境中的计算实体和业务实体的概念信息模型。它将提供一致的使用面向对象技术的数据定义和结构。
CIM 事件 是一种有趣的现象,可以按照生命周期 或警告 分类。CIM 事件十分复杂并且涉及到范围广泛的主题和场景。在 CIM 架构中,客户机应用程序可以订阅 CIM 事件的通知。通常,应用程序可以通过多个连接端口用相关事件处理程序创建事件过滤器。
在本文中,我们将展示如何用一个特定的连接端口注册 CIM 事件处理程序以避免增加复杂度。这将使您可以更轻松地用最少的网络资源实现和维护一个具体的、可操作的 CIM 事件模型。
CIM 事件模型概览
CIM 事件模型将定义与事件相关的抽象。它将描述 CIM 表示层次结构及如何将表示用于模型事件。事件模型还将描述如何使用订阅进行注册,以便您可以接收表示。
表示可以有零个或多个事件触发器,这些触发器可以识别状态更改。例如,如果由于卷创建而触动触发器,此事件将得到一个卷创建的生命周期表示。另举一例,如果由于拔出磁盘而触动触发器,此事件将得到磁盘已拔出的警告表示。
基于 HTTP 的 CIM 操作规范(有关链接,请参阅 参考资料)将描述发送和接收 CIM 表示的 CIM-XML 标准。图 1 中显示了 CIM 事件模型的全部工作流程:
图 1. CIM 事件模型的工作流程
整个操作流程包括以下步骤:
- CIM 客户机将发出 CIM 服务器过程请求,该请求将创建基于网络的订阅;过程的主要函数将注册以接收表示。
- CIM Object Manager(CIMOM)将接收请求并检查其验证。随后,CIMOM 将在 CIMOM Repository 中创建 CIM 表示过滤器、CIM 表示处理程序和 CIM 表示订阅。
- CIMOM 将联系 CIM Indication Provider,请求提供程序响应 CIMOM 所发出的请求来生成适当的表示。
- 当提供程序生成表示时,CIMOM 将把表示路由到 CIM 表示处理程序实例所指定的 CIM Indication Listener 中。这些实例是由 CIMOM Repository 中的订阅者创建的。
从技术上讲,当客户注册以接收 CIM 事件模型中的表示时,需要创建三类 CIM 实例:
- CIM Indication Filter:CIM_IndicationFilter 实例,用于定义表示使用者感兴趣的表示集合。
- CIM Indication Handler:CIM_ListenerDestination 实例,用于描述表示使用者的位置、编码和传输协议。
- CIM Indication Subscription:CIM_IndicationSubscription 实例,用于描述表示流程。该流程是由引用的表示过滤器指定并且定向到引用目标或在表示处理程序中处理。
CIM 表示类层次结构用于描述在正确定义了表示订阅后可以检测到的事件类型。CIM_Indication 实例表示事件的出现。通常,表示是生命周期非常短暂的对象,用于从表示生成器到零个或多个表示使用者之间传递信息。下面是 CIM 事件模型中定义的相关 CIM 表示类:
- Root 类
- CIM_Indication
- 超类
- CIM_ClassIndication
- CIM_InstIndication
- CIM_ProcessIndication
- 子类
- CIM_ClassCreation
- CIM_ClassDeletion
- CIM_ClassModification
- CIM_InstCreation
- CIM_InstDeletion
- CIM_InstMethodCall
- CIM_InstModification
- CIM_InstRead
- CIM_AlertIndication
- CIM_J2eeNotification
- CIM_SNMPTrapIndication
当您在 CIM 事件模型中注册 CIM 事件处理程序时可以使用所有类,这取决于具体要求。我们将在下面的小节中给您提供一些代码示例并且在最后提供实验结果。
创建事件过滤器
事件过滤器将描述要交付的事件类型及交付条件。要创建事件过滤器,需要创建 CIM_IndicationFilter 类的实例并定义其属性值。可以设置这些属性以惟一识别过滤器、指定查询字符串和指定解析查询字符串的查询语言。注意,属性是不是强制属性取决于目标 CIM 服务器中的 CIM 提供程序的实现;不同的 CIM 提供程序之间的字符串属性格式会略有不同。
清单 1 显示了用 SBLIM CIM 客户机库创建事件过滤器的示例:
清单 1. 创建事件过滤器的样例代码
// Define the name of CIM class to be created
String filterClassName = "CIM_IndicationFilter";
// Define the filter string for CIM_IndicationFilter instance
String filterString = "SELECT * FROM CIM_InstCreation WHERE SourceInstance
ISA CIM_StorageVolume";
// Get the CIM class definition from the CIMOM
CIMClass filterClass = _client.getClass(new CIMObjectPath(filterClassName));
// Create an instance of the CIM_IndicationFilter class
CIMInstance filterInstance = filterClass.newInstance();
// Set the name of the filter
filterInstance.setProperty("Name",
new CIMValue("PCL_Event",
new CIMDataType(CIMDataType.STRING)));
// Set the filter string to select CIM events
filterInstance.setProperty("Query",
new CIMValue(filterString,
new CIMDataType(CIMDataType.STRING)));
// Set the query language (WQL) to parse the query string
filterInstance.setProperty("QueryLanguage",
new CIMValue("WQL",
new CIMDataType(CIMDataType.STRING)));
// Set the source name space of the filter
filterInstance.setProperty("SourceNamespace",
new CIMValue(_namespace,
new CIMDataType(CIMDataType.STRING)));
// Create an instance of CIM_IndicationFilter on the target CIM server
CIMObjectPath filterCOP = _client.createInstance(new CIMObjectPath(),
filterInstance);
|
用一个连接端口创建事件处理程序
通常,应用程序可以通过多个连接端口用事件处理程序创建事件侦听程序,但是这在网络资源和维护方面花费较大。
通过使用两个类 —SBLIM CIM Client Library 中定义的 CIMEventDispatcher 和 HttpServerConnection — 可以用一个特定的连接端口注册 CIM 事件处理程序。图 2 中显示了整个过程。
图 2. 用一个连接端口将事件分发给事件处理程序
下面是用同一个端口创建事件处理程序的两个步骤:
- 在客户端注册侦听程序。
- 在提供程序端用目标信息创建侦听程序实例。
清单 2 和 3 显示了创建方法:
清单 2. 在客户端注册侦听程序
// Create a CIMIndicationListenertList instance
CIMIndicationListenertList _indicationClient =
new CIMIndicationListenertList();
/*
* Add a inner listener to the list, because if there is only one listener in
* CIMIndicationListenertList, it will get all event no matter the event is the
* certain listener registered to listen or not, we need to add a InnerListener
* which implements CIMListener and doing nothing
*/
_indicationClient.addListener(new InnerListener());
/*
* Add IndicationListenerList to a dispatcher, CIMEvent will be dispatched to
* target listener according to the hash code of one listener
*/
CIMEventDispatcher dispatcher = new CIMEventDispatcher(_indicationClient);
// Create an new CIMIndicationHandler instance which wraps the dispatcher
CIMIndicationHandler indicationHdlr = new CIMIndicationHandler(dispatcher);
// Create a HttpServerConnection with the specified port
// NOTE: This target port is shared by all the event handlers
HttpServerConnection _serverConn = new HttpServerConnection(
new HttpConnectionHandler(indicationHdlr), targetPort);
_serverConn.setName("CIMListener - Http Server");
_serverConn.start();
// You can also add listener after HttpServerConnection has started
|
清单 3. 在提供程序端创建侦听程序实例
// Create internal listener, InternalListener should implement CIMListener and
// have its own function
InternalListener internalListener = new InternalListener();
// Add internal listener to CIMIndicationListenertList instance
_indicationClient.addListener(internalListener);
// Create a listener destination instance
CIMClass indicationDestinationClass = _client.getClass(
new CIMObjectPath("CIM_ListenerDestinationCIMXML"), false);
CIMInstance cimListener = indicationDestinationClass.newInstance();
// Set the properties of CIM instance, and which properties are mandatory are
// highly depending on the implementation of CIM providers
// Set the creation class name of the listener
cimListener.updateProperty(new CIMProperty("CreationClassName",
new CIMValue("CIM_ListenerDestinationCIMXML",
CIMDataType.getPredefinedType(CIMDataType.STRING))));
// Set the system creation class name of the listener
cimListener.updateProperty(new CIMProperty("SystemCreationClassName",
new CIMValue(null,
CIMDataType.getPredefinedType(CIMDataType.STRING))));
// Set the system name of the listener
cimListener.updateProperty(new CIMProperty("SystemName",
new CIMValue(null,
CIMDataType.getPredefinedType(CIMDataType.STRING))));
// Set the name of the listener
cimListener.updateProperty(new CIMProperty("Name",
new CIMValue(listenerName,
CIMDataType.getPredefinedType(CIMDataType.STRING))));
// Set destination value, it should be combined with IP address of client and
// hash code of the listener object
cimListener.updateProperty(new CIMProperty("Destination",
new CIMValue(IPAddress +
"/" +
internalListener.hashCode(),
CIMDataType.getPredefinedType(CIMDataType.STRING))));
// Register the listener destination on the target CIM server
CIMObjectPath listenerCOP = _client.createInstance(new CIMObjectPath(),
cimListener);
|
将事件过滤器绑定到事件处理程序
事件过滤器将定义过滤器的条件。事件处理程序将描述在发生特定事件后采取的操作。
因此,绑定事件过滤器与事件处理程序意味着设置在特定事件发生时采取特定操作的情形。
CIM 类 CIM_IndicationSubscription 中有两个属性:
- Filter 指一个事件过滤器实例的对象路径。
- Handler 指一个事件处理程序实例的对象路径。
在绑定事件过滤器与事件处理程序时,您是在创建 CIM_IndicationSubscription 类的实例并设置该实例的 Filter 和 Handler 属性。在创建该类的表示时,将交付事件过滤器所指定的事件表示。
在 CIM 事件模型下,事件过滤器与事件处理程序之间的关系可以表示为 m:n,这意味着一个事件过滤器可以绑定到多个事件处理程序上,或者一个事件处理程序可以绑定到多个事件过滤器。图 3 和 4 演示了这两种情况。
图 3. 向多个事件处理程序注册一个事件过滤器
图 4. 为一个事件处理程序注册多个事件过滤器
清单 4 显示了如何用 SBLIM CIM 客户机库绑定事件处理程序与事件过滤器。
清单 4. 绑定事件过滤器与事件处理程序的样例代码
// Define class name of indication subscription
String subscriptionClassName = "CIM_IndicationSubscription";
// Construct object path of CIM_IndicationSubscription
CIMObjectPath cop = new CIMObjectPath(subscriptionClassName, _namespace);
// Get the CIMClass object for subscription
CIMClass subscriptionClass = _client.getClass(cop);
// Create CIM_IndicationSubscription instance and set properties
CIMInstance subscriptionInstance = subscriptionClass.newInstance();
// Set object path of event filter instance as the value of "Filter" property
subscriptionInstance.setProperty("Filter",
new CIMValue(filterInstance.getObjectPath(),
new CIMDataType(CIMDataType.REFERENCE)));
// Set object path of event handler instance as the value of "Handler" property
subscriptionInstance.setProperty("Handler",
new CIMValue(handlerInstance.getObjectPath(),
new CIMDataType(CIMDataType.REFERENCE)));
// Create CIM_IndicationSubscription instance on the target CIM server
CIMObjectPath sop = _client.createInstance(new CIMObjectPath(),
subscriptionInstance);
|
Linux 中的测试结果
我们在 Linux® 中部署了实现并且执行了一些测试。当在目标 CIM 服务器上注册 CIM 事件处理程序时,我们能够获得每个建立的侦听程序的连接信息。
图 5 显示了典型网络状态;每个侦听程序都有自己的通信端口。
图 5. 典型的注册 CIM 事件处理程序
图 6 显示了我们的实现使用的网络状态。您可以看到所有侦听程序都共享同一个通信端口。
图 6. 我们实现的注册 CIM 事件处理程序
(责任编辑:A6)
gmail.com