本例介绍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处理(二)的更多相关文章

  1. 【NIFI】 Apache NiFI 之 ExecuteScript处理(一)

    本例介绍NiFI ExecuteScript处理器的使用,使用的脚本引擎ECMScript FlowFile I / O简介 NiFi中的流文件由两个主要组件构成,即属性和内容.属性是关于内容/流文件 ...

  2. Nifi组件脚本开发—ExecuteScript 使用指南(二)

    Part 2 - FlowFile I/O 和 Error Handling flow File的IO NiFi 的 Flow files 由两个主要部件组成:attributes 和 content ...

  3. Nifi组件脚本开发—ExecuteScript 使用指南(三)

    上一篇:Nifi组件脚本开发-ExecuteScript 使用指南(二) Part 3 - 高级特征 本系列的前两篇文章涵盖了 flow file 的基本操作, 如读写属性和内容, 以及使用" ...

  4. Apache Nifi在Windows环境下搭建伪群集及证书登录

    代码地址如下:http://www.demodashi.com/demo/11986.html 前些时间做了关于Apache Nifi分布式集群的搭建分享,但很多时候要搭建分布式集群机器资源是个问题, ...

  5. 初识Apache NiFi

    一. NiFi介绍 Apache NiFi支持功能强大且可扩展的数据路由,转换和系统中介逻辑的有向图. Apache NiFi的一些高级功能和目标包括: 基于Web的用户界面 设计,控制,反馈和监控之 ...

  6. 深入Apache NiFi 之源码学习

    前言 要问 Hortonworks 这家公司最有产品力的产品是什么,我觉得是 Apache NiFi.去年Cloudera 和 Hortonworks 合并之后,以 Cloudera 为主,两家公司进 ...

  7. Nifi组件脚本开发—ExecuteScript 使用指南(一)

    Part 1 - 介绍 NiFi API 和 FlowFiles ExecuteScript 是一个万能的处理器,允许用户使用编程语言定义自己的数据处理功能, 在每一次 ExecuteScript p ...

  8. 【NIFI】 Apache NiFI 使用技巧

    本章介绍NIFI组件的使用. 主要有:Nginx反向代理NIFI,配置SSLContextService Nginx反向代理NIFI 使用nginx反向代理NIFI配置如下 upstream nifi ...

  9. 【NIFI】 Apache NiFI 授权配置

    当NIFI未配置需要单向SSL(例如LDAP,OpenId Connect等)的替代认证机制时,NiFi的Web服务器将要求访问用户界面的用户使用基于证书的客户端身份验证.启用备用身份验证机制会将We ...

随机推荐

  1. 采用ddt 可以把ddt获取的数据 塞进测试用例里面的备注里面去展示 (还没有试)

  2. NodeJS对象数组Array 根据对象object key的值排序sort

    有个js对象数组 var ary=[{id:1,name:”b”},{id:2,name:”b”}] 需求是根据name 或者 id的值来排序,这里有个风骚的函数. /** * 对数组中的对象,按对象 ...

  3. 使用jquery+css实现瀑布流布局

    虽然可以直接使用css实现瀑布流布局,但显示的方式有点问题,所以这儿就直接使用jquery+css来实现瀑布流布局,最终效果如下:      思路是通过将每个小块的position设置为relativ ...

  4. oninput、onchange与onpropertychange事件的区别, 与input输入框实时检测

    这几天项目着急,同时也学到好多以前没有接触过的知识.oninput.onchange与onpropertychange事件的区别, 与input输入框实时检测 onchange事件只在键盘或者鼠标操作 ...

  5. 201. Spring Boot JNDI:Spring Boot中怎么玩JNDI

      [视频&交流平台] àSpringBoot视频:http://t.cn/R3QepWG à SpringCloud视频:http://t.cn/R3QeRZc à Spring Boot源 ...

  6. Rabbitmq(6) 主题模式

    * 匹配1个 # 匹配所有 发送者: package com.aynu.bootamqp.service; import com.aynu.bootamqp.commons.utils.Amqp; i ...

  7. ReactiveX 学习笔记(21)使用 Rx.NET + ReactiveUI 进行 GUI 编程

    课题 程序界面由3个文本编辑框和1个文本标签组成. 要求文本标签实时显示3个文本编辑框所输入的数字之和. 文本编辑框输入的不是合法数字时,将其值视为0. 3个文本编辑框的初值分别为1,2,3. 创建工 ...

  8. 如何创建.gitignore文件,忽略不必要提交的文件

    1.gitignore 在工程实现过程中,会生成一些中间文件,或者在项目中的部分文件是不需要进行版本管理的.对于这些文件应该对于Github来讲是透明的.Github提供这种功能,可以自己指定哪些文件 ...

  9. funny故事

    name1 = input('请输入一个名字:') name2 = input('请输入一个名字:') vehicle = input('请输入一种车子:') print('\n上近代史的{}刚下课, ...

  10. Python利用PIL生成随机验证码图片

    安装pillow: pip install pillow PIL中的Image等模块提供了创建图片,制作图片的功能,大致的步骤就是我们利用random生成6个随机字符串,然后利用PIL将字符串绘制城图 ...