XML Logging: Difference between revisions

From DataFlex Wiki
Jump to navigationJump to search
mNo edit summary
Line 28: Line 28:
The trick is to make use of a ''client'' of you service ''within'' the service itself.  This in turn makes doing it a multi-stage process, since one can only create a client once the service is published and acessible.
The trick is to make use of a ''client'' of you service ''within'' the service itself.  This in turn makes doing it a multi-stage process, since one can only create a client once the service is published and acessible.


===Step 1===
====Step 1====
First you define your service:
First you define your service:


Line 39: Line 39:
  End_Object  // oLogSample<br />
  End_Object  // oLogSample<br />


===Step 2===
====Step 2====
Next you need to run the Web Service Client Class Generator (in the VDF Studio: File -> New -> Class -> Clint Web Service Class) on the WSDL for your service (Test Page -> Service Name -> Service Description, then copy the browser's Address window to the Web Service Client Class Generator's WSDL URL window and click "Parse", "Generate Class" and "OK" - plus "Yes" to overwrite if it already exists).
Next you need to run the Web Service Client Class Generator (in the VDF Studio: File -> New -> Class -> Clint Web Service Class) on the WSDL for your service (Test Page -> Service Name -> Service Description, then copy the browser's Address window to the Web Service Client Class Generator's WSDL URL window and click "Parse", "Generate Class" and "OK" - plus "Yes" to overwrite if it already exists).


===Step 3===
====Step 3====
Now you need to use and instanciate the client class you have just generated within your service:
Now you need to use and instanciate the client class you have just generated within your service:


Line 56: Line 56:
  End_Object  // oLogSample<br />
  End_Object  // oLogSample<br />


===Step 4===
====Step 4====
Next you need to  
Next you need to create a procedure that will utilise that client to ''reconstitute'' the XML from the data that your published method receives:
 
Object oLogSample is a cWebService<br />
  Use cWSLogSample.pkg
  Object oOwnService is a cWSLogSample
  End_Object  // oOwnService<br />
  // LogMsg:
  Procedure LogMsg Variant Data String sOp String sName Handle hoObj
  End_Procedure  // LogMsg<br />
  { Published = True  }
  { Description = "Interface for sending something to the system" }
  Procedure  SendSomething tSomeDocumentType Doc<br />
      // Code that actually does stuff...<br />
  End_Procedure  // SendSomething<br />
End_Object  // oLogSample<br />


==Replaying logged XML==
==Replaying logged XML==

Revision as of 15:29, 5 November 2007

With Service Oriented systems it can be very important to have a log of the XML that has been sent and received by the systems involved, for purposes of determining exactly what went on to cause any given situation (usually an error situation, otherwise there would be no need to look into it). This article looks at how such things can be done and how the logged XML can then be used to investigate the problem.


Web Service Client XML Logging

Logging the XML sent by a web service client is relatively easy. It simply involves, following the service invocation, getting the psXML property of the object pointed to by the phoSoapRequest property of your web service client object. Something like this:

tSomeInput Input
tSomeOutput Output
String  sXML
Get wsSomeOp of oXyzService Input to Output
Move (psXML(phoSoapRequest(oXyzService(Self)))) to sXML

Or, more verbosely:

tSomeInput Input
tSomeOutput Output
String  sXML
Handle  hoSoapReq
Get wsSomeOp of oXyzService Input to Output
Get phoSoapRequest of oXyzService to hoSoapReq Get psXML of hoSoapReq to sXML

Either way you now have the XML sent by your web service client and can log it in whatever way you require.

Web Service XML Logging

There is a very real difficulty regarding accessing the XML which is passed it a VDF Web Service (at least so far as revisions up to VDF 12.1 are concerned). The problem is that the original XML is nowhere available to the VDF program. One possible solution would be to employ some kind of HTTP proxy on the server involved, which would receive the XML (actually the HTTP within which the XML is wrapped) before it reached IIS, log that, then pass it on to IIS. However here we are going to concern ourselves only with the best that can be managed from within the VDF programming environment at the moment (November 2007).

The trick is to make use of a client of you service within the service itself. This in turn makes doing it a multi-stage process, since one can only create a client once the service is published and acessible.

Step 1

First you define your service:

Object oLogSample is a cWebService
{ Published = True } { Description = "Interface for sending something to the system" } Procedure SendSomething tSomeDocumentType Doc
// Code that actually does stuff...
End_Procedure // SendSomething
End_Object // oLogSample

Step 2

Next you need to run the Web Service Client Class Generator (in the VDF Studio: File -> New -> Class -> Clint Web Service Class) on the WSDL for your service (Test Page -> Service Name -> Service Description, then copy the browser's Address window to the Web Service Client Class Generator's WSDL URL window and click "Parse", "Generate Class" and "OK" - plus "Yes" to overwrite if it already exists).

Step 3

Now you need to use and instanciate the client class you have just generated within your service:

Object oLogSample is a cWebService
Use cWSLogSample.pkg Object oOwnService is a cWSLogSample End_Object // oOwnService
{ Published = True } { Description = "Interface for sending something to the system" } Procedure SendSomething tSomeDocumentType Doc
// Code that actually does stuff...
End_Procedure // SendSomething
End_Object // oLogSample

Step 4

Next you need to create a procedure that will utilise that client to reconstitute the XML from the data that your published method receives:

Object oLogSample is a cWebService
Use cWSLogSample.pkg Object oOwnService is a cWSLogSample End_Object // oOwnService
// LogMsg: Procedure LogMsg Variant Data String sOp String sName Handle hoObj End_Procedure // LogMsg
{ Published = True } { Description = "Interface for sending something to the system" } Procedure SendSomething tSomeDocumentType Doc
// Code that actually does stuff...
End_Procedure // SendSomething
End_Object // oLogSample

Replaying logged XML