【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 ...
随机推荐
- 前端-JavaScript1-6——JavaScript之变量类型的转换
6.1 string → number 先来学习一个语句,这个语句和alert差不多,也是弹窗,弹的是输入框: 1 prompt("请输入你的电话","139&qu ...
- 初始nginx(启动运行) 使用nginx做一个简单的静态资源服务器
第一次接触nginx的时候,那时候公司还是用的一些不知名的小技术,后来公司发展问题,重新招了人,然后接触到nginx,公司 使用nginx用来做代理服务器,所有请求 都先经过nginx服务器,然后交由 ...
- html/css/js-横向滚动条的实现
在前端UI设计时,网页的制作很麻烦,深有感悟!碰到太多的不懂,或是第一次见,就要去网上找资料!横向滚动条就是我遇到麻烦中其中的一个,其实也 很简单,只是在几次项目中都用到了这个横向滚动条所以就拿出来说 ...
- C语言的基础输入输出
首先来整理一下各个数据类型的输入输出格式: 1.char %c 2.int/short int %d 3.long int %ld 4.long long int %lld 5.float %f 6. ...
- leetcode301
class Solution { public List<String> removeInvalidParentheses(String s) { List<String> a ...
- Spring用了哪些设计模式
单例:只产生一个对象,共享对象的资源: 多例:产生多个对象,对象资源没有联系:(action) 在ssm框架中 service层.dao层.controller层都是默认使用单例模式,只会产生唯一 一 ...
- JPA中建立数据库表和实体间映射小结
在JPA中,映射数据库表和实体的时候,需要注意一些细节如下, 实体类要用@Entity的注解: 要用 @Id 来注解一个主键: 如果跟数据库相关联,要用@Table注解相关数据库表: 实体类中字段需要 ...
- springboot 启动脚本
#!/bin/bash cd `` data_dir=`pwd` JAVA_HOME=/usr/local/jdk1..0_92 logs_dir=$data_dir/logs if [ ! -d $ ...
- Delphi TXLSReadWriteII2 带的demo中直接编辑XLS文件的例子
unit Unit1; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, ...
- 微探eventlet.monkey_patch
e ventlet.monkey_patch在运行时动态修改已有的代码,而不需要修改原始代码 在eventlet.monkey_patch中支持以下几种python原生库修改 eventlet.mon ...