我正在尝试编写一个自定义Nifi处理器,它将接收传入流文件的内容,对其执行一些数学运算,然后将结果写入传出流文件中。有没有一种方法可以将传入流文件的内容转储为字符串或其他内容?我已经搜索了一段时间,但似乎并不那么简单。如果有人能指出我有关处理类似问题的优秀教程,将不胜感激。
答案 0 :(得分:1)
Apache NiFi Developer Guide很好地说明了创建自定义处理器的过程。在您的特定情况下,我将从Component Lifecycle部分和Enrich/Modify Content模式开始。做类似工作的任何其他处理器(例如ReplaceText或Base64EncodeContent)都是很好的例子;所有源代码都可以在GitHub上找到。
基本上,您需要在处理器类中实现#onTrigger()
方法,读取流文件内容并将其解析为所需的格式,执行操作,然后重新填充结果流文件内容。您的源代码将如下所示:
@Override
public void onTrigger(final ProcessContext context, final ProcessSession session) throws ProcessException {
FlowFile flowFile = session.get();
if (flowFile == null) {
return;
}
final ComponentLog logger = getLogger();
AtomicBoolean error = new AtomicBoolean();
AtomicReference<String> result = new AtomicReference<>(null);
// This uses a lambda function in place of a callback for InputStreamCallback#process()
processSession.read(flowFile, in -> {
long start = System.nanoTime();
// Read the flowfile content into a String
// TODO: May need to buffer this if the content is large
try {
final String contents = IOUtils.toString(in, StandardCharsets.UTF_8);
result.set(new MyMathOperationService().performSomeOperation(contents));
long stop = System.nanoTime();
if (getLogger().isDebugEnabled()) {
final long durationNanos = stop - start;
DecimalFormat df = new DecimalFormat("#.###");
getLogger().debug("Performed operation in " + durationNanos + " nanoseconds (" + df.format(durationNanos / 1_000_000_000.0) + " seconds).");
}
} catch (Exception e) {
error.set(true);
getLogger().error(e.getMessage() + " Routing to failure.", e);
}
});
if (error.get()) {
processSession.transfer(flowFile, REL_FAILURE);
} else {
// Again, a lambda takes the place of the OutputStreamCallback#process()
FlowFile updatedFlowFile = session.write(flowFile, (in, out) -> {
final String resultString = result.get();
final byte[] resultBytes = resultString.getBytes(StandardCharsets.UTF_8);
// TODO: This can use a while loop for performance
out.write(resultBytes, 0, resultBytes.length);
out.flush();
});
processSession.transfer(updatedFlowFile, REL_SUCCESS);
}
}
Daggett是对的,ExecuteScript处理器是一个很好的起点,因为它会缩短开发生命周期(无需构建NAR,部署和重新启动NiFi即可使用它),并且当您具有正确的行为时,您可以可以轻松地将其复制/粘贴到生成的框架中,然后将其部署一次。