在Nifi中从ExecuteScript传输多个flowFiles

时间:2019-03-21 16:21:34

标签: python apache-nifi

我正在尝试使用python中的ExecuteScript处理器从一个流文件生成多个流文件。

输出流文件取决于一个配置属性和输入流文件(xml内容)。

我尝试了很多事情,但是我总是以如下错误结束:

  • 此流文件已被标记为要传输
  • 未指定转移关系

在最新版本下:

from org.apache.commons.io import IOUtils
from java.nio.charset import StandardCharsets
from org.apache.nifi.processor.io import StreamCallback
import java.io
from org.python.core.util import StringUtil

class PyStreamCallback(StreamCallback):
    def __init__(self, flowFile):
        global matched
        self.parentFlowFile = flowFile
        pass

    def process(self, inputStream, outputStream):
        try:
            text_content = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
            flowfiles_list = []

            new_xml = "blabla"
            outputStream.write(bytearray(new_xml.encode('utf-8')))

            for n in range(0,5):
                flowFile = session.create(self.parentFlowFile)
                if (flowFile != None):
                    flowFile = session.write(flowFile, "Nothing")
                    flowfiles_list.append(flowFile)

            for flow in flowfiles_list:
                session.transfer(flow, REL_SUCCESS)
        except:
            print('Error inside process')
            raise

originalFlowFile = session.get()
if(originalFlowFile != None):
    try :
        originalFlowFile = session.write(originalFlowFile, PyStreamCallback(originalFlowFile))
        session.remove(originalFlowFile)

    except Exception as e:
        originalFlowFile = session.putAttribute(originalFlowFile,'python_error', str(e))
        session.transfer(originalFlowFile, REL_FAILURE)

有人可以告诉我我做错了什么以及如何实现我想做的事吗?

1 个答案:

答案 0 :(得分:0)

以下是有关脚本的一些说明:

1)您要继承StreamCallback的子类并写入原始流文件,但是稍后将其删除。 StreamCallback用于想要覆盖现有流文件的内容的情况。如果不需要这样做,可以将InputStreamCallback用作基类,它不需要一个outputStream arg,但是在这种情况下则不需要它。您还将在原始流文件上使用session.read,而不是session.write

2)第flowFile = session.write(flowFile, "Nothing")行是无效的,因为session.write需要OutputStreamCallback或StreamCallback作为参数(与在下面的PyStreamCallback调用它的位置相同)。当这引发错误时,它会一直上升到脚本的顶层,但是到那时您已经创建了一个流文件,并且没有到达将flowfiles_list传输到REL_SUCCESS的语句。考虑在try/except周围添加session.write,然后可以删除新创建的流文件,然后引发异常。

3)如果您想将传入流文件的全部内容读到内存中(当前正在执行),请删除原始流文件并从中创建新的流文件,请考虑使用{返回输入流的{1}}(即不需要session.read())。然后,您可以将内容保存到全局变量中和/或在要向创建的流文件中写入内容时将其传递到OutputStreamCallback。像这样:

InputStreamCallback

这不包括将PyStreamCallback重构为一个OutputStreamCallback,它在构造函数中使用字符串arg而不是FlowFile。