FlowFile的属性在整个数据流中非常重要,因为在对数据流进行处理时,经常会用到FlowFile的属性,这为数据流处理提供了很大的便利性。
(以下内容译自NiFi官方文档 working-with-attributes)
每个FlowFile被创建时,都会带有几个属性(Attributes),这些属性将在FlowFile的生命周期内发生变化。FlowFile的概念非常强大,并提供三个主要优点。
首先,它允许用户在流中做出路由决策,以便满足某些条件的FlowFiles可以与其他FlowFiles不同地进行处理。这是使用RouteOnAttribute和类似的处理器完成的。
其次,使用属性以便以这样的方式配置处理器:处理器的配置依赖于数据本身。例如,PutFile处理器能够使用Attributes来知道每个FlowFile的存储位置,而每个FlowFile的目录和文件名属性可能不同。
最后,属性提供了有关数据的极有价值的上下文。在查看FlowFile的Provenance数据时,这非常有用。这允许用户搜索符合特定条件的Provenance数据,并且还允许用户在检查Provenance事件的详细信息时查看此上下文。通过这样做,用户然后能够获得关于为什么以这样或那样的方式处理数据的有价值的见解,简单地通过浏览与内容一起携带的该上下文。
共同属性
每个FlowFile都有一组最小的属性:
- filename:可用于将数据存储到本地或远程文件系统的文件名。
- path:可用于将数据存储到本地或远程文件系统的目录的名称。
- uuid:一个通用唯一标识符,用于区分FlowFile与系统中的其他FlowFiles。
- entryDate:FlowFile进入系统的日期和时间(即创建)。此属性的值是一个数字,表示自1970年1月1日午夜(UTC)以来的毫秒数。
- lineageStartDate:任何时候克隆,合并或拆分FlowFile,都会导致创建“子”FlowFile。随着这些孩子被克隆,合并或分裂,建立了一系列祖先。此值表示最早的祖先进入系统的日期和时间。另一种思考方式是,此属性表示FlowFile通过系统的延迟。该值是一个数字,表示自1970年1月1日午夜(UTC)以来的毫秒数。
- fileSize:此属性表示FlowFile内容占用的字节数。
需要注意的是uuid
,entryDate
,lineageStartDate
,和fileSize
属性是系统生成的,不能改变。
提取属性
NiFi提供了几种不同的处理器,用于从FlowFiles中提取属性。可以在“属性提取”部分中找到用于此目的的常用处理器列表。这是构建自定义处理器的一个非常常见的用例。编写许多处理器是为了理解特定的数据格式并从FlowFile的内容中提取相关信息,创建属性来保存该信息,以便可以决定如何路由或处理数据。
添加用户定义的属性
除了能够将特定信息片段从FlowFile内容提取到属性中的处理器之外,用户还希望将自己的用户定义属性添加到流中特定位置的每个FlowFile。UpdateAttribute Processor专为此目的而设计。用户可以通过单击“属性”选项卡右上角的“+”按钮,在“配置”对话框中向处理器添加新属性。然后提示用户输入属性的名称,然后输入值。对于此UpdateAttribute Processor处理的每个FlowFile,将为每个用户定义的属性添加一个Attribute。Attribute的名称将与添加的属性的名称相同。
该属性的值也可以包含表达式语言。这允许基于其他属性修改或添加属性。例如,如果我们想要将正在处理文件的主机名和日期添加到文件名,我们可以通过添加名称filename
和值的属性来实现${hostname()}-${now():format('yyyy-dd-MM')}-${filename}
。虽然这可能看起来有点令人困惑,但下面关于表达式语言/在属性值中使用Attributes将有助于清理这里发生的事情。
除了始终添加一组已定义的属性外,UpdateAttribute Processor还具有一个高级UI,允许用户配置一组规则,以便在何时添加属性。要访问此功能,请在“配置”对话框的“属性”选项卡中,单击Advanced
对话框底部的按钮。这将提供专门为此处理器定制的UI,而不是为所有处理器提供的简单属性表。在此UI中,用户能够配置规则引擎,实质上是指定必须匹配的规则,以便将已配置的属性添加到FlowFile。
属性路由
NiFi最强大的功能之一是能够根据属性路由FlowFiles。执行此操作的主要机制是RouteOnAttribute Processor。此处理器与UpdateAttribute一样,通过添加用户定义的属性进行配置。通过单击处理器的“配置”对话框中“属性”选项卡右上角的“+”按钮,可以添加任意数量的属性。
每个FlowFile的属性将与配置的属性进行比较,以确定FlowFile是否满足指定的条件。每个属性的值应该是一个表达式语言表达式并返回一个布尔值。有关表达式语言的更多信息,请参阅下面的表达式语言/在属性值中使用Attributes部分。
在评估针对FlowFile的属性提供的表达式语言表达式之后,处理器根据所选的路由策略确定如何路由FlowFile。最常见的策略是“Route to Property name”策略。选择此策略后,处理器将为配置的每个属性公开Relationship。如果FlowFile的属性满足给定的表达式,则FlowFile的副本将路由到相应的Relationship。例如,如果我们有一个名为“begin-with-r”的新属性和值“${filename:startsWith(‘r’)}”,那么任何文件名以字母’r’开头的FlowFile将是路由到那个关系。所有其他FlowFiles将被路由到“unmatched”。
表达式语言/在属性值中使用Attributes
当我们从FlowFiles的内容中提取属性并添加用户定义的属性时,除非我们有一些可以使用它们的机制,否则它们不会作为运算符做得很好。NiFi表达式语言允许我们在配置流时访问和操作FlowFile属性值。并非所有处理器属性都允许使用表达式语言,但很多都可以。为了确定属性是否支持表达式语言,用户可以将鼠标悬停在“处理器配置”对话框的“属性”选项卡中的“帮助”图标([外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-teAe98hN-1588594735092)(https://nifi.apache.org/docs/nifi-docs/html/images/iconInfo.png)] )上。这将提供一个工具提示,显示属性的描述,默认值(如果有)以及属性是否支持表达式语言。
对于支持表达式语言的属性,可以通过在开始${
标记和结束 }
标记中添加表达式来使用它。表达式可以像属性名一样简单。例如,要引用uuid
Attribute,我们可以简单地使用该值${uuid}
。如果属性名称以字母以外的任何字符开头,或者如果它包含数字,字母,句点(.)或下划线(_)以外的字符,则属性名称需要被引用。例如,${My Attribute Name}
将无效,但${'My Attribute Name'}
将引用属性My Attribute Name
。
除了引用属性值之外,我们还可以对这些属性执行许多功能和比较。例如,如果我们想检查filename
属性是否包含字母’r’而不注意大小写(大写或小写),我们可以通过使用表达式来完成${filename:toLower():contains('r')}
。请注意,函数由冒号分隔。我们可以将任意数量的函数链接在一起,以构建更复杂的表达式。同样重要的是要明白,即使我们正在调用filename:toLower()
,这也不会改变filename
属性的值,而只是给我们一个新的价值。
我们也可以在另一个表达式中嵌入一个表达式 例如,如果我们想要将attr1
Attribute 的值与attr2
Attribute的值进行比较,我们可以使用以下表达式来执行此操作:${attr1:equals( ${attr2} )}
。
表达式语言包含许多不同的函数,可用于执行路由和操作属性所需的任务。存在用于解析和操作字符串,比较字符串和数值,操纵和替换值以及比较值的函数。对可用的不同功能的完整解释超出了本文档的范围,但“ 表达式语言指南”为每个功能提供了更多详细信息。
此外,此表达式语言指南内置于应用程序中,以便用户能够轻松查看哪些功能可用,并在键入时查看其文档。设置支持表达式语言的属性的值时,如果光标位于表达式语言的开始和结束标记内,则在关键字上按Ctrl + Space将弹出所有可用的函数,并将提供自动 - 完整的功能。单击或使用键盘导航到弹出窗口中列出的某个功能将导致显示工具提示,这解释了该功能的作用,它所期望的参数以及函数的返回类型。