I am working with Apache NiFi 0.5.1 on a Groovy script to replace incoming Json values with the ones contained in a mapping file. The mapping file looks like this (it is a simpl
I have some examples on how to read in a flow file containing JSON:
http://funnifi.blogspot.com/2016/02/executescript-explained-split-fields.html http://funnifi.blogspot.com/2016/05/validating-json-in-nifi-with.html http://funnifi.blogspot.com/2016/02/executescript-processor-replacing-flow.html
You've got the right structure above; basically you can use that "inputStream" variable in the closure to read the incoming flow file contents. If you want to read it in all at once (which you will likely need to do for JSON), you can use IOUtils.toString() followed by a JsonSlurper, as is done in the examples in the links above.
For your mapping file, especially if your JSON is "flat", you could have a Java Properties file, mapping the name of the field to the new value:
field2=some text
field3=A2
Check out ConfigSlurper for reading in properties files.
Once you have slurped the incoming JSON file and read in the mapping file, you can get at the individual fields of the JSON using array notation instead of direct member notation. So let's say I read the properties into a ConfigSlurper, and I want to overwrite any existing property in my input JSON (called "json" for the example) with the one from the properties file. That might look like the following:
config.parse(props).flatten().each { k,v ->
if(json[k]) {
json[k] = v
}
}
You can then continue on with your outputStream.write().
Instead of reading your mappings from a file, you could also load it into a distributed cache via the PutDistributedMapCache processor. You can read from a DistributedCacheMapServer in your ExecuteScript, I have an example here:
http://funnifi.blogspot.com/2016/04/inspecting-your-nifi.html
If your mapping is complex, you may want to use the TransformJSON processor, which will be available in the next release of NiFi (0.7.0). The associated Jira case is here:
https://issues.apache.org/jira/browse/NIFI-361
EDIT:
In response to your edits, I didn't realize you had multiple rules for various values. In this case a properties file is probably not the best way to represent the mappings. Instead you could use JSON:
{
"field2": {
"A": "some text",
"B": "some other text"
},
"field3": {
"A": "A2",
"B": "B2"
}
}
Then you can use a JSONSlurper to read in the mappings file. Here is an example of using the above mapping file:
import groovy.json.JsonBuilder
import groovy.json.JsonSlurper
import org.apache.commons.io.IOUtils
import org.apache.nifi.processor.io.StreamCallback
import java.nio.charset.StandardCharsets
def flowFile = session.get();
if (flowFile == null) {
return;
}
def mappingJson = new File('/Users/mburgess/mappings.json').text
flowFile = session.write(flowFile, { inputStream, outputStream ->
def content = IOUtils.toString(inputStream, StandardCharsets.UTF_8)
def inJson = new JsonSlurper().parseText(content)
def mappings = new JsonSlurper().parseText(mappingJson)
inJson.each {k,v ->
inJson[k] = mappings[k][v]
}
outputStream.write(inJson.toString().getBytes(StandardCharsets.UTF_8))
} as StreamCallback)
session.transfer(flowFile, REL_SUCCESS)