The message binding is a "GroovyMessage" object. The GroovMessage class is a convenience class that wraps the standard GatewayMessage class, which in turn wraps json object. The message object is not a map, and fields cannot be accessed using the Groovy dot notation for getters. In order to use the map notation, use asMap() as follows:

 

messageMap=message.asMap()
messageMap.incident.description

 

Tip: to avoid null pointer exceptions in Groovy, you can use “Safe navigation”:

 

messageMap.incident?.description

 

In this case, if the message does not contain a structure called “incident”, the expression returns null instead of throwing an exception. In combination with the Groovy Elvis operator, this can be used to assign a default value like this:

def description = messageMap.incident?.description :? "A default description"

 

For more detail see http://www.groovy-lang.org/operators.html#_safe_navigation_operator

To access the message directly, use get and put with the slash notation:


message.get("incident/description")
message.put("incident/description","The crossbeam has gone out of skew on the treddle")

 

 

Method

Purpose

Example

changed(key)

To determine whether a certain key in the message has changed since the last time this message was processed. Looks across the entire life of the message.

if (message.changed(“/ticket/priority”) escalate();

changed()

Returns true if anything has changed in the message since it was seen last time.


previous()

Returns the message as seen last time it was processed

 

put(key,value)

Add or replace a part of the message

if (message.changed(“/ticket/priority”))

  message.put(“/ticket/newnote”,”The priority has changed from “+previous().ticket.priority+” to “+message.ticket.priority);

putJson(key,value)

Parse and insert a json structure into the message


headers()

Returns a map of all the message headers.


getId()

Returns the id of the object that this message represents.


findIdmap(endpoint)

Returns the id map entry for this message and the specified endpoint


addIdmap(endpoint,id)

Records an ID mapping for this message and the specified endpoint/id pair.


discard()

Discard this message (only used in mappings)

if (message.value==null) message.discard()

updates(messagetype)

Returns a nested map that contains all inserted, updated and deleted fields of the message. Only processes the message of type messagetype. The resulting map contains an entry for each field, in the same place where that field appears in the message, with a structure containing action=insert/update/delete and the before and after values where applicable.


updates()

Same as updates(message.headers().message_type)


getMessages()

Returns the messages inside this message. In case of a bulk message, they are the individual messages. In case of a mapped message, they are the messages before and after each mapper.


toJson()

Returns the message content as a Json string


asMap()

Returns the message content as a map


 

Iterating over message content

 

There are two ways of iterating over a message: using a regular expression in the “from” field of a mapping, or using the Groovy “each()” method on the map representation of the message. The examples in this section use a Groovy poller that retrieves data from the WHO listing average life expectancy by country:

 

http=option.http
ret=http.get("https://apps.who.int/gho/athena/api/GHO/WHOSIS_000001?format=json")
api.publish(ret,"WhoMessage",false)
return null

 

Using a regular expression

 

When you define a mapping with a regular expression and a capture group in the “from” field, the mapping will be executed once for each matching result, automatically iterating over the result set. In the mapping itself, the content of the current branch (the part of the message referenced by the matching from field) is made available as “curnode”. In this example, we basically add a country code lookup table to the message.


Using Groovy each() 

 

message.asMap().dimension.each() { dim ->
   dim.code.each() { code ->
       message.put("Lookup/"+dim.label.textValue()+ "/" + code.label.textValue(),code.display.textValue())
   }
}

 

In this second example, there are two nested iterations to create a lookup table not just for countries, but for all dimensions of the data. 

CAUTION: The iterator function each() only works on arrays. If a certain part of the message should be an array but isn’t, you can easily convert it into an array by using the “Convert object node to array” mapping before processing it in Groovy.

CAUTION: The closure parameter of the each() operator (dim and code in the example) represent Jackson JsonNode objects. To turn them into scalar values, use the textValue(), intValue() or doubleValue() methods.


Another example of Groovy each() 

In the following example we poll a URL to search for issues from Jira. For each ticket we get the issue details by getting each issue individually.

  

// search for tickets 
query = "updated>='"+lasttime+"' AND project=TEST order by updated ASC"
query = java.net.URLEncoder.encode(query, "UTF-8")
url = "https://faciligate.atlassian.net/rest/api/2/search?jql=" + query
option.http.content("application/json")
option.http.useAuth("jira")

ticketsres=option.http.get(url)

// parse the response as messages
msgs = api.parse(ticketsres,msgtype, true)

// iterate over messages
msgs.extractMessages().each() { m ->
   // set message id to GET the message
   m.headers().set("idlocation","key") 
   url = "https://faciligate.atlassian.net/rest/api/2/issue/" + m.getId()
   extendedTicketStr=option.http.get(url)
   resMap = parser.asMap(extendedTicketStr)

  // parse the response as message
   msg = api.parse(parser.asJson(resMap),msgtype, false)
   // publish each mesage
   api.publish(msg)
}

Headers

 

The following headers can be manipulated using message.headers().set(headername,value). You can also read the current header value using message.headers().headername

 

 

Headername

Meaning

Example

  plugin

Plugin name in the origin header

set(“plugin”,”Ivanti poller”)

  product

Product name in origin header

set(“product”,”Ivanti”)

  endpoint

Endpoint in origin header

set(“endpoint”,”IvantiProd”)

  idlocation

The pointer to the id in the message

set(“idlocation”,”/incident/identifier/value”)

  id

The id itself

set(“id”,”MONI43985”)

  message_type

The message type

set(“message_type”,”IncomingIvantiIncident”)

  record_type

The type of object this message represents

set(“record_type”,”Incident”)

  timestamp

The message timestamp in epoch

set(“timestamp”, 1630233221)

  table

The table name where to persist this message

set(“table”,”Incidents”)

  detail

The detail to persist (0=headers only, 1=whole message)

set(“detail”,0)

  track_updates

Whether to automatically keep track of changes in this message

set(“track_updates”,true)

  persist

Whether to persist this message

set(“persist”,true)