Attempting to acknowledge Quest Diagnostics results
By: Johnathon Wright on: September 09, 2013
I am successfully retrieving HL7 messages, including data and embedded PDF, via Ruby. I wish I had kept better notes... so I'm doing that now. My current challenge is to send an ACK message.
I can tell that the people at Quest were very satisfied with their recent guidance to me, which I can fairly summarize as:
Oh, you were using our *NEW* API. No one is using that yet. Go back to the one labeled "legacy."
Very enterprisey in its own way.
The endpoint I am using to retrieve results is:
https://cert.hub.care360.com:443/resultsHub/observations/hl7
The documentation describes this endpoint as:
This is to retrieve HL7 ORU messages only from the HUB, this would also include embedded pdfs in the HL7 ORU message
Do not attempt to make sense of the fact that it says we provide only x, and also y and z.
So the WSDL file I have includes the following actions:
>> Interfaces::Quest.new.soap_interface.client.wsdl.soap_actions
=> [:get_results, :get_more_results, :acknowledge_results, :get_hl7_results, :get_more_hl7_results, :acknowledge_hl7_results, :get_provider_accounts]
I am using 'get_results' ( which presumably would translate to GetResults in the actual WSDL.) Looking at the parameters I'm sending and the WSDL file, it seems like I need to include any ComplexType names as a key with the parameters of that complex type being in a hash.
Since I'm using 'getresults' to get results, I'm going to try using 'acknowledgeresults' to ... acknowledge... the ... results.
Here's the WSDL:
<message name="acknowledgeResults">
<part xmlns:partns="http://www.w3.org/2001/XMLSchema"
type="partns:string"
name="requestId">
</part>
<part xmlns:partns="java:language_builtins.lang"
type="partns:ArrayOfString"
name="acknowledgeMessages">
</part>
</message>
no complex types here.
Question: does the Request ID come from Quest's response to my original SOAP message? Or the ID of the HL7 message I'm acknowledging? Because it would be more complicated, I'm going to assume the first one.
Question There are two parts. Are these supposed to be sent as just two child nodes of a collection? If not, how?
I'm going to their HUB MedPlus HIT toolkit (13.2) for examples... which I will pull from sample_messages/soap/results/legacy/observation/acknowledgeResults.xml
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:acknowledgeResults soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://medplus.com/observation">
<ack href="#id0"/>
</ns1:acknowledgeResults>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:Acknowledgment" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="java:com.medplus.serviceHub.results.webservice.observation">
<acknowledgedResults soapenc:arrayType="ns2:AcknowledgedResult[1]" xsi:type="soapenc:Array">
<acknowledgedResults href="#id1"/>
</acknowledgedResults>
<requestId xsi:type="xsd:string">bd078d98c0a83801008397d28f1918ca</requestId>
</multiRef>
<multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns3:AcknowledgedResult" xmlns:ns3="java:com.medplus.serviceHub.results.webservice.observation" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<ackCode xsi:type="xsd:string">ACK</ackCode>
<documentIds soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array">
<documentIds xsi:type="xsd:string">19784</documentIds>
</documentIds>
<rejectionReason xsi:type="xsd:string" xsi:nil="true"/>
<resultId xsi:type="xsd:string">bd078f8cc0a8380100c6235dadf0c33e</resultId>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
SOAP envelopes and whatever-else aside, the structure seems to be:
acknoledgeResults * ack href="something" * multiRef ** acknowledgedResults **acknowledgedResults href * requestId * multiRef ** acknowledgedResults **acknowledgedResults href * requestId multiRef * ackCode ACK ** documentIds *** documentIds 19784 ** rejectionReason nil ** resultId bd078f8cc0a8380100c6235dadf0c33e
Well, that XML doesn't match up with the 'parts' from the WSDL at all, so ... that must be the wrong example file.
So now I'll try sample messages\soap\results\observation:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:res="http://medplus.com/results">
<soapenv:Header/>
<soapenv:Body>
<res:acknowledgeResults>
<res:RetrieveResultsAcknowledge>
<ackMessages>
<controlId>ca3ce8a6ac1262891d36757221fb4e7b</controlId>
<message>TVNIfF5+XCZ8fEJyZW50IFByb3ZpZGVyIEFjY291bnR8TEFCfEJyZW50IFByb3ZpZGVyfDIwMTMwMjExMDAwMDAwLjAwMDAtMDcwMHx8QUNLfGJzMjV8RHwyLjMNTVNBfENBfGJzMjV8U1VDQ0VTU0ZVTA0=</message>
</ackMessages>
<ackMessages>
<controlId>ca3ce8b3ac1262891d36892e9c4b5be3</controlId>
<message>TVNIfF5+XCZ8fEJyZW50IFByb3ZpZGVyIEFjY291bnR8TEFCfEJyZW50IFByb3ZpZGVyfDIwMTMwMjExMDAwMDAwLjAwMDAtMDcwMHx8QUNLfGJzMjV8RHwyLjMNTVNBfENBfGJzMjV8U1VDQ0VTU0ZVTA0=</message>
</ackMessages>
<requestId>ca3ce788ac1262891c8775475f428cf8</requestId>
<requestParameters>
<parameterName></parameterName>
<parameterValue></parameterValue>
</requestParameters>
<resultServiceType>observation</resultServiceType>
</res:RetrieveResultsAcknowledge>
</res:acknowledgeResults>
</soapenv:Body>
</soapenv:Envelope>
This doesn't match either.
In the absence of examples that match the documentation, I'm taking a step back. I know I have one endpoint working... resultsRequest. So I'm going to look through the examples for any request that is structured in the way mine is structured.
- sample messages\soap\results\legacy\observation\getResults.xml is somewhat similar, except that it has multiRef nodes ... but looking at it, the multiRef node has an ID which you could plug in above and ... presumably... get rid of the multiRef node as you replace the thing above with its contents... and then it would be the same.
- sample messages\soap\results\legacy\observation\getResults-by-provider-acct is similar but not as good a match.
- sample messages\soap\results\legacy\observation\getResults-dates seems similar... would need a diff to properly compare them.
None of the other examples in sample messages\soap\results are even close. The other options under "sample messages" are "demographics" and "orders", so not relevant to me.
So now I'm going to reverse-engineer an ACK using sample messages\soap\results\legacy\observation\acknowledgeResults.xml
<?xml version="2.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:acknowledgeResults soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns1="http://medplus.com/observation">
<ack href="#id0"/>
</ns1:acknowledgeResults>
<multiRef id="id0" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns2:Acknowledgment" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:ns2="java:com.medplus.serviceHub.results.webservice.observation">
<acknowledgedResults soapenc:arrayType="ns2:AcknowledgedResult[1]" xsi:type="soapenc:Array">
<acknowledgedResults href="#id1"/>
</acknowledgedResults>
<requestId xsi:type="xsd:string">bd078d98c0a83801008397d28f1918ca</requestId>
</multiRef>
<multiRef id="id1" soapenc:root="0" soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xsi:type="ns3:AcknowledgedResult" xmlns:ns3="java:com.medplus.serviceHub.results.webservice.observation" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<ackCode xsi:type="xsd:string">ACK</ackCode>
<documentIds soapenc:arrayType="xsd:string[1]" xsi:type="soapenc:Array">
<documentIds xsi:type="xsd:string">19784</documentIds>
</documentIds>
<rejectionReason xsi:type="xsd:string" xsi:nil="true"/>
<resultId xsi:type="xsd:string">bd078f8cc0a8380100c6235dadf0c33e</resultId>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
clearing away the soap headers and after some substitution:
ns1:acknowledgeResults
So this is pretty reasonable seeming. There are double acknowledgedResults nodes... one of them was the target of a multiRef substitution so it's hard to know whether to keep or discard that without someone who stares at these things all day... I'll just experiment. The other target of a multiRef substitution was the ack node... seems like you would want to keep that one. So one of the instances makes me think you do keep the node, the other makes me think you discard it. We'll just find out.
I want to compare my existing parameters to the example I like from the samples:
ns1:getResults
compare this with the function I use to generate parameters:
def param_lambda
lambda {
{
'resultsRequest' =>
{
'startDate' => self.start_date.to_date.to_s(:mdy),
'endDate' => self.end_date.to_date.to_s(:mdy),
'maxMessages' => 30,
'providerAccounts' => 'THO',
'retrieveFinalsOnly' => 'false'
}
}
}
end
def soap_interface
Interfaces::SOAP.new(
:wsdl_location => self.class.wsdl_location,
:wsdl_action => 'get_results',
:param_lambda => self.param_lambda,
:username => CONFIG[:quest_username],
:password => CONFIG[:quest_password]
)
end
All that gives me the following request:
SOAP request: https://cert.hub.care360.com/resultsHub/observations/hl7
SOAPAction: "acknowledgeResults", Content-Type: text/xml;charset=UTF-8, Content-Length: 954
<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://medplus.com/resultsHub/observations" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ins0="java:com.medplus.serviceHub.results.webservice" xmlns:ins1="java:com.medplus.serviceHub.results.webservice.printable" xmlns:ins2="java:javax.xml.rpc" xmlns:ins3="java:javax.xml.soap" xmlns:ins4="java:language_builtins.lang"><env:Body><acknowledgeResults><wsdl:ack><wsdl:acknowlegedResults>
wsdl:requestIdbd078d98c0a83801008397d28f1918ca/wsdl:requestIdwsdl:acknowledgedResultswsdl:ackCodeACK/wsdl:ackCode
wsdl:documentIds80000000000000026053/wsdl:documentIds
and response:
Savon::SOAP::Fault: (env:Server) Exception during processing: javax.xml.soap.SOAPException: Found SOAPElement [<wsdl:ack>
wsdl:acknowlegedResultswsdl:requestIdbd078d98c0a83801008397d28f1918ca/wsdl:requestIdwsdl:acknowledgedResults
wsdl:ackCodeACK/wsdl:ackCodewsdl:documentIds80000000000000026053/wsdl:documentIds
Interesting. So ack > acknowledgeResults has two child elements... requestId and acknoledgedResults. I found some typos above ( the first one that comes to mind is id3/id2 ) so it isn't a stretch to assume that the inner acknowledgedResults should be acknowledgeMessages.
New request:
SOAP request: https://cert.hub.care360.com/resultsHub/observations/hl7
SOAPAction: "acknowledgeResults", Content-Type: text/xml;charset=UTF-8, Content-Length: 954
<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://medplus.com/resultsHub/observations" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ins0="java:com.medplus.serviceHub.results.webservice" xmlns:ins1="java:com.medplus.serviceHub.results.webservice.printable" xmlns:ins2="java:javax.xml.rpc" xmlns:ins3="java:javax.xml.soap" xmlns:ins4="java:language_builtins.lang"><env:Body><acknowledgeResults><wsdl:ack><wsdl:acknowlegedResults>
wsdl:requestIdbd078d98c0a83801008397d28f1918ca/wsdl:requestIdwsdl:acknowledgeMessageswsdl:ackCodeACK/wsdl:ackCode
wsdl:documentIds80000000000000026053/wsdl:documentIds
Same error:
Savon::SOAP::Fault: (env:Server) Exception during processing: javax.xml.soap.SOAPException: Found SOAPElement [<wsdl:ack>
wsdl:acknowlegedResultswsdl:requestIdbd078d98c0a83801008397d28f1918ca/wsdl:requestIdwsdl:acknowledgeMessages
wsdl:ackCodeACK/wsdl:ackCodewsdl:documentIds80000000000000026053/wsdl:documentIds
so I'll try getting rid of acknowledgedResults... just ... a guess.
SOAP request: https://cert.hub.care360.com/resultsHub/observations/hl7
SOAPAction: "acknowledgeResults", Content-Type: text/xml;charset=UTF-8, Content-Length: 903
<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://medplus.com/resultsHub/observations" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ins0="java:com.medplus.serviceHub.results.webservice" xmlns:ins1="java:com.medplus.serviceHub.results.webservice.printable" xmlns:ins2="java:javax.xml.rpc" xmlns:ins3="java:javax.xml.soap" xmlns:ins4="java:language_builtins.lang"><env:Body><acknowledgeResults><wsdl:ack>
wsdl:requestIdbd078d98c0a83801008397d28f1918ca/wsdl:requestIdwsdl:acknowledgeMessageswsdl:ackCodeACK/wsdl:ackCode
wsdl:documentIds80000000000000026053/wsdl:documentIds
Try getting rid of the ACK parent node
SOAP request: https://cert.hub.care360.com/resultsHub/observations/hl7
SOAPAction: "acknowledgeResults", Content-Type: text/xml;charset=UTF-8, Content-Length: 882
<?xml version="1.0" encoding="UTF-8"?><env:Envelope xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:wsdl="http://medplus.com/resultsHub/observations" xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ins0="java:com.medplus.serviceHub.results.webservice" xmlns:ins1="java:com.medplus.serviceHub.results.webservice.printable" xmlns:ins2="java:javax.xml.rpc" xmlns:ins3="java:javax.xml.soap" xmlns:ins4="java:language_builtins.lang"><env:Body><acknowledgeResults>
wsdl:requestIdbd078d98c0a83801008397d28f1918ca/wsdl:requestIdwsdl:acknowledgeMessageswsdl:ackCodeACK/wsdl:ackCode
wsdl:documentIds80000000000000026053/wsdl:documentIds
<env:Envelope xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:env="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><env:Header></env:Header>
env:Body
It's shocking to me how different this is from their example and docs.... but whatever. Moving on. Since I used the IDs from their sample message it's not surprising we got this kind of error.
But even when I replace it with what I suspect is the data they want, I'm still getting that error. I think I need to do some nested document_id stuff.