Creating the Web Service Client Program

This part of the tutorial looks at the COBOL program that issues the web request, focusing on the XML manipulations as well as the CALLs that interact with RMNet.

After a Fahrenheit temperature is accepted from the operator, the following statements create the SOAP envelope for the request:

XML EXPORT FILE
    Fahrenheit-To-Celsius
    "TempFahrenheitRequest.xml"
    "Fahrenheit-To-Celsius"
    "TempConvertRequestF2C.xsl".
if not XML-OK go to z.
XML EXPORT TEXT
    Fahrenheit-To-Celsius
    request-payload
    request-len
    "Fahrenheit-To-Celsius"
    "TempConvertRequestF2C.xsl".
if not XML-OK go to z.

The XML EXPORT FILE is for illustrative purposes only. It produces a copy of the XML that is created by the XML EXPORT TEXT. A production program would not include the XML EXPORT FILE. At the end of these statements, request-payload and request-len point at the text string that contains the XML to be sent to the web service as the payload in the HTTP request.

call "NetInit"
  giving
    response-status.

call "HttpPost"
  using
    Post-Address
    Content-Type
    request-payload
    request-len
    response-payload
    response-len
    Desired-SOAP-Action
  giving
    response-status.

NetInit is called to initialize the RMNet interface. Then, HttpPost is called to make a POST request to the URL contained in Post-Address. The Content-Type parameter describes the MIME type and character encoding of the payload. In the case of a SOAP request, the MIME type should always be text/xml.

If you were creating a POST to a web form, then your payload would not be XML, and the content type would be application/x-www-form-urlencoded.

The request-payload and request-len parameters are the pointer and length of the request payload (created in the XML EXPORT TEXT). The response-payload and response-len parameters receive the pointer and length of the response payload received in the HTTP response to the POST. Finally, the last parameter, used to supply extra HTTP headers, (named Desired-SOAP-Action here) adds the SOAPAction header name/value pair. (The need for a SOAPAction header was discovered when we used soapUI to look at the WSDL.)

Following the CALL to HttpPost, there follows some error checking:

set address of http-response to response-payload.

display "Response: ", response-status.

if not response-status = 0
  call "NetGetError" using response-payload response-len
                     giving response-status-2  
  set address of http-response to response-payload
  display "Error! ", response-status
  display "Error message: ", http-response(1:response-len)
  call "NetFree" using response-payload
  go to z
end-if

This is 'normal' error processing if the response status is nonzero. Note that the reuse of response payload pointer is a convenience

Finally, the response document, a SOAP envelope containing the response value, needs to be imported.

           XML FREE TEXT
               request-payload.

           if response-payload = NULL
               display "Error:  NULL pointer returned", line 10, blink
               accept a-single-char prompt
               go to z
           end-if.

           XML PUT TEXT
               response-payload
               response-len
               "TempFahrenheitResponse.xml".
           if not XML-OK go to z.

           XML IMPORT TEXT
               Fahrenheit-To-Celsius-Response
               response-payload
               response-len
               "Fahrenheit-To-Celsius-Response"
               "TempConvertResponseF2C.xsl".
           if not XML-OK go to z.

           call "NetFree"
             using
               response-payload.

           call "NetCleanup".

The request, which is memory allocated by XML Extensions, is returned; it is no longer needed. The XML PUT TEXT is for illustrative purposes, and would not be present in a production environment. The XML IMPORT TEXT imports the required data from the response SOAP envelope, using the XSLT developed above. At this point the response payload is no longer needed and the memory is returned using NetFree. Finally, NetCleanup is called to terminate RMNet processing, allowing it to release any resources that may have been acquired during its processing.