使用通用表达式语言

通用表达式语言 (CEL) 是一种开源的非图灵完备语言,可用于对表达式求值。Eventarc 高级版中的每个注册都包含一个以 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" 连接了两个语句,要想生成总体结果 True,需要同时满足这两个语句(即这两个语句均为 True)。

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

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

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

逻辑运算符

下表介绍了 Eventarc 高级版支持的逻辑运算符。

表达式 说明
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 高级版支持的字符串操作运算符。

表达式 说明
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 高级版支持的正则表达式函数。

表达式 说明
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 支持某些扩展函数,这些函数可用于转换通过总线接收的事件数据。如需了解详情和示例,请参阅转换已接收事件

后续步骤