Re: Unable to properly tally all keys in nested json

2023-05-13 Thread James McMahon
I tried parsing the stream without forcing it to text, like you had done
Paul. I thought maybe that was the source of my problem, so I changed that
to this:

def root = new
JsonSlurper().setType(JsonParserType.LAX).parse(inputStream)

I continue to get this error:

ExecuteScript[id=028b1d40-33a5-1766-b659-31b3faaf13f5] Error
processing json fields: groovy.lang.MissingMethodException: No
signature of method: Script87$_run_closure3.call() is applicable for
argument types: (Node, String) values: [te=0.63847, ]
Possible solutions: any(), any(), doCall(java.util.Map,
java.lang.String), collect(), find(), dump()


I notice the content of the error statement shows this (Node, String)
values: [te=0.63847, ], which is not what I see in my input, which is
this: "te": "0.9494",


Is this perhaps the source of my problem - the fact that the key and
value are not being read in as strings?


On Sat, May 13, 2023 at 12:01 PM James McMahon  wrote:

> Thank you Paul. I have integrated this approach into the framework of my
> NiFi ExecuteScript code, which reads the flowfile content from the stream.
> I am seeing an undefined method error, and it seems to indicate it cannot
> digest the json. Does anything jump out at you as an obvious error in my
> approach?
>
> Here is the simple sample json in the flowfile:
>
> {"id": "20230508215236_4447cd0a-9dca-47cb-90b1-6562cf34155a_Timer-Driven
> Process Thread-9",
>
> "te": "0.9494",
>
> "diskusage": "0.2776125422110003.3 MB",
>
> "memory": 77,
>
> "cpu": 0.58,
>
> "host": "172.31.73.197/ip-172-31-73-197.ec2.internal",
>
> "temperature": "97",
>
> "macaddress": "f417ead3-4fa9-4cee-a14b-7172e9ecd3ea",
>
> "end": "61448816405795",
> "systemtime": "05/08/2023 16:52:36"}
>
>
> Here is the output error:
>
> ExecuteScript[id=028b1d40-33a5-1766-b659-31b3faaf13f5] Error processing json 
> fields: groovy.lang.MissingMethodException: No signature of method: 
> Script83$_run_closure3.call() is applicable for argument types: (Node, 
> String) values: [te=0.9494, ]
>
> Possible solutions: any(), any(), doCall(java.util.Map, java.lang.String), 
> collect(), find(), dump()
>
>
> Here is the current implementation of my code:
>
> import groovy.json.JsonSlurper
> import groovy.json.JsonParserType
> import org.apache.commons.io.IOUtils
> import java.nio.charset.StandardCharsets
>
> def keys = []
> def topValuesMap = [:].withDefault{ [:].withDefault{ 0 } }
> def tallyMap = [:].withDefault{ 0 }
> def tally
> tally = { Map json, String prefix ->
> json.each { k, v ->
> String key = prefix + k
> if (v instanceof List) {
>   tallyMap[key] += 1
>   v.each{ tally(it, key + '.') }
> } else {
> def val = v?.toString().trim()
> if (v) {
> tallyMap[key] += 1
> topValuesMap[key][v] += 1
> if (v instanceof Map) tally(v, key + '.')
> }
> }
> }
> }
>
>
> def ff = session.get()
> if (!ff) return
>
> try {
> session.read(ff, { inputStream ->
>
> def root = new
> JsonSlurper().setType(JsonParserType.LAX).parseText(IOUtils.toString(inputStream,
> StandardCharsets.UTF_8))
>
> root.each {
>  tally(it, '')
> }
> } as InputStreamCallback)
>
> keys = tallyMap.keySet().toList()
> def tallyMapString = tallyMap.collectEntries { k, v -> [(k): v]
> }.toString()
> def topValuesMapString = topValuesMap.collectEntries { k, v -> [(k):
> v.sort{ -it.value }.take(10)] }.toString()
>
> ff = session.putAttribute(ff, 'triage.json.fields', keys.join(","))
> ff = session.putAttribute(ff, 'triage.json.tallyMap', tallyMapString)
> ff = session.putAttribute(ff, 'triage.json.topValuesMap',
> topValuesMapString)
>
> session.transfer(ff, REL_SUCCESS)
> } catch (Exception e) {
> log.error('Error processing json fields', e)
> session.transfer(ff, REL_FAILURE)
> }
>
> On Fri, May 12, 2023 at 8:54 AM Paul King  wrote:
>
>> Something like this worked for me:
>>
>> def topValuesMap = [:].withDefault{ [:].withDefault{ 0 } }
>> def tallyMap = [:].withDefault{ 0 }
>> def tally
>> tally = { Map json, String prefix ->
>> json.each { k, v ->
>> String key = prefix + k
>> if (v instanceof List) {
>>   tallyMap[key] += 1
>>   v.each{ tally(it, key + '.') }
>> } else {
>> def val = v?.toString().trim()
>> if (v) {
>> tallyMap[key] += 1
>> topValuesMap[key][v] += 1
>> if (v instanceof Map) tally(v, key + '.')
>> }
>> }
>> }
>> }
>>
>> def root = new JsonSlurper().parse(inputStream)
>> root.each { // each allows json to be a list, not needed if always a map
>> tally(it, '')
>> }
>> println tallyMap
>> println topValuesMap.collectEntries{ k, m -> [(k), m.sort{ _, v ->
>> -v.value }] }.take(10)
>>
>>
>>
>> 

Re: Unable to properly tally all keys in nested json

2023-05-13 Thread James McMahon
Thank you Paul. I have integrated this approach into the framework of my
NiFi ExecuteScript code, which reads the flowfile content from the stream.
I am seeing an undefined method error, and it seems to indicate it cannot
digest the json. Does anything jump out at you as an obvious error in my
approach?

Here is the simple sample json in the flowfile:

{"id": "20230508215236_4447cd0a-9dca-47cb-90b1-6562cf34155a_Timer-Driven
Process Thread-9",

"te": "0.9494",

"diskusage": "0.2776125422110003.3 MB",

"memory": 77,

"cpu": 0.58,

"host": "172.31.73.197/ip-172-31-73-197.ec2.internal",

"temperature": "97",

"macaddress": "f417ead3-4fa9-4cee-a14b-7172e9ecd3ea",

"end": "61448816405795",
"systemtime": "05/08/2023 16:52:36"}


Here is the output error:

ExecuteScript[id=028b1d40-33a5-1766-b659-31b3faaf13f5] Error
processing json fields: groovy.lang.MissingMethodException: No
signature of method: Script83$_run_closure3.call() is applicable for
argument types: (Node, String) values: [te=0.9494, ]

Possible solutions: any(), any(), doCall(java.util.Map,
java.lang.String), collect(), find(), dump()


Here is the current implementation of my code:

import groovy.json.JsonSlurper
import groovy.json.JsonParserType
import org.apache.commons.io.IOUtils
import java.nio.charset.StandardCharsets

def keys = []
def topValuesMap = [:].withDefault{ [:].withDefault{ 0 } }
def tallyMap = [:].withDefault{ 0 }
def tally
tally = { Map json, String prefix ->
json.each { k, v ->
String key = prefix + k
if (v instanceof List) {
  tallyMap[key] += 1
  v.each{ tally(it, key + '.') }
} else {
def val = v?.toString().trim()
if (v) {
tallyMap[key] += 1
topValuesMap[key][v] += 1
if (v instanceof Map) tally(v, key + '.')
}
}
}
}


def ff = session.get()
if (!ff) return

try {
session.read(ff, { inputStream ->

def root = new
JsonSlurper().setType(JsonParserType.LAX).parseText(IOUtils.toString(inputStream,
StandardCharsets.UTF_8))

root.each {
 tally(it, '')
}
} as InputStreamCallback)

keys = tallyMap.keySet().toList()
def tallyMapString = tallyMap.collectEntries { k, v -> [(k): v]
}.toString()
def topValuesMapString = topValuesMap.collectEntries { k, v -> [(k):
v.sort{ -it.value }.take(10)] }.toString()

ff = session.putAttribute(ff, 'triage.json.fields', keys.join(","))
ff = session.putAttribute(ff, 'triage.json.tallyMap', tallyMapString)
ff = session.putAttribute(ff, 'triage.json.topValuesMap',
topValuesMapString)

session.transfer(ff, REL_SUCCESS)
} catch (Exception e) {
log.error('Error processing json fields', e)
session.transfer(ff, REL_FAILURE)
}

On Fri, May 12, 2023 at 8:54 AM Paul King  wrote:

> Something like this worked for me:
>
> def topValuesMap = [:].withDefault{ [:].withDefault{ 0 } }
> def tallyMap = [:].withDefault{ 0 }
> def tally
> tally = { Map json, String prefix ->
> json.each { k, v ->
> String key = prefix + k
> if (v instanceof List) {
>   tallyMap[key] += 1
>   v.each{ tally(it, key + '.') }
> } else {
> def val = v?.toString().trim()
> if (v) {
> tallyMap[key] += 1
> topValuesMap[key][v] += 1
> if (v instanceof Map) tally(v, key + '.')
> }
> }
> }
> }
>
> def root = new JsonSlurper().parse(inputStream)
> root.each { // each allows json to be a list, not needed if always a map
> tally(it, '')
> }
> println tallyMap
> println topValuesMap.collectEntries{ k, m -> [(k), m.sort{ _, v ->
> -v.value }] }.take(10)
>
>
>
> 
> Virus-free.www.avast.com
> 
> <#m_6659555815292156536_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
>
> On Fri, May 12, 2023 at 8:27 PM James McMahon 
> wrote:
>
>> Thank you for the response, Paul. I will integrate and try these
>> suggestions within my Groovy code that runs in a nifi ExecuteScript
>> processor. I'll be working on this once again tonight.
>>
>> The map topValuesMap is intended to capture this: for each key identified
>> in the json, cross-tabulate for each value associated with that key how
>> many times it occurs. After the json is fully processed for key, sort the
>> resulting map and retain only the top ten values found in the json. If a
>> set has a lastName key, the topValuesMap that results might look something
>> like this after all keys have been cross-tabulated:
>>
>> ["lastName": ["Smith" : 1023, "Jones" : 976, "Chang": 899, "Doe": 511,
>> ...],
>>  "address.street": [.],
>> .
>> .
>> .
>> "a final key": [.]
>> ]
>>
>> Each key would have ten values in its value map, unless it
>> cross-tabulates to 

Re: Unable to properly tally all keys in nested json

2023-05-12 Thread Paul King
Something like this worked for me:

def topValuesMap = [:].withDefault{ [:].withDefault{ 0 } }
def tallyMap = [:].withDefault{ 0 }
def tally
tally = { Map json, String prefix ->
json.each { k, v ->
String key = prefix + k
if (v instanceof List) {
  tallyMap[key] += 1
  v.each{ tally(it, key + '.') }
} else {
def val = v?.toString().trim()
if (v) {
tallyMap[key] += 1
topValuesMap[key][v] += 1
if (v instanceof Map) tally(v, key + '.')
}
}
}
}

def root = new JsonSlurper().parse(inputStream)
root.each { // each allows json to be a list, not needed if always a map
tally(it, '')
}
println tallyMap
println topValuesMap.collectEntries{ k, m -> [(k), m.sort{ _, v -> -v.value
}] }.take(10)



Virus-free.www.avast.com

<#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>

On Fri, May 12, 2023 at 8:27 PM James McMahon  wrote:

> Thank you for the response, Paul. I will integrate and try these
> suggestions within my Groovy code that runs in a nifi ExecuteScript
> processor. I'll be working on this once again tonight.
>
> The map topValuesMap is intended to capture this: for each key identified
> in the json, cross-tabulate for each value associated with that key how
> many times it occurs. After the json is fully processed for key, sort the
> resulting map and retain only the top ten values found in the json. If a
> set has a lastName key, the topValuesMap that results might look something
> like this after all keys have been cross-tabulated:
>
> ["lastName": ["Smith" : 1023, "Jones" : 976, "Chang": 899, "Doe": 511,
> ...],
>  "address.street": [.],
> .
> .
> .
> "a final key": [.]
> ]
>
> Each key would have ten values in its value map, unless it cross-tabulates
> to less than ten in total, in which case it will be sorted by count value
> and all values accepted.
> Again, many thanks.
> Jim
>
> On Fri, May 12, 2023 at 2:19 AM Paul King  wrote:
>
>> I am not 100% sure what you are trying to capture in topValuesMap but for
>> tallyMap you probably want something like:
>>
>> def tallyMap = [:].withDefault{ 0 }
>> def tally
>> tally = { Map json, String prefix ->
>> json.each { k, v ->
>> if (v instanceof List) {
>>   tallyMap[prefix + k] += 1
>>   v.each{ tally(it, "$prefix${k}.") }
>> } else if (v?.toString().trim()) {
>> tallyMap[prefix + k] += 1
>> if (v instanceof Map) tally(v, "$prefix${k}.")
>> }
>> }
>> }
>>
>> def root = new JsonSlurper().parse(inputStream)
>> def initialPrefix = ''
>> tally(root, initialPrefix)
>> println tallyMap
>>
>> Output:
>> [name:1, age:1, address:1, address.street:1, address.city:1,
>> address.state:1, address.zip:1, phoneNumbers:1, phoneNumbers.type:2,
>> phoneNumbers.number:2]
>>
>>
>>
>> 
>> Virus-free.www.avast.com
>> 
>> <#m_227840230113638997_m_3707991732434518544_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
>>
>> On Fri, May 12, 2023 at 10:38 AM James McMahon 
>> wrote:
>>
>>> I have this incoming json: { "name": "John Doe", "age": 42, "address": {
>>> "street": "123 Main St", "city": "Anytown", "state": "CA", "zip": "12345"
>>> }, "phoneNumbers": [ { "type": "home", "number": "555-1234" }, { "type":
>>> "work", "number": "555-5678" } ] } I wish to tally all the keys in this
>>> json in a map that gives me the key name as its key, and a count of the
>>> number of times the key occurs in the json as its value. For this example,
>>> the keys I expect in my output should include name, age, address,
>>> address.street, address.city, address.state, address.zip, phoneNumbers,
>>> phoneNumbers.type, and phoneNumbers.number. But I do not get that. Instead,
>>> I get this for the list of fields: triage.json.fields
>>> name,age,address,phoneNumbers And I get this for my tally count by key:
>>> triage.json.tallyMap [name:1, age:1, address:1, phoneNumbers:1]
>>>
>>> I am close, but not quite there. I don't capture all the keys. Here is
>>> my code. How must I modify this to get the result I require? import
>>> groovy.json.JsonSlurper import org.apache.commons.io.IOUtils import
>>> java.nio.charset.StandardCharsets def keys = [] def tallyMap = [:] def
>>> topValuesMap = [:] def ff = session.get() if (!ff) return try {
>>> session.read(ff, { inputStream -> def json = new
>>> JsonSlurper().parseText(IOUtils.toString(inputStream,
>>> StandardCharsets.UTF_8)) json.each { k, v -> if (v != null &&
>>> !v.toString().trim().isEmpty()) { tallyMap[k] = tallyMap.containsKey(

Re: Unable to properly tally all keys in nested json

2023-05-12 Thread James McMahon
Thank you for the response, Paul. I will integrate and try these
suggestions within my Groovy code that runs in a nifi ExecuteScript
processor. I'll be working on this once again tonight.

The map topValuesMap is intended to capture this: for each key identified
in the json, cross-tabulate for each value associated with that key how
many times it occurs. After the json is fully processed for key, sort the
resulting map and retain only the top ten values found in the json. If a
set has a lastName key, the topValuesMap that results might look something
like this after all keys have been cross-tabulated:

["lastName": ["Smith" : 1023, "Jones" : 976, "Chang": 899, "Doe": 511, ...],
 "address.street": [.],
.
.
.
"a final key": [.]
]

Each key would have ten values in its value map, unless it cross-tabulates
to less than ten in total, in which case it will be sorted by count value
and all values accepted.
Again, many thanks.
Jim

On Fri, May 12, 2023 at 2:19 AM Paul King  wrote:

> I am not 100% sure what you are trying to capture in topValuesMap but for
> tallyMap you probably want something like:
>
> def tallyMap = [:].withDefault{ 0 }
> def tally
> tally = { Map json, String prefix ->
> json.each { k, v ->
> if (v instanceof List) {
>   tallyMap[prefix + k] += 1
>   v.each{ tally(it, "$prefix${k}.") }
> } else if (v?.toString().trim()) {
> tallyMap[prefix + k] += 1
> if (v instanceof Map) tally(v, "$prefix${k}.")
> }
> }
> }
>
> def root = new JsonSlurper().parse(inputStream)
> def initialPrefix = ''
> tally(root, initialPrefix)
> println tallyMap
>
> Output:
> [name:1, age:1, address:1, address.street:1, address.city:1,
> address.state:1, address.zip:1, phoneNumbers:1, phoneNumbers.type:2,
> phoneNumbers.number:2]
>
>
>
> 
> Virus-free.www.avast.com
> 
> <#m_3707991732434518544_DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>
>
> On Fri, May 12, 2023 at 10:38 AM James McMahon 
> wrote:
>
>> I have this incoming json: { "name": "John Doe", "age": 42, "address": {
>> "street": "123 Main St", "city": "Anytown", "state": "CA", "zip": "12345"
>> }, "phoneNumbers": [ { "type": "home", "number": "555-1234" }, { "type":
>> "work", "number": "555-5678" } ] } I wish to tally all the keys in this
>> json in a map that gives me the key name as its key, and a count of the
>> number of times the key occurs in the json as its value. For this example,
>> the keys I expect in my output should include name, age, address,
>> address.street, address.city, address.state, address.zip, phoneNumbers,
>> phoneNumbers.type, and phoneNumbers.number. But I do not get that. Instead,
>> I get this for the list of fields: triage.json.fields
>> name,age,address,phoneNumbers And I get this for my tally count by key:
>> triage.json.tallyMap [name:1, age:1, address:1, phoneNumbers:1]
>>
>> I am close, but not quite there. I don't capture all the keys. Here is my
>> code. How must I modify this to get the result I require? import
>> groovy.json.JsonSlurper import org.apache.commons.io.IOUtils import
>> java.nio.charset.StandardCharsets def keys = [] def tallyMap = [:] def
>> topValuesMap = [:] def ff = session.get() if (!ff) return try {
>> session.read(ff, { inputStream -> def json = new
>> JsonSlurper().parseText(IOUtils.toString(inputStream,
>> StandardCharsets.UTF_8)) json.each { k, v -> if (v != null &&
>> !v.toString().trim().isEmpty()) { tallyMap[k] = tallyMap.containsKey(k) ?
>> tallyMap[k] + 1 : 1 if (topValuesMap.containsKey(k)) { def valuesMap =
>> topValuesMap[k] valuesMap[v] = valuesMap.containsKey(v) ? valuesMap[v] + 1
>> : 1 topValuesMap[k] = valuesMap } else { topValuesMap[k] = [:].withDefault{
>> 0 }.plus([v: 1]) } } } } as InputStreamCallback) keys =
>> tallyMap.keySet().toList() def tallyMapString = tallyMap.collectEntries {
>> k, v -> [(k): v] }.toString() def topValuesMapString =
>> topValuesMap.collectEntries { k, v -> [(k): v.sort{ -it.value }.take(10)]
>> }.toString() ff = session.putAttribute(ff, 'triage.json.fields',
>> keys.join(",")) ff = session.putAttribute(ff, 'triage.json.tallyMap',
>> tallyMapString) ff = session.putAttribute(ff, 'triage.json.topValuesMap',
>> topValuesMapString) session.transfer(ff, REL_SUCCESS) } catch (Exception e)
>> { log.error('Error processing json fields', e) session.transfer(ff,
>> REL_FAILURE) }
>>
>


Re: Unable to properly tally all keys in nested json

2023-05-11 Thread Paul King
I am not 100% sure what you are trying to capture in topValuesMap but for
tallyMap you probably want something like:

def tallyMap = [:].withDefault{ 0 }
def tally
tally = { Map json, String prefix ->
json.each { k, v ->
if (v instanceof List) {
  tallyMap[prefix + k] += 1
  v.each{ tally(it, "$prefix${k}.") }
} else if (v?.toString().trim()) {
tallyMap[prefix + k] += 1
if (v instanceof Map) tally(v, "$prefix${k}.")
}
}
}

def root = new JsonSlurper().parse(inputStream)
def initialPrefix = ''
tally(root, initialPrefix)
println tallyMap

Output:
[name:1, age:1, address:1, address.street:1, address.city:1,
address.state:1, address.zip:1, phoneNumbers:1, phoneNumbers.type:2,
phoneNumbers.number:2]



Virus-free.www.avast.com

<#DAB4FAD8-2DD7-40BB-A1B8-4E2AA1F9FDF2>

On Fri, May 12, 2023 at 10:38 AM James McMahon  wrote:

> I have this incoming json: { "name": "John Doe", "age": 42, "address": {
> "street": "123 Main St", "city": "Anytown", "state": "CA", "zip": "12345"
> }, "phoneNumbers": [ { "type": "home", "number": "555-1234" }, { "type":
> "work", "number": "555-5678" } ] } I wish to tally all the keys in this
> json in a map that gives me the key name as its key, and a count of the
> number of times the key occurs in the json as its value. For this example,
> the keys I expect in my output should include name, age, address,
> address.street, address.city, address.state, address.zip, phoneNumbers,
> phoneNumbers.type, and phoneNumbers.number. But I do not get that. Instead,
> I get this for the list of fields: triage.json.fields
> name,age,address,phoneNumbers And I get this for my tally count by key:
> triage.json.tallyMap [name:1, age:1, address:1, phoneNumbers:1]
>
> I am close, but not quite there. I don't capture all the keys. Here is my
> code. How must I modify this to get the result I require? import
> groovy.json.JsonSlurper import org.apache.commons.io.IOUtils import
> java.nio.charset.StandardCharsets def keys = [] def tallyMap = [:] def
> topValuesMap = [:] def ff = session.get() if (!ff) return try {
> session.read(ff, { inputStream -> def json = new
> JsonSlurper().parseText(IOUtils.toString(inputStream,
> StandardCharsets.UTF_8)) json.each { k, v -> if (v != null &&
> !v.toString().trim().isEmpty()) { tallyMap[k] = tallyMap.containsKey(k) ?
> tallyMap[k] + 1 : 1 if (topValuesMap.containsKey(k)) { def valuesMap =
> topValuesMap[k] valuesMap[v] = valuesMap.containsKey(v) ? valuesMap[v] + 1
> : 1 topValuesMap[k] = valuesMap } else { topValuesMap[k] = [:].withDefault{
> 0 }.plus([v: 1]) } } } } as InputStreamCallback) keys =
> tallyMap.keySet().toList() def tallyMapString = tallyMap.collectEntries {
> k, v -> [(k): v] }.toString() def topValuesMapString =
> topValuesMap.collectEntries { k, v -> [(k): v.sort{ -it.value }.take(10)]
> }.toString() ff = session.putAttribute(ff, 'triage.json.fields',
> keys.join(",")) ff = session.putAttribute(ff, 'triage.json.tallyMap',
> tallyMapString) ff = session.putAttribute(ff, 'triage.json.topValuesMap',
> topValuesMapString) session.transfer(ff, REL_SUCCESS) } catch (Exception e)
> { log.error('Error processing json fields', e) session.transfer(ff,
> REL_FAILURE) }
>


Unable to properly tally all keys in nested json

2023-05-11 Thread James McMahon
I have this incoming json: { "name": "John Doe", "age": 42, "address": {
"street": "123 Main St", "city": "Anytown", "state": "CA", "zip": "12345"
}, "phoneNumbers": [ { "type": "home", "number": "555-1234" }, { "type":
"work", "number": "555-5678" } ] } I wish to tally all the keys in this
json in a map that gives me the key name as its key, and a count of the
number of times the key occurs in the json as its value. For this example,
the keys I expect in my output should include name, age, address,
address.street, address.city, address.state, address.zip, phoneNumbers,
phoneNumbers.type, and phoneNumbers.number. But I do not get that. Instead,
I get this for the list of fields: triage.json.fields
name,age,address,phoneNumbers And I get this for my tally count by key:
triage.json.tallyMap [name:1, age:1, address:1, phoneNumbers:1]

I am close, but not quite there. I don't capture all the keys. Here is my
code. How must I modify this to get the result I require? import
groovy.json.JsonSlurper import org.apache.commons.io.IOUtils import
java.nio.charset.StandardCharsets def keys = [] def tallyMap = [:] def
topValuesMap = [:] def ff = session.get() if (!ff) return try {
session.read(ff, { inputStream -> def json = new
JsonSlurper().parseText(IOUtils.toString(inputStream,
StandardCharsets.UTF_8)) json.each { k, v -> if (v != null &&
!v.toString().trim().isEmpty()) { tallyMap[k] = tallyMap.containsKey(k) ?
tallyMap[k] + 1 : 1 if (topValuesMap.containsKey(k)) { def valuesMap =
topValuesMap[k] valuesMap[v] = valuesMap.containsKey(v) ? valuesMap[v] + 1
: 1 topValuesMap[k] = valuesMap } else { topValuesMap[k] = [:].withDefault{
0 }.plus([v: 1]) } } } } as InputStreamCallback) keys =
tallyMap.keySet().toList() def tallyMapString = tallyMap.collectEntries {
k, v -> [(k): v] }.toString() def topValuesMapString =
topValuesMap.collectEntries { k, v -> [(k): v.sort{ -it.value }.take(10)]
}.toString() ff = session.putAttribute(ff, 'triage.json.fields',
keys.join(",")) ff = session.putAttribute(ff, 'triage.json.tallyMap',
tallyMapString) ff = session.putAttribute(ff, 'triage.json.topValuesMap',
topValuesMapString) session.transfer(ff, REL_SUCCESS) } catch (Exception e)
{ log.error('Error processing json fields', e) session.transfer(ff,
REL_FAILURE) }