Adding business logic to the generated PL/I template

For each operation in the WSDL, an operationNameHandler procedure and an operationNameImpl procedure are created in the generated template. The operationNameHandler procedure contains protocol logic while the operationNameImpl procedure is ready to be filled out and customized with your business logic.

For example, a service WSDL file has an import statement that references operation definitions from an XSD file.
<wsdl:types>
   <xs:schema targetNamespace="http://www.fastbank.com/FAST247/">
	    <xs:import namespace="http://www.interface.fastbank.com/FAST247/"
          schemaLocation="Operations.xsd">
      </xs:import>
	 </xs:schema>
</wsdl:types>
In the XSD file, the checkBalanceRequest and checkBalanceresponse operations are defined:
<xs:complexType name="balance">
		<xs:sequence>
			<xs:element name="status" type="xs:boolean" />
			<xs:element name="amount" type="xs:decimal" />

		</xs:sequence>
	</xs:complexType>

	<xs:complexType name="checkBalance">
		<xs:sequence>
			<xs:element name="accountno" type="xs:long" />
		</xs:sequence>
	</xs:complexType>

	<xs:element name="checkBalanceRequest" type="account:checkBalance" />
	<xs:element name="checkBalanceResponse" type="account:balance" />
For each operation in the wsdl:binding section, there is an input message, an output message, and a fault message:
<wsdl:operation name="CheckBalanceOperation">
		<soap:operation soapAction="CheckBalanceOperation" style="document" />
		<wsdl:input name="CheckBalanceRequest">
			<soap:body parts="CheckBalancePart" use="literal" />
		</wsdl:input>
		<wsdl:output name="CheckBalanceResponse">
			<soap:body parts="CheckBalancePart" use="literal" />
		</wsdl:output>
		<wsdl:fault name="ServiceExceptionFault">
			<soap:fault use="literal" name="ServiceExceptionFault" />
		</wsdl:fault>
	</wsdl:operation>
This operation is specified in the correlator entry:
<correlatorEntry operationName="CheckBalanceOperation" portName="FAST247Port" 
serviceName="FAST247Service">

These input and output elements are directly reflected in the generated PL/I application template. Add necessary business logic in the implementation procedure for each operation. The generated PL/I application template uses the DFSQGETS and DFSQSETS APIs to retrieve and set the SOAP body language structure from the IMS message queue.

The operationNameHandler procedure checks for and retrieves the @dfs_soap_header structure before retrieving the request body structure. If the dfs_soap_header_ptr pointer is null, it means that no SOAP header element is present in the request SOAP message. You can implement application-specific processing of the information that is contained in the SOAP header in the operationNameImpl procedures.

The following sample shows a generated operationNameImpl procedure. The dfs_soap_header_ptr pointer information is available to the PutOperationImpl procedure.
CheckBalanceOperationImpl: procedure(iopcb_mask_ptr, dfs_soap_header_ptr,
 checkBalanceRequest_ptr, checkBalanceResponse_ptr, ServiceException_ptr)
 internal;
 
   dcl iopcb_mask_ptr pointer byvalue;
   dcl dfs_soap_header_ptr pointer byvalue; 
   dcl checkBalanceRequest_ptr pointer byvalue;
   dcl checkBalanceResponse_ptr pointer byaddr;
   dcl ServiceException_ptr pointer byaddr;
   ...
   return;

 end CheckBalanceOperationImpl;

You add your back-end business logic to process the SOAP header. If the dfs_soap_header_ptr pointer is not null, parse the @dfs_soap_header structure. The dfs_soap_header_ptr providers the pointer to the header data structure.
CheckBalanceOperationImpl: procedure(iopcb_mask_ptr, dfs_soap_header_ptr,
 checkBalanceRequest_ptr, checkBalanceResponse_ptr, ServiceException_ptr)
 internal;
 
   dcl iopcb_mask_ptr pointer byvalue;
   dcl dfs_soap_header_ptr pointer byvalue; 
   dcl checkBalanceRequest_ptr pointer byvalue;
   dcl checkBalanceResponse_ptr pointer byaddr;
   dcl ServiceException_ptr pointer byaddr;

   /* Add your custom business logic and SOAP header processing code.
    * The PARSEHDR procedure is a user-supplied procedure that parses  
    * the SOAP header by using a parser such as PLISAXA. It must be
    * declared before it is called. 
    */
 if (dfs_soap_header_ptr ^= sysnull()) then do;
     call PARSEHDR(addr(@dfs_soap_header.header_xml(1)),
          @irz_soap_header.header_xml_cnt);
   end;

   /* Add your business logic for generating a Fault */	
   if (checkBalanceRequest.accountno < 9167889 |
     checkBalanceRequest.accountno > 9167889) then do;

     allocate ServiceException set(ServiceException_ptr);
     ServiceException.faultcode = 'env:Client';
     ServiceException.faultstring = 'The specified account no '
       || trim(checkBalanceRequest.accountno)
       || ' is invalid or undefined.';
     ServiceException.faultactor = trim(packagename())
       || '#' || trim(procedurename());
     ServiceException.exCode = '10999';
     ServiceException.exDescription = 'The specified account no '
       || trim(checkBalanceRequest.accountno)
       || ' is invalid or undefined.';

     return;
   end;

After processing the SOAP header, handle the request message and the response message in the SOAP body. The following example shows the allocating of the structure that handles the response from the CheckBalance operation.
	/* Allocate the response data structure for returning a response
	allocate checkBalanceResponse
		set (checkBalanceResponse_ptr);

  checkBalanceResponse.amount = 987.50;
  checkBalanceResponse.status = '1'b;

  return;
 
 end CheckBalanceOperationImpl;