生成 HTML table 并在 Apache NiFI 中通过电子邮件发送
Generate HTML table and send it vie email in Apache NiFI
我们有一个 Java 应用程序,它从数据库中读取信息并通过 Freemarker 生成 HTML table,如下所示:
<#if marks?size != 0>
<div>
<p>
<b>Total rows with information about broken utm-marks for ${date} is: ${total}. Displayed in current report: ${displayed}</b>
</p>
<br/>
</div>
<table border="1" cellspacing="0" cellpadding="1">
<tr class="tableHeader" style = "background-color:#f8f5e4; text-align:center; font-weight: bold;">
<th>Report date</th>
<th>Account Login</th>
<th>View Id</th>
<th>Utm marks</th>
<th>Exception type</th>
<th>Exception message</th>
</tr>
<#list marks as mark>
<tr class="tableBody">
<td>${(mark.reportDate)!""}</td>
<td>${(mark.accountLogin)!""}</td>
<td>${(mark.accountViewId)!""}</td>
<td>${(mark.utmMarks)!""}</td>
<td>${(mark.exceptionType)!""}</td>
<td>${(mark.exceptionMessage)!""}</td>
</tr>
</#list>
</table>
<br/>
<#else>
<div>
<p>
<b>No information about broken utm marks for ${date}.</b>
</p>
</div>
</#if>
此生成的 table 将发送到配置的电子邮件。
是否可以使用 Apache NiFi(不使用和使用 ExecuteScript
)构建此类应用程序?从数据库读取 - 很好;发送电子邮件 - 很好;但是模板和 html table 呢?
在 nifi 根文件夹中创建 ./templates
文件夹
将模板文件 test.ftlh
放在那里,内容为:
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Welcome ${user}!</h1>
<p>Our latest product:
<a href="${latestProduct.url}">${latestProduct.name}</a>!
</body>
</html>
使用 GenerateFlowFile
将以下 json 注入流文件:
{
"user":"Big Joe",
"latestProduct": {
"name":"green mouse",
"url":"aaa/bbb/ccc"
}
}
使用ExecuteGroovyScript
合并模板与数据
@Grab(group='org.freemarker', module='freemarker', version='2.3.31')
import freemarker.template.*
import groovy.json.*
class Const{
static Configuration cfg
}
//on processor start
static onStart(ProcessContext context){
Const.cfg = new Configuration(Configuration.VERSION_2_3_29)
Const.cfg.with{
setDirectoryForTemplateLoading(new File("./templates"))
setDefaultEncoding("UTF-8")
setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER)
setLogTemplateExceptions(false)
setWrapUncheckedExceptions(true)
setFallbackOnNullLoopVariable(false)
}
}
//flowfile process
def ff=session.get()
if(!ff)return
ff.write{InputStream rawIn, OutputStream rawOut->
//assume json in flowfile
def root = new JsonSlurper().parse(rawIn)
Template tpl = Const.cfg.getTemplate("test.ftlh")
rawOut.withWriter("UTF-8"){w-> tpl.process(root, w) }
}
REL_SUCCESS << ff
没有 ExecuteScript
(或类似的)的一种方法是:
- 将 HTML 模板文本放入 NiFi 进程组变量中
- 然后使用NiFi表达式语言函数
evaluateELString
将流文件属性代入模板。
这种方法的优点是易于维护:HTML 模板文本可以与流程组一起使用;没有脚本代码需要维护。
为了说明这种方法,假设您将 HTML 模板文本放入名为 email_template
的进程组变量中。此外,假设流文件具有 HTML 模板所需的属性集(例如,来自数据库)。然后为了获得实现的电子邮件正文,将 NiFi 表达式 ${email_template:evaluateELString()}
放入 Replacement 属性 的 ReplaceText[=40] 的值中=] 处理器(在 PutEmail 处理器之前)。
在上图中,变量email_template
可以设置为:
<#if marks?size != 0>
<div>
<p>
<b>Total rows with information about broken utm-marks for ${date} is: ${total}. Displayed in current report: ${displayed}</b>
</p>
<br/>
</div>
<table border="1" cellspacing="0" cellpadding="1">
<tr class="tableHeader" style = "background-color:#f8f5e4; text-align:center; font-weight: bold;">
<th>Report date</th>
<th>Account Login</th>
<th>View Id</th>
<th>Utm marks</th>
<th>Exception type</th>
<th>Exception message</th>
</tr>
<#list marks as mark>
<tr class="tableBody">
<td>${mark.reportDate}</td>
<td>${mark.accountLogin}</td>
<td>${mark.accountViewId}</td>
<td>${mark.utmMarks}</td>
<td>${mark.exceptionType}</td>
<td>${mark.exceptionMessage}</td>
</tr>
</#list>
</table>
<br/>
<#else>
<div>
<p>
<b>No information about broken utm marks for ${date}.</b>
</p>
</div>
</#if>
...和 ${email_template:evaluateELString()}
将用流文件属性值替换 date
、total
、displayed
、mark.reportDate
等
我们有一个 Java 应用程序,它从数据库中读取信息并通过 Freemarker 生成 HTML table,如下所示:
<#if marks?size != 0>
<div>
<p>
<b>Total rows with information about broken utm-marks for ${date} is: ${total}. Displayed in current report: ${displayed}</b>
</p>
<br/>
</div>
<table border="1" cellspacing="0" cellpadding="1">
<tr class="tableHeader" style = "background-color:#f8f5e4; text-align:center; font-weight: bold;">
<th>Report date</th>
<th>Account Login</th>
<th>View Id</th>
<th>Utm marks</th>
<th>Exception type</th>
<th>Exception message</th>
</tr>
<#list marks as mark>
<tr class="tableBody">
<td>${(mark.reportDate)!""}</td>
<td>${(mark.accountLogin)!""}</td>
<td>${(mark.accountViewId)!""}</td>
<td>${(mark.utmMarks)!""}</td>
<td>${(mark.exceptionType)!""}</td>
<td>${(mark.exceptionMessage)!""}</td>
</tr>
</#list>
</table>
<br/>
<#else>
<div>
<p>
<b>No information about broken utm marks for ${date}.</b>
</p>
</div>
</#if>
此生成的 table 将发送到配置的电子邮件。
是否可以使用 Apache NiFi(不使用和使用 ExecuteScript
)构建此类应用程序?从数据库读取 - 很好;发送电子邮件 - 很好;但是模板和 html table 呢?
在 nifi 根文件夹中创建 ./templates
文件夹
将模板文件 test.ftlh
放在那里,内容为:
<html>
<head>
<title>Welcome!</title>
</head>
<body>
<h1>Welcome ${user}!</h1>
<p>Our latest product:
<a href="${latestProduct.url}">${latestProduct.name}</a>!
</body>
</html>
使用 GenerateFlowFile
将以下 json 注入流文件:
{
"user":"Big Joe",
"latestProduct": {
"name":"green mouse",
"url":"aaa/bbb/ccc"
}
}
使用ExecuteGroovyScript
合并模板与数据
@Grab(group='org.freemarker', module='freemarker', version='2.3.31')
import freemarker.template.*
import groovy.json.*
class Const{
static Configuration cfg
}
//on processor start
static onStart(ProcessContext context){
Const.cfg = new Configuration(Configuration.VERSION_2_3_29)
Const.cfg.with{
setDirectoryForTemplateLoading(new File("./templates"))
setDefaultEncoding("UTF-8")
setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER)
setLogTemplateExceptions(false)
setWrapUncheckedExceptions(true)
setFallbackOnNullLoopVariable(false)
}
}
//flowfile process
def ff=session.get()
if(!ff)return
ff.write{InputStream rawIn, OutputStream rawOut->
//assume json in flowfile
def root = new JsonSlurper().parse(rawIn)
Template tpl = Const.cfg.getTemplate("test.ftlh")
rawOut.withWriter("UTF-8"){w-> tpl.process(root, w) }
}
REL_SUCCESS << ff
没有 ExecuteScript
(或类似的)的一种方法是:
- 将 HTML 模板文本放入 NiFi 进程组变量中
- 然后使用NiFi表达式语言函数
evaluateELString
将流文件属性代入模板。
这种方法的优点是易于维护:HTML 模板文本可以与流程组一起使用;没有脚本代码需要维护。
为了说明这种方法,假设您将 HTML 模板文本放入名为 email_template
的进程组变量中。此外,假设流文件具有 HTML 模板所需的属性集(例如,来自数据库)。然后为了获得实现的电子邮件正文,将 NiFi 表达式 ${email_template:evaluateELString()}
放入 Replacement 属性 的 ReplaceText[=40] 的值中=] 处理器(在 PutEmail 处理器之前)。
在上图中,变量email_template
可以设置为:
<#if marks?size != 0>
<div>
<p>
<b>Total rows with information about broken utm-marks for ${date} is: ${total}. Displayed in current report: ${displayed}</b>
</p>
<br/>
</div>
<table border="1" cellspacing="0" cellpadding="1">
<tr class="tableHeader" style = "background-color:#f8f5e4; text-align:center; font-weight: bold;">
<th>Report date</th>
<th>Account Login</th>
<th>View Id</th>
<th>Utm marks</th>
<th>Exception type</th>
<th>Exception message</th>
</tr>
<#list marks as mark>
<tr class="tableBody">
<td>${mark.reportDate}</td>
<td>${mark.accountLogin}</td>
<td>${mark.accountViewId}</td>
<td>${mark.utmMarks}</td>
<td>${mark.exceptionType}</td>
<td>${mark.exceptionMessage}</td>
</tr>
</#list>
</table>
<br/>
<#else>
<div>
<p>
<b>No information about broken utm marks for ${date}.</b>
</p>
</div>
</#if>
...和 ${email_template:evaluateELString()}
将用流文件属性值替换 date
、total
、displayed
、mark.reportDate
等