解决有关用户定义扩展的问题

尽管在正确的目录中已有插件 LIL,但仍无法部署某个用户定义节点。

过程

  • 场景: 尽管在正确的目录中具有插件 LIL ,但无法部署其中一个用户定义的节点。
  • 说明: 您已将 memset() 数据区设置为零,并且尚未使用初始化常量 {CNI_VFT_DEFAULT}初始化 CNI_VFT 结构。
  • 解决方案: 通过在函数表区域上复制预定义的初始化结构来初始化,如下所示:
    static CNI_VFT	virtualFunctionTable = {CNI_VFT_DEFAULT};

    此外,请实现从用户定义节点进行记录,以便您可以查看插件 API 是否正在产生错误代码;除非您采用服务跟踪,否则集成节点不会将这些代码记录到自己的日志中。

您不能部署含有用户定义节点的流。

过程

  • 场景: 无法部署包含其中一个用户定义节点的流。
  • 说明: 无法装入 LIL 文件。
  • 解决方案: 检查集成节点启动的系统日志 (syslog 或 Eventviewer); 是否看到 BIP2308 消息指出 LIL 文件未能装入? 如果装入 LIL 文件时存在任何问题,系统日志中则出现 BIP2308 消息。

当节点尝试在插件 API 中使用 ESQL 路径接口时遇到问题

过程

  • 场景: 尝试在插件 API 中使用 ESQL 路径接口时,返回值为 CCI_PATH_NOT_NAVIGABLE。
  • 说明: 插件 API 允许您以 ESQL 路径表达式的形式指定路径,并浏览至该元素,如果该元素存在,那么返回该元素的句柄。 它还允许您使用指向请求元素的路径创建元素。

    导航实用程序函数(cniSqlNavigatePath)会执行使用 cniSqlCreateReadOnlyPathExpressioncniSqlCreateModifiablePathExpression 实用程序函数创建的 SQLPathExpression(如 sqlPathExpression 参数所定义的那样)。

    如果路径无法导航,则返回码设置为 CCI_PATH_NOT_NAVIGABLE。 当将一个路径表达式嵌入到另一个路径表达式中时,也可能会返回该代码。 输入 cciMessage* 函数不能为 NULL;但是任何输出 cciMessage* 函数都可为 NULL。 如果将可为 NULL 的路径表达式嵌入到不能为 NULL 的路径表达式中,则会返回 CCI_PATH_NOT_NAVIGABLE。

  • 解决方案: 如果返回码设置为 CCI_PATH_NOT_NAVIGABLE ,请确保如果在路径中指定了相关名称,那么相应的参数不为 NULL。

迁移之后,定制属性编辑器无法正常运行

过程

  • 场景: 您已迁移到 IBM® App Connect Enterprise 的新版本,但自定义属性编辑器不再起作用。
  • 说明: 定制属性编辑器可以使用 Eclipse 或 RAD API。 如果 IBM App Connect Enterprise 的新版本中更改了这些API中的任何一个,您的属性编辑器可能无法正常工作。
  • 解决方案: 更新属性编辑器代码以符合已更改的 API。

解释有关用户定义扩展的问题

过程

  • 场景: 您希望调试用户定义节点和解析器中的问题。
  • 解决方案: 在调试级别启动用户跟踪。 如果要查看 BIP4142BIP4144BIP4145BIP4146 消息,那么必须启动集成服务器级别的用户跟踪。 例如,使用不带 -f 参数的 mqsichangetrace 命令。
    以下调试消息可用于帮助您了解用户定义节点和解析器的执行情况。
    • BIP2233BIP2234:调用用户定义扩展实现函数之前和之后跟踪到的一对消息。 这些消息会报告输入参数和返回的值。 例如:

      BIP2233Invoking user-defined extension function [function name] ([function call parameters])

      BIP2234Returned from user-defined extension function [function name] with result: [result of call]
      注: 在这些消息中, 实现函数 可以解释为 C 实现函数或 Java™ 实现方法。
    • BIP2308:集成节点无法装入 LIL 文件时所记录的消息。

      BIP2308File [name of LIL file] could not be loaded; operating system return code [error code return from operating system]

    • BIP3904: 在调用用户定义节点的 Java evaluate() 方法之前跟踪的消息。 例如:

      BIP3904(for Java): Invoking the evaluate() method of node (class=[node class name], name=[label of node in flow])其中 node class name 是 Java 用户定义的扩展类的名称。

    • BIP3905:调用用户定义节点的 C cniEvaluate 实现函数(CNI_VFT 的 iFpEvaluate 成员)之前跟踪到的消息。 例如:

      BIP3905(for C): Invoking the cniEvaluate() implementation function of node (class=[node class name], name=[label of node in flow])其中 node class name 是用户定义的扩展类的名称,由用户定义的扩展在调用 C cniDefineNodeClass 时提供。

    • BIP4142:调用用户定义节点实用程序函数时跟踪到的调试消息,其中实用程序函数会改变语法元素的状态。 这包含所有以 cniSetElement* 开头的实用程序函数,其中 * 表示带有该词干的所有节点。 例如:

      BIP4142Evaluating cniSetElement [element identifier type]. Changing value from [value before user's change] to [value after user's change]"

    • BIP4144BIP4145:由某些实现函数跟踪到的一对消息,当这些实现函数由用户定义扩展调用时,它们可以修改集成节点对象的内部状态。 可能的集成节点对象包含语法元素、节点和解析器。 这些消息会报告提供给调用方法和返回值的输入参数。 例如:

      BIP4144Entered function [function name] ([function call parameters])

      BIP4145Exiting function [function name] with result: [result to be returned]

      在这些消息中,可以将 实现函数 解释为 C 实现函数或 Java 实现方法。

      调用消息 BIP4144BIP4145 的 C 实现函数包含:

      对于用户定义解析器 对于用户定义节点
      cpiCreateParserFactory cniCreateElement*
      cpiDefineParserClass cniDeleteMessage
      cpiAppendToBuffer cniAdd*
      cpiCreateElement cniDetach
      cpiCreateAndInitializeElement cniCopyElementTree
      cpiAddBefore cniFinalize
      cpiAddAfter cniWriteBuffer
      cpiAddAsFirstChild cniSql*
      cpiAddAsLastChild cniSetInputBuffer
      cpiSetNameFromBuffer cniDispatchThread

      (* 表示带有该词干的所有节点;例如,cniAdd* 包含 cniAddAfter、cniAddasFirstChild、cniAddasLastChild 和 cniAddBefore。)

      调用消息 BIP4144BIP4145 的 Java 方法包括:

      对于用户定义节点
      com.ibm.broker.plugin.MbElement.CreateElement*
      com.ibm.broker.plugin.MbElement.add*
      com.ibm.broker.plugin.MbElement.detach
      com.ibm.broker.plugin.MbElement.copyElementTree
    • BIP4146:调用用户定义解析器实用程序函数时跟踪到的调试消息,其中实用程序函数会改变语法元素的状态。 这包含所有以 cpiSetElement* 开头的实用程序函数,其中 * 表示带有该词干的所有节点。 例如:

      BIP4146Evaluating cpiSetElement [element identifier type]. Changing value from [value before user's change] to [value after user's change]

      有关 C 用户定义的 API 的信息,请参阅 C 语言用户定义的解析器 APIC 语言用户定义的节点 API

    • BIP4147:用户定义扩展将无效的输入对象传递至用户定义扩展实用程序 API 函数时跟踪到的错误消息。 例如:

      BIP4147User-defined extension input parameter failed debug validation check. Input parameter [parameter name] passed into function [function name] is not a valid object.

    • BIP4148:用户定义扩展破坏集成节点对象时跟踪到的错误消息。 例如:

      BIP4148User-defined extension damaged an integration node object. Function [function name] has damaged integration node object passed as parameter [parameter name].

    • BIP4149:用户定义扩展将无效的输入数据指针传递至用户定义扩展实用程序 API 函数时跟踪到的错误消息。 例如:

      BIP4149User-defined extension input parameter failed debug validation check. Input parameter [parameter name] passed into function [function name] is a NULL pointer.

    • BIP4150:用户定义扩展将无效的输入数据传递至用户定义扩展实用程序 API 函数时跟踪到的错误消息。 例如:

      BIP4150User-defined extension input parameter failed debug validation check. Input parameter [parameter name] passed into function [function name] does not have a valid value.

    • BIP4151cniGetAttribute2cniGetAttributeName2 将返回码设置为意外值时跟踪到的调试消息。 期待获取的值为 CCI_SUCCESS、CCI_ATTRIBUTE_UNKNOWN 和 CCI_BUFFER_TOO_SMALL。 除此以外的任何其他值均为意外值。 例如:

      BIP4151An unexpected value was returned from User-defined extension implementation function [function name].

    • BIP4152:在以下情况下跟踪到的调试消息:cniGetAttribute2cniGetAttributeName2 将返回码设置为 CCI_BUFFER_TOO_SMALL,然后再次调用 cniGetAttribute2cniGetAttributeName2,但这次是用正确大小的缓冲区进行调用,然而返回码仍设置为 CCI_BUFFER_TOO_SMALL。 例如:

      BIP4152User-defined extension Implementation function [function name] returned CCI_BUFFER_TOO_SMALL on 2nd attempt.

您想调试类装入

过程

  • 场景: 您要调试类装入。
  • 解决方案: 将类以及从中装入类的位置写入用户跟踪。 使用该信息以检查是否正在装入正确的类。

Linux 上部署用户定义扩展时发生错误

过程

  • 场景: Linux® 上部署用户定义扩展时,会在每个集成服务器的日志中显示错误,说明没有足够的权限来打开 LIL 文件。
  • 说明: Linux 上,用户定义的扩展必须具有组读许可权。
  • 解决方案:
    Linux 上,通过发出命令 chmod a+r 将用户定义扩展的文件许可权设置为组读取

启动时,无法确定集成节点已装入哪些用户定义扩展

过程

  • 场景: 无法确定集成节点在启动时已装入哪些用户定义扩展。
  • 解决方案: 对每种类型的用户定义扩展使用 mqsireportproperties 命令。
    • 对于 Java 用户定义扩展,请发出以下命令:
      mqsireportproperties INODE -e default -o ComIbmJavaPluginNodeFactory -r

      您会看到类似于本示例的报告:

      ComIbmJavaPluginNodeFactory
      	uuid='ComIbmJavaPluginNodeFactory'
      	userTraceLevel='none'
      	traceLevel='none'
      	userTraceFilter='none'
      	traceFilter='none'
      	NodeClassName='ComIbmJMSClientInputNode'
      	NodeClassName='ComIbmJMSClientOutputNode'
      	NodeClassName='ComIbmJavaComputeNode'
      	NodeClassName='ComIbmXslMqsiNode'
      	NodeClassName='SearchFilterNode'
      
      BIP8071I: Successful command completion.

      称为 SearchFilter 的用户定义扩展的 NodeClassName 为 SearchFilterNode。

    • 对于用户定义的 C 扩展(假定在 NodeFactory.h 文件中,CONST_PLUGIN_NODE_FACTORY 设置为 ComIbmSamplePluginNodeFactory,如在样本 NumComputeNode 中设置的那样),请发出以下命令:
      mqsireportproperties INODE -e default -o ComIbmSamplePluginNodeFactory -r
      
      

      您会看到类似于本示例的报告:

      ComIbmSamplePluginNodeFactory
      	uuid='ComIbmSamplePluginNodeFactory'
      	userTraceLevel='none'
      	traceLevel='none'
      	userTraceFilter='none'
      	traceFilter='none'
      	NodeClassName='NumComputeNode'
      	
      BIP8071I: Successful command completion.

      称为 NumCompute 的用户定义扩展的 NodeClassName 为 NumComputeNode。

在迁移用户定义 C 节点时,cniDefineNodeClass 返回 CCI_INV_IMPL_FUNCTION

过程

  • 场景: 尝试迁移 C 用户定义节点时, cniDefineNodeClass 会返回 CCI_INV_IMPL_FUNCTION。
  • 说明: 已向 CNI_VFT 结构添加新字段。 CNI_VFT_DEFAULT 已更新为在 头文件 BipCci.h 中初始化这些新字段。 如果使用 CNI_VFT_DEFAULT 初始化 CNI_VFT,那么不需要进行任何代码更改。 但是,如果不使用 CNI_VFT_DEFAULT 对 CNI_VFT 进行初始化,则这些新字段会使用随机值进行初始化。
  • 解决方案: 使用 CNI_VFT_DEFAULT 初始化 CNI_VFT。