XML Replay: Difference between revisions
No edit summary |
|||
Line 33: | Line 33: | ||
Boolean bOK | Boolean bOK | ||
String sServer sURI | String sServer sURI | ||
Integer iTarg | Integer iTarg<br /> | ||
Get Create U_cXmlDomDocument to hoDoc | Get Create U_cXmlDomDocument to hoDoc | ||
Set psDocumentName of hoDoc to (Value(oInput(Self))) | Set psDocumentName of hoDoc to (Value(oInput(Self))) | ||
Get LoadXmlDocument of hoDoc to bOK | Get LoadXmlDocument of hoDoc to bOK<br /> | ||
If not bOK Begin | If not bOK Begin | ||
Error 0 ("Could not load document" * psDocumentName(hoDoc)) | Error 0 ("Could not load document" * psDocumentName(hoDoc)) | ||
Procedure_Return | Procedure_Return | ||
End | End<br /> | ||
Get DocumentElement of hoDoc to hoMsg<br /> | |||
Get DocumentElement of hoDoc to hoMsg | |||
Get Create U_cXmlDomDocument to hoXML | Get Create U_cXmlDomDocument to hoXML | ||
Send AddChildProcessingInstruction of hoXML "xml" 'version="1.0"' // encoding="utf-8"' | Send AddChildProcessingInstruction of hoXML "xml" 'version="1.0"' // encoding="utf-8"' | ||
Get CreateDocumentElementNS of hoXML "http://schemas.xmlsoap.org/soap/envelope/" "soap:Envelope" to hoEnv | Get CreateDocumentElementNS of hoXML "http://schemas.xmlsoap.org/soap/envelope/" "soap:Envelope" to hoEnv | ||
Get AddElement of hoEnv "soap:Body" "" to hoBody | Get AddElement of hoEnv "soap:Body" "" to hoBody | ||
Get AppendNode of hoBody hoMsg to hoMsg | Get AppendNode of hoBody hoMsg to hoMsg<br /> | ||
Send ClearHeaders of oTfr<br /> | |||
Send ClearHeaders of oTfr | |||
Set psAcceptTypes of oTfr to "text/*" | Set psAcceptTypes of oTfr to "text/*" | ||
Set psContentTypeSent of oTfr to "text/xml; charset=UTF-8" | Set psContentTypeSent of oTfr to "text/xml; charset=UTF-8" | ||
Get AddHeader of oTfr "SOAPAction" ('"' + Value(oOperation(Self)) + '"') to bOk | Get AddHeader of oTfr "SOAPAction" ('"' + Value(oOperation(Self)) + '"') to bOk<br /> | ||
Get Value of oServer to sServer | Get Value of oServer to sServer | ||
Get Value of oURI to sURI | Get Value of oURI to sURI | ||
Set piRemotePort of oTfr to (Value(oPort(Self))) | Set piRemotePort of oTfr to (Value(oPort(Self)))<br /> | ||
Get HttpPostXmlNode of oTfr sServer sURI hoXML to hoXMLResponse<br /> | |||
Get HttpPostXmlNode of oTfr sServer sURI hoXML to hoXMLResponse | |||
If (hoXmlResponse=0) Set Value of oReturnedXML to "NO RESPONSE" | If (hoXmlResponse=0) Set Value of oReturnedXML to "NO RESPONSE" | ||
Else Set Value of oReturnedXML to (psXml(hoXmlResponse)) | Else Set Value of oReturnedXML to (psXml(hoXmlResponse))<br /> | ||
Send Destroy of hoXML | Send Destroy of hoXML | ||
If hoXMLResponse Send Destroy of hoXMLResponse | If hoXMLResponse Send Destroy of hoXMLResponse<br /> | ||
End_Procedure // InvokeService | End_Procedure // InvokeService |
Revision as of 17:45, 5 November 2007
Replaying Logged XML
When attempting to diagnose problems which occur within web service environments, it is often useful to be able to re-run the XML which triggered the problem, so as to be able to step through it in the Visual DataFlex Studio debugger. The XML passed to a web service can be logged (see XML logging for details of how this can be done) and this historic data can then be used to "replay" the offending call and see what probably happened.
Assuming you have access to the original XML (see XML logging), this can then be saved into a text file - usually with the extension ".xml". If this has been logged using the mechanism suggested in the XML logging article, it may need to be slightly doctored before being sent for replay. This is because, for obscure reasons, the message namespace gets attached to the first child element of the message XML, instead of to the parent itself, thus:
<MessageName> <ParameterName xmlns="http://myDomain/myURI"> <Element1>Foo</Element1> <Element2>Bar</Element2> <Element3>Etc.</Element3> </ParameterName> </MessageName>
Instead of the correct:
<MessageName xmlns="http://myDomain/myURI"> <ParameterName> <Element1>Foo</Element1> <Element2>Bar</Element2> <Element3>Etc.</Element3> </ParameterName> </MessageName>
Once this has been corrected (either manually or in your replay program), the XML is then ready for incorporation into a SOAP message for re-sending to you service, running under a debugger so you can set breakpoints and trace the execution through, step by step.
In order to do this however, you are going to need a client which operates at a lower level than the standard web service client class you are able to generate for your service. The following is an example of how you might do this.
Object oTfr is a cXmlHttpTransfer End_Object // oTfr Procedure InvokeService Handle hoXML hoXmlResponse hoEnv hoBody hoDoc hoMsg Boolean bOK String sServer sURI Integer iTarg
Get Create U_cXmlDomDocument to hoDoc Set psDocumentName of hoDoc to (Value(oInput(Self))) Get LoadXmlDocument of hoDoc to bOK
If not bOK Begin Error 0 ("Could not load document" * psDocumentName(hoDoc)) Procedure_Return End
Get DocumentElement of hoDoc to hoMsg
Get Create U_cXmlDomDocument to hoXML Send AddChildProcessingInstruction of hoXML "xml" 'version="1.0"' // encoding="utf-8"' Get CreateDocumentElementNS of hoXML "http://schemas.xmlsoap.org/soap/envelope/" "soap:Envelope" to hoEnv Get AddElement of hoEnv "soap:Body" "" to hoBody Get AppendNode of hoBody hoMsg to hoMsg
Send ClearHeaders of oTfr
Set psAcceptTypes of oTfr to "text/*" Set psContentTypeSent of oTfr to "text/xml; charset=UTF-8" Get AddHeader of oTfr "SOAPAction" ('"' + Value(oOperation(Self)) + '"') to bOk
Get Value of oServer to sServer Get Value of oURI to sURI Set piRemotePort of oTfr to (Value(oPort(Self)))
Get HttpPostXmlNode of oTfr sServer sURI hoXML to hoXMLResponse
If (hoXmlResponse=0) Set Value of oReturnedXML to "NO RESPONSE" Else Set Value of oReturnedXML to (psXml(hoXmlResponse))
Send Destroy of hoXML If hoXMLResponse Send Destroy of hoXMLResponse
End_Procedure // InvokeService