Search code examples
mirth

How do I extract the ACK from a webservice response in Mirth?


I have a destination which sends an HL7 v2 message to a WCF webservice. I've managed to get the message correctly to the webservice (after fixing various encoding problems) and I can confirm that the message is reaching the WCF endpoint correctly. However, after much hunting around in the forums and documentation, I am unable to correctly parse the ACK we receive back to indicate when an error has occurred.

The response coming back from the webservice looks like:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
    <s:Header/>
    <s:Body>
        <ProcessMessageResponse xmlns="http://www.bluewire-technologies.com/webservices">  
            <ProcessMessageResult>
               MSH|^~\&amp;|Epro|RGR|||||ACK||D||||||GBR|ASCII|
               MSA|AE||Empty message|
               ERR|^^^100|
            </ProcessMessageResult>
        </ProcessMessageResponse>
    </s:Body>
</s:Envelope>

The response contains an ACK in the ProcessMessageResult element. How to I extract this ACK from the response and pass it as the output of the destination? Will Mirth automatically parse the ACK and determine that there was an error?

I had thought that I needed some kind of transformer on the destination (called 'SOAP') and use something along the lines of:

var xml = responseMap.get('SOAP').getMessage(); 

and then extract the ProcessMessageResponse element but responseMap.get('SOAP') returns null so that seems the wrong approach.


Solution

  • I've now solved part of this thanks to an answer on the Mirth forums.

    To summarize, I use the following postprocessor to extract the ack and update the status:

    var s = new Namespace('http://schemas.xmlsoap.org/soap/envelope/');
    var bw = new Namespace('http://www.bluewire-technologies.com/webservices');
    
    var response = new XML($r('SOAP').getMessage());
    var ack = new XML(SerializerFactory.getHL7Serializer().toXML(response.s::Body.bw::ProcessMessageResponse.bw::ProcessMessageResult.toString()));
    
    var ackCode = ack.MSA['MSA.1']['MSA.1.1'].toString();
    if(ackCode == 'AE')
    {
        var errorMessage = ack.MSA['MSA.3']['MSA.3.1'].toString();
        var messageController = com.mirth.connect.server.controllers.DefaultMessageObjectController.create();
        var channelStatisticsController = com.mirth.connect.server.controllers.DefaultChannelStatisticsController.create();
    
        messageObject.getContext().put("replace", "true"); // yuk - this is to make setError below work.
        messageController.setError(messageObject, null, errorMessage, null, null);
        channelStatisticsController.decrementSentCount(new java.lang.String(channelId));
    }
    

    Not pretty, but it works...