我正在尝试使用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)
有人可以告诉我我做错了什么以及如何实现我想做的事吗?
答案 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。