簡體   English   中英

在Nifi中從ExecuteScript傳輸多個flowFiles

[英]Transfer multiple flowFiles from ExecuteScript in Nifi

我試圖使用python中的ExecuteScript處理器從一個流文件生成多個流文件。

ouputs流文件依賴於配置的一個屬性和輸入流文件(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)您是StreamCallback的子類並寫入原始流文件,但之后您將其刪除。 StreamCallback適用於要覆蓋現有流文件的內容。 如果您不需要這樣做,可以使用InputStreamCallback作為基類,它不會采用outputStream arg,但在這種情況下您不需要它。 你也想使用session.read原始流文件,而不是session.write

2)行flowFile = session.write(flowFile, "Nothing")無效,因為session.write需要一個OutputStreamCallback或StreamCallback作為參數(與下面用PyStreamCallback調用它的地方相同)。 當拋出錯誤時,它會一直提升到腳本的頂層,但到那時你已經創建了一個流文件而沒有到達將flowfiles_list傳遞給REL_SUCCESS的語句。 考慮在session.write周圍添加try/except ,然后您可以刪除新創建的流文件,然后引發異常。

3)如果要將傳入流文件的整個內容讀入內存(當前正在執行),則刪除原始流文件,而是從中創建新的流文件,而是考慮使用session.read()的版本session.read()返回一個InputStream(即不需要InputStreamCallback )。 然后,當您想要對創建的流文件寫入內容時,可以將內容保存到全局變量中和/或將其傳遞給OutputStreamCallback。 就像是:

inputStream = session.read(originalFlowFile)
text_content = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
inputStream.close()
flowfiles_list = []

for n in range(0,5):
    flowFile = session.create(originalFlowFile)
    if (flowFile != None):
        try:
            flowFile = session.write(flowFile, PyStreamCallback(text_content))
            flowfiles_list.append(flowFile)
        except Exception as e:
            session.remove(flowFile)
            raise

for flow in flowfiles_list:
    session.transfer(flow, REL_SUCCESS)

session.remove(originalFlowFile)

這不包括PyStreamCallback的重構是一個OutputStreamCallback,它在構造函數中采用字符串arg而不是FlowFile。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM