XML Replay: Difference between revisions

From DataFlex Wiki
Jump to navigationJump to search
No edit summary
Line 25: Line 25:


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.
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

Revision as of 18:40, 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