Easy filtering of duplicate messages

For duplicate message filtering I recommend that you use Iguana 5.6.12 or above and take advantage of a more efficient message filter module that you can find in the Iguana Apps section.  The code below is an earlier solution which has been improved upon since.

It’s not an uncommon problem to have an issue with an information system that is generating duplicate messages. This is an easy thing to sort out in Iguana thanks to ease with which you can query the logs. In fact the speed with with queries work on the logs thanks to the full text index that Iguana generates makes this an efficient operation.

To make it simple I put together this little module to drop it into your own mapping scripts and just use.

This is how you would use it in the context of a ‘Filter’ script in a channel. You could use this module in any place you like of course since it’s just a simple function to call:

dup = require 'dup'

local N = 0

function main(Data)

   local Success, count = dup.isDuplicate(Data)

   if Success and count > N then
         iguana.logInfo('Filtering duplicate message')
         return    
   end

   queue.push{data=Data}
end

Here’s a screen shot of it in action:

And here’s a copy of the source code of the script. I recommend that you put it into a re-useable module called ‘dup’ or ‘duplicate’. Note that you’ll need to adjust the username and password for your environment:

local dup = {}

-- Edit these for your environment
local UserName='admin'
local Password='password'

local function GetMessageId(Message)
   local In = hl7.parse{vmd='matchAll.vmd',data=Message}
   return In.MSH[10]:nodeValue()
end

function dup.isDuplicate(Message)
   GetMessageId(Message)

   local X = net.http.get{url='http://localhost:6543/api_query',
      parameters={
         username=UserName, 
         password=Password,
         source=iguana.channelName(),
         filter=GetMessageId(Message),
         type='Message'
      },live=true}  
   X = xml.parse{data=X}
   local dupsCount = 0
   for i = 1,X.export:childCount('message') do
      if X.export:child("message", i).data:nodeValue() == Message then
         dupsCount = dupsCount +1
      end
   end
   if dupsCount > 0 then 
      return true, dupsCount  -- we got a duplicate!
   end

   return false, 0
end

return dup

The script works very simply. It extracts the “Message Control ID” from the HL7 message. It queries all the messages for this channel and it uses the message control id as a filter. Because of the full text search index this query is fast.

Then the script loops through the messages that exist in the log and compares to see if they match the current message. This means that if a system is sending different messages with the same Message Control ID that it won’t break. It will return true if it finds a match and false it does not. It will also return a count of matches if found.

If this channel Source component is LLP Listener, and Filter script is running in Filter component, then in necessary we will have exactly one copy of same message in Logs even before message gets processed by script in Filter. The N parameter compensates Source components processing traces and we would adjust value of N to be 1. Another example: if we apply filtering script directly in Source Translator script, then most possible N will be 0 since we have no previous processing by this channel itself and no respective log entries. The N parameter can be easily predicted.

We may say that N is a number, of existing in Logs duplicates of a message, which we wish to tolerate, to accommodate for specific channel configurations.

It is possible to read channel configuration from IguanaConfiguration.xml file programmatically and to calculate value for N, but this is not a general case. People may apply this script in different configurations and at different circumstances.

Done!

matchAll.vmd

Leave A Comment?