I am trying to replace API Data with "All" in Emp_Id field in data in json. And then make rows with every data of API.
I tried in ecmascript but I need in Java as this map function is giving error in nifi.
API DATA: I have stored this data in "Response" attribute in ExtractText in Apache Nifi.
response
{
"status": "success",
"data": [[123, 0], [124, 0], [446, 0], [620, 0], [470 ,1]]
};
jsonData
{
"Emp_Id": "All",
"Emp_loc": "523",
"Emp_dept": "Management",
"Emp_sub_dept": "Finance",
"Emp_sub_dept2": "Accountant"
};
Expected Result
[
{
"Emp_Id":"123",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"124",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"446",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"620",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
},
{
"Emp_Id":"470",
"Emp_loc":"523",
"Emp_dept":"Management",
"Emp_sub_dept":"Finance",
"Emp_sub_dept2":"Accountant"
}
]
This is tried in ecmaScript but I want it to be in Java because these functions are not working in executeScript of NIFI and giving error."java.lang.assertionError: geberating bytecode". Or if any other approach for converting this data.
this is the script I tried
var InputStreamCallback = Java.type("org.apache.nifi.processor.io.InputStreamCallback")
var IOUtils = Java.type("org.apache.commons.io.IOUtils");
var OutputStreamCallback = Java.type("org.apache.nifi.processor.io.OutputStreamCallback");
var StandardCharsets = Java.type("java.nio.charset.StandardCharsets");
var Set = Java.type("java.util.HashSet");
var Map = Java.type("java.util.HashMap");
var String = Java.type("java.lang.String");
var flowFile = session.get();
if (flowFile != null) {
var text = ''
session.read(flowFile,
new InputStreamCallback(function (inputStream) {
text = IOUtils.toString(inputStream, StandardCharsets.UTF_8);
}));
var s3Data ={}
var apiResponse={}
var map = new Map();
var s3Data = JSON.parse(flowFile.getAttribute('jsonData'))
var apiResponse = JSON.parse(flowFile.getAttribute('response'))
var result = apiResponse.data.map(([id]) =>
Object.fromEntries(Object.entries(s3Data).map(([k, v]) =>
[k, v === "All" ? id : v]
))
);
flowFile = session.write(flowFile,
new OutputStreamCallback(function(outputStream) {
outputStream.write(JSON.stringify(result).getBytes(StandardCharsets.UTF_8))
})
);
}
I tried with groovy also but I have very less knowledge of Groovy so I couldn’t write the proper ExecuteScript.
2
Answers
Can you try following Code, please see that i have trie to match the output if there are anyother logic present please update question.
ObjectMapper from here
You may try library Josson & Jossons to transform and join the two datasets.
https://github.com/octomix/josson
Deserialize, Transform and Join
Left join
<=<
two transformed datasets with matchingkey
.Output
Demonstrate the transformation of
response
Divert each
data
element to separate branches. For each branch, get the first array element and then build an object with elementEmp_Id
andkey
.Output
Demonstrate the transformation of
jsonData
Add an element
key
with the value ofEmp_Id
and then removeEmp_Id
.Output