多行规则执行器

通常需要构建多行规则以计算属性的期望值。 IBM® Verify 支持配置简单的单行规则和更复杂的多行规则。

有关单行语法规则,请参阅 “属性函数 ”。

多行规则的元素

以 YAML 格式撰写多行规则。 其受 YAML 文档的格式化需求所约束。 使用的 YAML 解析器支持大多数 YAML 1.1 和 1.2。

重要的是了解以下术语。
语句
语句是规则构建块且可以是不同类型。 例如,return 语句计算提供的表达式并将表达式返回为规则值。
阻止
块是语句的限定集合。 规则从名为 statements 的顶级块开始。 块可以存在于特定语句类型中。 例如,if.block 是要在对应的 if.match 语句求值为 true 时执行的语句的集合。
块上下文
块上下文是此块中提供的变量的集合。 子块可访问父块的上下文。 父块无法访问子块的上下文。
表达式
表达式是使用与单行表达式相同语法的片段。 参见 “属性函数 ”。

受支持的语句类型

支持三种类型的语句。
  • 上下文
  • 退货
  • If

Context 语句

context 语句用于初始化并将值分配给指定的变量。 其支持两个操作。
:=
此运算符用于初始化评估语句的上下文块中的新变量。 例如,如果在 if.block 中初始化变量,因此在此块的后续语句中不可用。
=
此运算符用于将值分配给现有变量。 变量可存在于当前上下文块或父块中。
格式为 context: {{varname}} := {{expression}}。 使用 context.{{varname}} 以访问相同块或子块的后续语句中的 {{varname}}

Return 语句

Return 语句用于指示规则引擎结束执行并立即返回计算的值。

格式为 return: {{expression}}

If 语句

if 语句用于构建条件块。 其包含多个属性,与先前两个语句不同。

表1。
名称 描述 格式
match 如果此条件求值为 true,那么将执行对应的 block match: 1 == 2
block match 求值为 true 时必须执行的限定的语句块。 语句的标准 YAML 数组
elsifs match 未能求值为 true 时评估的 else-if 条件的数组。 作为嵌套 if 语句的 YAML 数组
else match 和所有 elseifs.match 未能求值为 true 时执行的语句块。 语句的 YAML 数组

跟踪日志记录

可以在多行规则中添加跟踪日志功能,以便发送调试日志。 如果规则在启用跟踪模式的情况下执行,则会执行跟踪日志属性。 通过 和 debugx 属性支持跟踪日志记录 debug

debug 语句

debug 语句用于指示执行所提供的表达式,并记录返回的值。 该表达式应始终求值为字符串。

格式 - debug: {{expression}}

debugx 阻止

fieldsdebugx 区块包含两个属性: log 和。

名称 描述 格式
日志 对给定的表达式进行求值,并将返回的值记录下来。 该表达式应始终求值为字符串。 log: {{expression}}
字段 随日志一起发送的自定义元数据字段。 以键值对数组的形式提供。 每对数据的值都是一个表达式,其计算结果必须为字符串。 {{field_key}}: {{expression}}

请参阅该章节 ,其中提供了一个演示跟踪日志记录的示例函数。

片段

此片段列表不详尽并且不涵盖所有可能的规则使用。 但是,此列表提供一些可使用或者可扩展的样本。

注意: 由于多行语法遵循 格式 YAML ,正确的缩进对于自定义规则的正常运行至关重要。

获取经理的显示名称

statements:
  - context: manager := user.getManager()
  - context: userExists := has(context.manager.name)
  - context: >
      givenNameExists := context.userExists
      && has(context.manager.name.givenName) 
      && context.manager.name.givenName != ""
  - context: familyNameExists := context.userExists && has(context.manager.name.familyName) && context.manager.name.familyName != ""
  - context: formattedExists := context.userExists && has(context.manager.name.formatted) && context.manager.name.formatted != ""
  - if:
      match: context.formattedExists
      block:
        - return: context.manager.name.formatted
      elseifs:
        - match: context.givenNameExists
          block:
            - if:
                match: context.familyNameExists
                block:
                  - context: managerName := context.manager.name.familyName + ", " + context.manager.name.givenName
                  - return: context.managerName
                else:
                  - return: context.manager.name.givenName
        - match: context.familyNameExists
          block:
            - return: context.manager.name.familyName
- return: string("Not Available")

转换电子邮件域

statements:
  - context: "workEmails := has(user.emails) ? user.emails.filter(e, e.type == 'work') : []"
  - context: "workEmail := size(context.workEmails) > 0 ? context.workEmails[0].value : ''"
  - if:
      match: context.workEmail != ""
      block:
        - context: cn := context.workEmail.substring(0, context.workEmail.lastIndexOf('@'))
        - if:
            match: context.cn != ""
            block:
              - return: context.cn + "@github.com"
  - return: ""

变量的作用域限定

statements:
    - context: ret := 3 + 4
    - if:
        match: 2 > 1block:
          - context: ret := 5
          - if:
              match: 3 > 2block:
                - context: ret = 0
    - return: context.ret

结果是 7。 if.block出现这种结果是因为第6行在 内重新初始化 ret 了。 后续嵌套语句都会看到此变量。 但是,在规则引擎退出 if.block 后,它可以访问在第 2 行已初始化的变量。

跟踪日志示例

此示例演示了如何使用跟踪日志语句。

statements:
  - context: uid := user.id
  - context: userEmail := "user@test.com"
  - debug: '"This is an example of a trace log at time " + string(now)'
  - debugx: 
      log: '"The user id obtained: " + context.uid'
      fields:
          flow: '"login"'
          time: 'string(now)'
          userEmail: context.userEmail
  - return: context.uid  + ", " + context.userEmail

对于该 debug 语句,系统将对提供的表达式进行求值,并将其记录为 "This is an example of a trace log at time <timestamp>"

对于该 debugx 块,提供的表达式将被求值并记录为 "The user id obtained: <user id>"。 以下自定义元数据字段将随日志一并发送。
"flow" "login"
"time" "<timestamp>"
"userEmail" "user@test.com"

重要限制

  • context 框架初始化的变量只能存在于该框架内或其子框架内。 在先前规则示例中,变量 managerName 在其初始化所在的 if 框架之外不可访问。
  • 仅当 if 框架处于相同级别时,才能使用 elseifselse 框架。
  • 所有 ifelseifs 框架必须具有一个始终返回布尔值的 match 表达式。
  • 如果规则评估流程未遇到 return 语句,那么返回空值。 没有抛出错误,也没有执行语法检查以确保所有可能的流程都具有 return。 规则的作者必须确保规则的所有流程都返回一个可接受的值。