使用通用表达式语言

通用表达式语言 (CEL) 是一种开源的非图灵完备语言,可用于对表达式求值。Eventarc Advanced 中的每项注册都包含一个用 CEL 编写的条件表达式,用于评估和过滤消息。您还可以使用 CEL 编写转换表达式,从而转换您的事件数据内容。

通常,条件表达式由一个或多个使用逻辑运算符(&&||!)联接的语句组成。每个语句表示一条适用于数据且基于属性的规则。通常,运算符用于比较变量中包含的值和字面量值。

例如,如果 message.type 的值为 google.cloud.dataflow.job.v1beta3.statusChanged,则表达式 message.type == "google.cloud.dataflow.job.v1beta3.statusChanged" 的求值结果为 True

详情请参阅以下内容:

可用的属性

您可以通过预定义的 message 对象以变量形式访问所有事件上下文属性。这些变量会根据运行时的事件上下文属性填充值。注册可以使用变量来表示给定属性。例如,message.type 会返回 type 属性的值。

请注意以下几点:

  • 事件可能会包含(注册可以使用)任意数量具有不同名称的自定义 CloudEvents 属性(也称为扩展属性)。不过,无论其实际格式如何,它们在 CEL 表达式中都表示为 String 类型。您可以使用 CEL 表达式将其值转换为其他类型。

  • 您无法根据事件载荷内容评估注册情况。message.datamessage.data_base64 都是预留变量,不能在表达式中使用。不过,在转换事件数据时,系统支持 CEL,这样您就可以修改事件载荷内容(例如,以满足特定目标位置的 API 合约)。

在评估注册的条件表达式时,可以访问以下属性:

属性 特性类型 说明
message.datacontenttype String data 值的内容类型
message.dataschema URI 标识 data 遵循的架构
message.id String 标识事件。生产者必须确保对于每个不同的事件,source + id 都是唯一的。
message.source URI-reference 标识事件发生的上下文
message.specversion String 事件使用的 CloudEvents 规范版本
message.subject String 描述事件生产者(通过 source 标识)上下文中的事件主题
message.time Timestamp 发生时间戳;可能会由 CloudEvents 生产方设置为其他时间(例如当前时间);不过,对于同一 source,所有生产方的时间戳都必须一致
message.type String 描述与起始发生实例相关的事件类型

运算符和函数

您可以使用运算符和函数构建复杂的逻辑表达式。

借助逻辑运算符(例如 &&||,!),您可以在条件表达式中验证多个变量。例如,message.time.getFullYear() < 2020 && message.type == "google.cloud.dataflow.job.v1beta3.statusChanged" 连接了两个语句,而且必须同时满足这两个语句,才能生成总体计算结果 TrueTrue

字符串操作运算符(例如 x.contains('y'))可匹配您定义的字符串或子字符串,让您能够制定规则来匹配消息,而无需列出所有可能的组合。

Eventarc Advanced 还支持扩展函数(例如 mergeflatten),可用于转换数据,并简化对从总线接收的事件的修改。

请参阅 CEL 预定义运算符和函数以及 CEL 预定义宏列表。

逻辑运算符

下表介绍了 Eventarc Advanced 支持的逻辑运算符。

表达式 说明
x == "my_string" 如果 x 等于常量字符串字面量参数,则返回 True
x == R"my_string\n" 如果 x 等于不解释转义序列的指定原始字符串字面量,则返回 True。原始字符串字面量便于表示自己必须使用转义序列的字符串,例如正则表达式或程序文本。
x == y 如果 x 等于 y,则返回 True
x != y 如果 x 不等于 y,则返回 True
x && y 如果 xy 均为 True,则返回 True
x || y 如果 xy 或两者均为 True,则返回 True
!x 如果布尔值 xFalse,则返回 True;如果布尔值 xTrue,则返回 False
m['k'] 如果存在键 k,则返回字符串到字符串映射 m 中的键 k 处的值。如果不存在键 k,则返回导致评估中的规则不匹配的错误。

字符串操作运算符

下表介绍了 Eventarc Advanced 支持的字符串操作运算符。

表达式 说明
double(x) 将字符串结果 x 转换为 double 类型。转换后的字符串可用于使用标准算术运算符(例如 ><=)比较浮点数。此方法仅适用于可以是浮点数的值。
int(x) 将字符串结果 x 转换为 int 类型。转换后的字符串可用于使用标准算术运算符(例如 ><=)比较整数。这仅适用于可以是整数的值。
x + y 返回串联的字符串 xy
x.contains(y) 如果字符串 x 包含子字符串 y,则返回 True
x.endsWith(y) 如果字符串 x 以子字符串 y 结尾,则返回 True
x.join() 返回一个新字符串,其中串联了字符串列表的元素。接受可选的分隔符,该分隔符会放置在生成的字符串中的元素之间。例如,以下表达式会返回 'hello world'

['hello', 'world'].join(' ')

x.lowerAscii() 返回一个新字符串,其中所有 ASCII 字符均为小写。
x.matches(y)

如果字符串 x 与指定的 RE2 模式 y 匹配,则返回 True

RE2 模式在编译时使用了已停用 Unicode 功能的 RE2::Latin1 选项。

x.replace(y,z) 返回一个新字符串,其中子字符串 y 的出现次数被子字符串 z 替换。接受一个可选参数,用于限制要进行的替换次数。例如,以下表达式会返回 'wello hello'

'hello hello'.replace('he', 'we', 1)

x.split(y) 返回按分隔符 y 从输入中拆分出的字符串列表。接受一个可选参数,用于限制要生成的子字符串的数量。例如,以下表达式会返回 ['hello', 'hello hello']

'hello hello hello'.split(' ', 2)

x.startsWith(y) 如果字符串 x 以子字符串 y 开头,则返回 True
x.upperAscii() 返回一个新字符串,其中所有 ASCII 字符均为大写。

正则表达式函数

下表介绍了 Eventarc Advanced 支持的正则表达式函数。

表达式 说明
re.capture(target,regex)

使用 regex 捕获 target 字符串中的第一个未命名或命名组值,并返回一个字符串。例如,以下表达式会返回 "o"

re.capture("hello", R"hell(o)")

re.captureN(target,regex) 使用 regextarget 字符串中捕获组名称和字符串(对于命名组)以及组索引和字符串(对于未命名组),并返回键值对的映射。例如,以下表达式会返回 {"1": "user", "Username": "testuser", "Domain": "testdomain"}

re.captureN("The user testuser belongs to testdomain", R"The (user|domain) (?P.*) belongs to (?P.*)")

re.extract(target,regex,rewrite) 使用 regextarget 字符串中提取匹配的组值,并返回一个字符串,其中包含根据 rewrite 参数设置格式的提取值。例如,以下表达式会返回 "example.com"

re.extract("alex@example.com", "(^.*@)(.*)", "\\2")

x.matches(regex)

如果字符串 x 与指定的 RE2 模式 regex 匹配,则返回 True

RE2 模式在编译时使用了已停用 Unicode 功能的 RE2::Latin1 选项。

正则表达式遵循 RE2 语法。请注意,正则表达式前面的 R 表示不需要转义的原始字符串。

扩展函数

Eventarc Advanced 支持某些扩展函数,可用于转换通过总线接收的事件数据。如需了解详情和示例,请参阅转换收到的事件

后续步骤