- Subscribe to RSS Feed
- Mark Question as New
- Mark Question as Read
- Float this Question for Current User
- Bookmark
- Subscribe
- Mute
- Printer Friendly Page
NiFi - Script for JSON-content manipulation before JOLT
- Labels:
-
Apache NiFi
Created ‎07-08-2019 04:24 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi all,
as far as I investigated this (https://community.hortonworks.com/questions/247330/nifi-need-help-with-jolt-syntax-jolttransformjson-1.html) it is not possible to do this with JOLT.
Now I want to manipulate the JSON-content BEFORE JOLT does simple transformation.
I'm getting used to do some things with groovy, viewed some examples but couldn't find the right syntax.
There are two things I need to to:
1. All timestamps from JSON have to be converted and formated from CET yyyyMMddHHmmss ==> to UTC yyyy-MM-dd HH:mm:ss.SSS
2. Some string manipulation with some kind of expression language doing this:
Expression Language to build "dnr_group"
${DNR:substringAfter('('):substringBefore(')'):toNumber() :lt( 10 ) :ifElse(${DNR:substringAfter('('):substringBefore(')'):prepend('0')}, ${DNR:substringAfter('('):substringBefore(')')}) :append('-'):append(${GROUP:toNumber() :lt( 10 ) :ifElse(${GROUP:prepend('0')}, ${GROUP})}) :prepend('V-')}
Input-JSON
{ "user": "Justen", "stand": "20190702121621", "table": [ { "zn": 1, "elem_user": "Meier", "elem_stand": "20190705081410", "dnr": "(0)", "group": "1" }, { "elem_stand": "20190706201918", "zn": 2, "elem_user": "Schmidt", "dnr": "(0)", "group": "2" } ] }
Desired Output-JSON
{ "user": "Justen", "stand": "2019-07-02 10:16:21", "table": [ { "zn": 1, "elem_user": "Meier", "elem_stand": "2019-07-05 06:14:10", "dnr_group": "V-00-01" }, { "elem_stand": "2019-07-06 18:19:18", "zn": 2, "elem_user": "Schmidt", "dnr_group": "V-00-02" } ] }
Is it possible to do this with groovy or does anybody know other ways manipulating JSON-content in NiFi?
Thanks for any help!
Created ‎07-09-2019 11:29 AM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
you could first read that line from the json file (evaluate json path) and then update attribute with expression language and push it back into the json file with update record processor.
let me know if you need further help.
Created ‎07-09-2019 02:44 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @Rosa Negra thanks for your answer!
I worked with ff-attributes as long as the JSON-file contained only one entry at a time and it worked fine.
Now with the complex structure I couldn't find a way to manipulate the fields of the positions.
Unfortunately I have no experience with record processing. If I understand you correctly it would be possible to update the JSON doing record processing.
So I am "afraid" I have to explore it...
Maybe there are further solutions?
Created ‎09-30-2020 12:32 PM
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
Hi @justenji ! Please take a look at the below code and tell me if it is working or if you need any further upgradations. As of now, I have converted the timestamps and added dnr_group.
import java.nio.charset.StandardCharsets
import org.apache.nifi.components.PropertyValue
import groovy.json.JsonSlurper
import groovy.json.JsonOutput
flowFile = session.get()
if (!flowFile) return
try {
def jsonSlurper = new JsonSlurper();
def jsonOutput = new JsonOutput();
def input = flowFile.read().withStream {
data -> jsonSlurper.parse(data)
}
def pattern1 = 'yyyyMMddHHmmss';
def tz1 = 'GMT+0200';
def pattern2 = 'yyyy-MM-dd HH:mm:ss';
def tz2 = 'GMT';
input.stand = convertDatePattern(input.stand,pattern1,TimeZone.getTimeZone(tz1),pattern2,TimeZone.getTimeZone(tz2));
for(int i=0;i<input.table.size();i++){
input.table[i].elem_stand = convertDatePattern(input.table[i].elem_stand,pattern1,TimeZone.getTimeZone(tz1),pattern2,TimeZone.getTimeZone(tz2));
def dnr = input.table[i].dnr.replaceAll('\\(|\\)','');
def group = input.table[i].group.replaceAll('\\(|\\)','');
if(dnr.toInteger() < 10){
dnr = '0'+dnr;
}
if(group.toInteger() < 10){
group = '0'+group;
}
input.table[i].dnr_group = "V-"+dnr+"-"+group;
input.table[i].remove('dnr');
input.table[i].remove('group');
}
flowFile = session.write(flowFile, {
outputStream ->
outputStream.write(jsonOutput.toJson(input).toString().getBytes(StandardCharsets.UTF_8))
}as OutputStreamCallback);
session.transfer(flowFile, REL_SUCCESS);
} catch (e) {
log.error('Error Occured,{}', e)
session.transfer(flowFile, REL_FAILURE)
}
def convertDatePattern(String input, String pattern1, TimeZone tz1, String pattern2, TimeZone tz2){
return new Date().parse(pattern1,input,tz1).format(pattern2,tz2).toString();
}
