【NIFI】 Apache NiFI 之 ExecuteScript处理(二)
本例介绍NiFI ExecuteScript处理器的使用,使用的脚本引擎ECMScript
接上一篇【NIFI】 Apache NiFI 之 ExecuteScript处理(一)
ExecuteScript使用
1、动态属性
其中一个功能是动态属性的概念,也称为用户定义属性。这些是处理器的属性,用户可以为其设置属性名称和值。并非所有处理器都支持/使用动态属性,但ExecuteScript会将动态属性作为变量传递,这些变量引用与属性值对应的PropertyValue对象。这里有两件重要的事情需要注意:
- 由于属性名称按原样绑定到变量名称,因此必须为指定的编程语言支持动态属性的命名约定。例如,Groovy不支持句点(。)作为有效的变量字符,因此动态属性(如“my.value”)将导致处理器失败。在这种情况下,有效的替代方案是“myValue”。
- 使用PropertyValue对象(而不是值的String表示形式)以允许脚本在将属性值评估为String之前对属性的值执行各种操作。如果已知属性包含文字值,则可以对变量调用getValue()方法以获取其String表示形式。相反,如果值可能包含表达式语言,或者您希望将值转换为除String之外的值(例如对布尔对象的值为'true'),则还有这些操作的方法。这些示例在下面的配方中说明,假设我们有两个属性'myProperty1'和'myProperty2'定义如下:

目的:用户输入了动态属性以供脚本使用(例如,配置参数)。
方法:使用变量的PropertyValue对象中的getValue()方法。此方法返回动态属性值的String表示形式。请注意,如果值中存在表达式语言,则getValue()将不对其进行求值
Examples
Javascript
var myValue1 = myProperty1.getValue()
var myValue2 = myProperty2.evaluateAttributeExpressions(flowFile).getValue()
2、添加模块
ExecuteScript的另一个功能是能够向类路径添加外部“模块”,这允许您利用各种第三方库,脚本等。但是每个脚本引擎都以不同方式处理模块的概念,因此我将讨论它们分别。一般来说,有两种类型的模块,Java库(JAR)和脚本(用与ExecuteScript中相同的语言编写
配置如下:

目的:脚本执行时,使用Java库
方法:配置ExecuteScript,添加Module Directory目录(里面都是jar包),脚本中获取jar包中的类,使用jar包中的类方法
Examples
Javascript
var ObjectMapper = Java.type("com.fasterxml.jackson.databind.ObjectMapper");
var Map = Java.type("java.util.Map");
var objectMapper = new ObjectMapper();
// java对象转 json字符串
var str = objectMapper.writeValueAsString(obj);
// json字符串 转 java对象
var map = objectMapper.readValue(str, Map.class);
3、状态存储
NiFi(我相信0.5.0)为处理器和其他NiFi组件提供了持久保存一些信息的能力,以便在组件周围实现某些状态功能,例如,QueryDatabaseTable处理器跟踪它在指定列中看到的最大值,这样下次运行时,它只会获取其值大于目前已见过的行(即存储在州经理)。
NiFi组件可以选择将其状态存储在集群级别或本地级别。请注意,在独立的NiFi实例中,“群集范围”与“本地范围”相同。范围的选择通常是关于在流中,每个节点上的相同处理器是否可以共享状态数据。如果群集中的实例不需要共享状态,则使用本地范围。在Java中,这些选项作为名为Scope的枚举提供,因此当我引用Scope.CLUSTER和Scope.LOCAL时,我分别表示集群和本地作用域。
要在ExecuteScript中使用状态管理功能(下面是特定于语言的示例),您可以通过调用ProcessContext的getStateManager()方法获得对StateManager的引用(回想一下,每个引擎都获得一个名为“context”的变量,其中包含ProcessContext实例)。然后,您可以在StateManager对象上调用以下方法:
void setState(Map <String,String> state,Scope scope) - 更新组件在给定范围内的状态值,并将其设置为给定值。请注意,该值是一个Map; “组件状态”的概念是每个构成较低级别状态的所有键/值对的映射。Map会立即更新以提供原子性。
StateMap getState(作用域范围) - 返回给定范围内组件的当前状态。此方法永远不会返回null; 相反,它是一个StateMap对象,如果尚未设置状态,StateMap的版本将为-1,值的映射将为空。通常会创建一个新的Map <String,String>来存储更新的值,然后调用setState()或replace()。
boolean replace(StateMap oldValue,Map <String,String> newValue,Scope scope) - 当且仅当值与给定的oldValue相同时,才更新组件状态(在给定范围内)的值到新值。如果状态已更新为新值,则返回true; 否则,如果状态的值不等于oldValue,则返回false。
void clear(范围范围) - 清除给定范围内组件状态的所有键和值。
目的1:脚本需要从状态管理器获取当前键/值对以供脚本使用(例如,更新)
方法1:使用ProcessContext中的getStateManager()方法,然后使用StateManager中的getStateMap(),然后使用toMap()转换为键/值对的Map <String,String>。请注意,StateMap还有一个简单检索值的get(key)方法,但这种方法并不常用,因为Map通常会更新,一旦完成,就必须为StateManager设置。
Examples
Javascript
var Scope = Java.type('org.apache.nifi.components.state.Scope');
var oldMap = context.stateManager.getState(Scope.LOCAL).toMap();
目的2:脚本希望使用新的键/值对映射更新状态映射。
方法2:要获取当前StateMap对象,请再次使用ProcessContext中的getStateManager()方法,然后使用StateManager中的getStateMap()。这些示例假设一个新的Map,但使用上面的配方(使用toMap()方法),您可以使用现有值创建一个新的Map,然后只更新所需的条目。请注意,如果没有当前映射(即StateMap.getVersion()返回-1),则replace()将不起作用,因此示例将相应地检查并调用setState()或replace()。从新的ExecuteScript实例运行时,StateMap版本将为-1,因此在单次执行后,如果右键单击ExecuteScript处理器并选择View State,您应该看到如下内容:

Examples
Javascript
var Scope = Java.type('org.apache.nifi.components.state.Scope');
var stateManager = context.stateManager;
var stateMap = stateManager.getState(Scope.CLUSTER);
var newMap = {'myKey1': 'myValue1'};
if (stateMap.version == -1) {
stateManager.setState(newMap, Scope.CLUSTER);
} else {
stateManager.replace(stateMap, newMap, Scope.CLUSTER);
}
ExecuteScript-Demo
Demo流程:先存入缓存myKey1 =》 第二次取出myKey1的值 =》 myKey1的值修改 =》 再次存入缓存中
ExecuteScript内容如下:
var Scope = Java.type('org.apache.nifi.components.state.Scope');
var stateManager = context.stateManager;
var stateMap = stateManager.getState(Scope.CLUSTER);
if (stateMap.version == -1) {
var newMap = {'myKey1': "1"};
stateManager.setState(newMap, Scope.CLUSTER);
} else {
var myValue1 = stateMap.toMap().get("myKey1");
myValue1 = myValue1*1 + 1;
var newMap = {'myKey1': myValue1 + ""};
// 替换
stateManager.replace(stateMap, newMap, Scope.CLUSTER);
}
其他脚本引擎,参考以下地址
参考文档链接:https://community.hortonworks.com/articles/77739/executescript-cookbook-part-3.html
【NIFI】 Apache NiFI 之 ExecuteScript处理(二)的更多相关文章
- 【NIFI】 Apache NiFI 之 ExecuteScript处理(一)
本例介绍NiFI ExecuteScript处理器的使用,使用的脚本引擎ECMScript FlowFile I / O简介 NiFi中的流文件由两个主要组件构成,即属性和内容.属性是关于内容/流文件 ...
- Nifi组件脚本开发—ExecuteScript 使用指南(二)
Part 2 - FlowFile I/O 和 Error Handling flow File的IO NiFi 的 Flow files 由两个主要部件组成:attributes 和 content ...
- Nifi组件脚本开发—ExecuteScript 使用指南(三)
上一篇:Nifi组件脚本开发-ExecuteScript 使用指南(二) Part 3 - 高级特征 本系列的前两篇文章涵盖了 flow file 的基本操作, 如读写属性和内容, 以及使用" ...
- Apache Nifi在Windows环境下搭建伪群集及证书登录
代码地址如下:http://www.demodashi.com/demo/11986.html 前些时间做了关于Apache Nifi分布式集群的搭建分享,但很多时候要搭建分布式集群机器资源是个问题, ...
- 初识Apache NiFi
一. NiFi介绍 Apache NiFi支持功能强大且可扩展的数据路由,转换和系统中介逻辑的有向图. Apache NiFi的一些高级功能和目标包括: 基于Web的用户界面 设计,控制,反馈和监控之 ...
- 深入Apache NiFi 之源码学习
前言 要问 Hortonworks 这家公司最有产品力的产品是什么,我觉得是 Apache NiFi.去年Cloudera 和 Hortonworks 合并之后,以 Cloudera 为主,两家公司进 ...
- Nifi组件脚本开发—ExecuteScript 使用指南(一)
Part 1 - 介绍 NiFi API 和 FlowFiles ExecuteScript 是一个万能的处理器,允许用户使用编程语言定义自己的数据处理功能, 在每一次 ExecuteScript p ...
- 【NIFI】 Apache NiFI 使用技巧
本章介绍NIFI组件的使用. 主要有:Nginx反向代理NIFI,配置SSLContextService Nginx反向代理NIFI 使用nginx反向代理NIFI配置如下 upstream nifi ...
- 【NIFI】 Apache NiFI 授权配置
当NIFI未配置需要单向SSL(例如LDAP,OpenId Connect等)的替代认证机制时,NiFi的Web服务器将要求访问用户界面的用户使用基于证书的客户端身份验证.启用备用身份验证机制会将We ...
随机推荐
- windows下apache httpd2.4.26集群完整搭建例子:下载、启动、tomcat集群例子
第一部分——下载 1.1: 百度搜索apache httpd关键字,第一个链接既是官方下载地址.如果这一步不会,此篇文章不适合你阅读,请自行停止. 1.2:进入官网http://httpd.apach ...
- 2018-2019-2 20175227张雪莹 《Java程序设计》 实验一 Java开发环境的熟悉
2018-2019-2 20175227张雪莹<Java程序设计> 实验一 Java开发环境的熟悉 一.实验报告封面 课程:Java程序设计 班级:1752班 姓名:张雪莹 学号:2017 ...
- Python关于Pyqt
参考百度文摘地址: https://jingyan.baidu.com/article/a3761b2ba2b8581576f9aa98.html 1 首先进行安装Pyqt5 pip3 install ...
- sqlserver数据库镜像运行模式
运行模式: 从大层面来说,SQL Server镜像只有两种模式:高安全模式和高性能模式.两种模式的主要区别在于在事务提交后的操作.可以从图1-1中查看运行模式. 在高性能模式下,主体服务器不需要等待镜 ...
- 一入爬虫深似海,从此游戏是路人!总结我的python爬虫学习笔记!
前言 还记得是大学2年级的时候,偶然之间看到了学长在学习python:我就坐在旁边看他敲着代码,感觉很好奇.感觉很酷,从那之后,我就想和学长一样的厉害,就想让学长教我,请他吃了一周的饭,他答应了.从此 ...
- 为何要使用ViewModel
ViewModel类是用来存储和管理与UI相关的数据,在设计之初就考虑到生命周期的影响.ViewModel允许数据在屏幕旋转等配置变化后存活. Android framework管理UI控制器(如Ac ...
- vim移动一行或一段代码
nmap <M-j> mz:m+<cr>`z nmap <M-k> mz:m-2<cr>`z vmap <M-j> :m'>+< ...
- i386 x86_64 armv7 arm64
arm7: Used in the oldest iOS 7-supporting devices arm7s: As used in iPhone 5 and 5C arm64: For the 6 ...
- SpringCloud-day01-简介
1.spring cloud简介 Spring Cloud是一系列框架的有序集合.它利用Spring Boot的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册.配置中心.消息总线.负载 ...
- Mysql添加新用户遇到的一些小问题
登陆命令:mysql -u root -p 添加本地用户:create user 'sheet'@'localhost' identified by '123456' ; 添加允许外网IP访问的用户 ...