Using the enhanced templates, IMS application programmers may immediately focus on writing or integrating business logic to process or create the input, output, or fault structures respective to each operation implemented by the MPP. The following figure illustrates how the separation of protocol-level logic from business logic is implemented in the enhanced templates.

As shown in the above figure, protocol-level logic exists in code-complete procedures named OperationNameHandler that are dedicated to handling interactions with the IMS Message Queue and IRZPWSIO APIs on behalf of the respective user-written business logic in procedures named OperationNameImpl. All of the user-written business logic must be entered into the OperationNameImpl procedures. At execution time, OperationNameImpl procedures are invoked by their respective OperationNameHandler procedure.
*process macro not('¬') or('|') rules(nolaxdcl);
*process limits(name(100) extname(8) fixeddec(15,31) fixedbin(31,63));
*process system(IMS) display(std);
/*********************************************************************
* IBM Rational Developer for System z
* Enterprise Service Tools (EST)
* Single-service Projects (XSE)
* IMS Enterprise Suite SOAP Gateway
* Web Service Provider Template MPP
*
* Date created: 2011-05-17 11:31:39 PDT
* UUID: be97872d-c773-4e42-b9bd-f8ac4d45c450
* INSTALLATION: 8.3.100
********************************************************************/
WSPOC1Package: package exports(*);
/* IMS PL/I service provider include
*/
%INCLUDE IRZPWSH;
/* WSDL2ELS language structures
*/
%INCLUDE WSPOC1;
/*-------------------------------------------------------------------*
* Procedure: WSPOC1
* Description: Implementation of a Web service provider MPP for ser
* vice "WS_poc_1" and binding "WS_poc_1_Binding" of the Web service
* definition file "WS_PoC_1.wsdl".
*------------------------------------------------------------------*/
WSPOC1: procedure(iopcb_mask_ptr) options(main);
dcl iopcb_mask_ptr pointer;
dcl host_text_1 char(1024) varying init('');
dcl host_text_2 char(1024) varying init('');
/* Begin mainline logic.
*/
@irz_iopcb_mask_ptr = iopcb_mask_ptr;
@irz_cee_feedback_ptr = addr(@irz_cee_feedback);
call ProcessMessages();
/* End mainline logic.
*/
return;
/*-------------------------------------------------------------------*
* Procedure: ProcessMessages
* Description: Retrieve the IRZPWSIO message header from the IMS Me
* ssage Queue and invoke a handler procedure based on the service c
* ontext.
*------------------------------------------------------------------*/
ProcessMessages: procedure internal;
/* Allocate memory for the IRZPWSIO message header and copy it fro
m the IMS Message Queue.
*/
allocate @irz_async_msg_header set (@irz_async_msg_header_ptr);
call CEETDLI(@irz_dli_get_unique, @irz_iopcb_mask,
@irz_async_msg_header);
/* Branch to a handler procedure corresponding to the operation ci
ted in the service context.
*/
do while(@irz_iopcb_mask.iopcb_status_code =
@irz_dli_status_ok);
select(@irz_async_msg_header.service_name);
when('WS_poc_1') do;
select(@irz_async_msg_header.operation_name);
when('getteam_1_0') do;
call getteam_1_0Handler;
end;
when('setteam_1_0') do;
call setteam_1_0Handler;
end;
when('ping_1_0') do;
call ping_1_0Handler;
end;
otherwise do;
host_text_1 = @irz_async_msg_header.operation_name;
host_text_2 = @irz_async_msg_header.service_name;
call LogEvent(trim(packagename()) || '#'
|| trim(procedurename()) || '(): Error, '
|| 'operation name "' || trim(host_text_1) || '" '
|| 'is not valid for service name "'
|| trim(host_text_2) || '".');
end;
end;
end;
otherwise do;
host_text_1 = @irz_async_msg_header.service_name;
call LogEvent(trim(packagename()) || '#'
|| trim(procedurename()) || '(): Error, '
|| 'service name "' || trim(host_text_1) || '" '
|| 'is not valid or is not implemented by this '
|| 'application.');
end;
end;
call CEETDLI(@irz_dli_get_unique, @irz_iopcb_mask,
@irz_async_msg_header);
end;
if (@irz_iopcb_mask.iopcb_status_code ¬=
@irz_dli_end_messages) then do;
host_text_1 = @irz_iopcb_mask.iopcb_status_code;
call LogEvent(trim(packagename()) || '#'
|| trim(procedurename()) || '(): Error, '
|| 'CEETDLI.GU(@irz_async_msg_header), '
|| 'iopcb_status_code: '
|| trim(host_text_1) || '.');
end;
free @irz_async_msg_header;
return;
end ProcessMessages;
/*-------------------------------------------------------------------*
* Procedure: getteam_1_0Handler
* Description: Get the request language structure for operation "ge
* tteam_1_0" from the IMS Message Queue using the IRZQGETS API, inv
* oke user-written implementation, set the response or fault langua
* ge structure and commit it to the IMS Message Queue using the IRZ
* QSETS API. Finally, deallocate language structures.
*------------------------------------------------------------------*/
getteam_1_0Handler: procedure internal;
/* Get the request language structure from the IMS Message Queue u
sing the IRZQGETS API.
*/
@irz_struct_name = 'getteam_1_0';
@irz_struct_type = @irz_soap_body_struct;
@irz_struct_ptr = null();
@irz_struct_size = 0;
@irz_debug = '0'b;
call IRZQGETSWrapper(procedurename());
if (@return_code = @irz_success) then do;
getteam_1_0_ptr = @irz_struct_ptr;
end; else do;
return;
end;
/* Invoke user-written implementation of operation "getteam_1_0" p
assing pointers to the request, response, and fault language struc
tures.
*/
getteam_1_0Response_ptr = null();
ServiceException_ptr = null();
call getteam_1_0Impl(@irz_iopcb_mask_ptr, getteam_1_0_ptr, getteam_1_
0Response_ptr, ServiceException_ptr);
/* Set the response or fault language structure for operation "get
team_1_0" and commit it to the IMS Message Queue using the IRZQSET
S API.
*/
if (getteam_1_0Response_ptr ¬= null()) then do;
@irz_struct_name = 'getteam_1_0Response';
@irz_struct_type = @irz_soap_body_struct;
@irz_struct_ptr = getteam_1_0Response_ptr;
@irz_struct_size = storage(getteam_1_0Response);
end; else if (ServiceException_ptr ¬= null()) then do;
@irz_struct_name = 'ServiceException';
@irz_struct_type = @irz_soap_fault_struct;
@irz_struct_ptr = ServiceException_ptr;
@irz_struct_size = storage(ServiceException);
end;
@irz_commit_structs = '1'b;
@irz_debug = '0'b;
call IRZQSETSWrapper(procedurename());
/* Deallocate language structures.
*/
if (getteam_1_0_ptr ¬= null()) then do;
call plifree(getteam_1_0_ptr);
getteam_1_0_ptr = null();
end;
if (getteam_1_0Response_ptr ¬= null()) then do;
call plifree(getteam_1_0Response_ptr);
getteam_1_0Response_ptr = null();
end;
if (ServiceException_ptr ¬= null()) then do;
call plifree(ServiceException_ptr);
ServiceException_ptr = null();
end;
return;
end getteam_1_0Handler;
/*-------------------------------------------------------------------*
* Procedure: getteam_1_0Impl
* Description: Implement the business logic for operation "getteam_
* 1_0" using the following steps: (1) Process the request language
* structure "getteam_1_0", (2) Allocate and fill in the response la
* nguage structure "getteam_1_0Response" or a fault language struct
* ure from the set {ServiceException}. (3) Finally, set the respect
* ive response or fault language structure pointer before returning
* to the operation handler (Handler) procedure. Note: If an error
* occurs that requires a rollback, use parameter iopcb_mask_ptr to
* access the IOPCB.
*------------------------------------------------------------------*/
getteam_1_0Impl: procedure(iopcb_mask_ptr, getteam_1_0_ptr, getteam_1_0
Response_ptr, ServiceException_ptr) internal;
dcl iopcb_mask_ptr pointer byvalue;
dcl getteam_1_0_ptr pointer byvalue;
dcl getteam_1_0Response_ptr pointer byaddr;
dcl ServiceException_ptr pointer byaddr;
return;
end getteam_1_0Impl;
/*-------------------------------------------------------------------*
* Procedure: setteam_1_0Handler
* Description: Get the request language structure for operation "se
* tteam_1_0" from the IMS Message Queue using the IRZQGETS API, inv
* oke user-written implementation, set the response or fault langua
* ge structure and commit it to the IMS Message Queue using the IRZ
* QSETS API. Finally, deallocate language structures.
*------------------------------------------------------------------*/
setteam_1_0Handler: procedure internal;
/* Get the request language structure from the IMS Message Queue u
sing the IRZQGETS API.
*/
@irz_struct_name = 'setteam_1_0';
@irz_struct_type = @irz_soap_body_struct;
@irz_struct_ptr = null();
@irz_struct_size = 0;
@irz_debug = '0'b;
call IRZQGETSWrapper(procedurename());
if (@return_code = @irz_success) then do;
setteam_1_0_ptr = @irz_struct_ptr;
end; else do;
return;
end;
/* Invoke user-written implementation of operation "setteam_1_0" p
assing pointers to the request, response, and fault language struc
tures.
*/
setteam_1_0Response_ptr = null();
ServiceException_ptr = null();
call setteam_1_0Impl(@irz_iopcb_mask_ptr, setteam_1_0_ptr, setteam_1_
0Response_ptr, ServiceException_ptr);
/* Set the response or fault language structure for operation "set
team_1_0" and commit it to the IMS Message Queue using the IRZQSET
S API.
*/
if (setteam_1_0Response_ptr ¬= null()) then do;
@irz_struct_name = 'setteam_1_0Response';
@irz_struct_type = @irz_soap_body_struct;
@irz_struct_ptr = setteam_1_0Response_ptr;
@irz_struct_size = storage(setteam_1_0Response);
end; else if (ServiceException_ptr ¬= null()) then do;
@irz_struct_name = 'ServiceException';
@irz_struct_type = @irz_soap_fault_struct;
@irz_struct_ptr = ServiceException_ptr;
@irz_struct_size = storage(ServiceException);
end;
@irz_commit_structs = '1'b;
@irz_debug = '0'b;
call IRZQSETSWrapper(procedurename());
/* Deallocate language structures.
*/
if (setteam_1_0_ptr ¬= null()) then do;
call plifree(setteam_1_0_ptr);
setteam_1_0_ptr = null();
end;
if (setteam_1_0Response_ptr ¬= null()) then do;
call plifree(setteam_1_0Response_ptr);
setteam_1_0Response_ptr = null();
end;
if (ServiceException_ptr ¬= null()) then do;
call plifree(ServiceException_ptr);
ServiceException_ptr = null();
end;
return;
end setteam_1_0Handler;
/*-------------------------------------------------------------------*
* Procedure: setteam_1_0Impl
* Description: Implement the business logic for operation "setteam_
* 1_0" using the following steps: (1) Process the request language
* structure "setteam_1_0", (2) Allocate and fill in the response la
* nguage structure "setteam_1_0Response" or a fault language struct
* ure from the set {ServiceException}. (3) Finally, set the respect
* ive response or fault language structure pointer before returning
* to the operation handler (Handler) procedure. Note: If an error
* occurs that requires a rollback, use parameter iopcb_mask_ptr to
* access the IOPCB.
*------------------------------------------------------------------*/
setteam_1_0Impl: procedure(iopcb_mask_ptr, setteam_1_0_ptr, setteam_1_0
Response_ptr, ServiceException_ptr) internal;
dcl iopcb_mask_ptr pointer byvalue;
dcl setteam_1_0_ptr pointer byvalue;
dcl setteam_1_0Response_ptr pointer byaddr;
dcl ServiceException_ptr pointer byaddr;
return;
end setteam_1_0Impl;
/*-------------------------------------------------------------------*
* Procedure: ping_1_0Handler
* Description: Get the request language structure for operation "pi
* ng_1_0" from the IMS Message Queue using the IRZQGETS API, invoke
* user-written implementation, set the response or fault language
* structure and commit it to the IMS Message Queue using the IRZQSE
* TS API. Finally, deallocate language structures.
*------------------------------------------------------------------*/
ping_1_0Handler: procedure internal;
/* No request language structure is defined for operation "ping_1_
0".
*/
/* Invoke user-written implementation of operation "ping_1_0" pass
ing pointers to the request, response, and fault language structur
es.
*/
call ping_1_0Impl(@irz_iopcb_mask_ptr);
/* No response language structure is defined for operation "ping_1
_0". Insert only the IRZPWSIO message header.
*/
call CEETDLI(@irz_dli_insert, @irz_iopcb_mask,
@irz_async_msg_header);
return;
end ping_1_0Handler;
/*-------------------------------------------------------------------*
* Procedure: ping_1_0Impl
* Description: Implement the business logic for operation "ping_1_0
* " using the following steps: (1) Process the request language str
* ucture "n/a", (2) Allocate and fill in the response language stru
* cture "n/a" or a fault language structure from the set {}. (3) Fi
* nally, set the respective response or fault language structure po
* inter before returning to the operation handler (Handler) procedu
* re. Note: If an error occurs that requires a rollback, use parame
* ter iopcb_mask_ptr to access the IOPCB.
*------------------------------------------------------------------*/
ping_1_0Impl: procedure(iopcb_mask_ptr) internal;
dcl iopcb_mask_ptr pointer byvalue;
return;
end ping_1_0Impl;
/*-------------------------------------------------------------------*
* Procedure: IRZQGETSWrapper
* Description: Get a language structure from the IMS Message Queue
* using the IRZQGETS API.
*------------------------------------------------------------------*/
IRZQGETSWrapper: procedure(caller_proc_name) internal;
dcl caller_proc_name char(*) byaddr;
@return_code = IRZQGETS(@irz_async_msg_header_ptr,
@irz_iopcb_mask_ptr, @irz_struct_type,
@irz_struct_name, @irz_struct_ptr,
@irz_struct_size, @irz_cee_feedback_ptr,
@irz_debug);
if (@return_code ¬= @irz_success) then do;
call LogEvent(trim(packagename()) || '#'
|| trim(caller_proc_name) || '(): '
|| 'Error, IRZQGETS return code: '
|| trim(@return_code) || '.');
if (@irz_struct_ptr ¬= null()) then do;
call plifree(@irz_struct_ptr);
@irz_struct_ptr = null();
@irz_struct_size = 0;
end;
end;
return;
end IRZQGETSWrapper;
/*-------------------------------------------------------------------*
* Procedure: IRZQSETSWrapper
* Description: Set a language structure and optionally commit it to
* the IMS Message Queue using the IRZQSETS API.
*------------------------------------------------------------------*/
IRZQSETSWrapper: procedure(caller_proc_name) internal;
dcl caller_proc_name char(*) byaddr;
@return_code = IRZQSETS(@irz_async_msg_header_ptr,
@irz_iopcb_mask_ptr, @irz_struct_type,
@irz_struct_name, @irz_struct_ptr,
@irz_struct_size, @irz_commit_structs,
@irz_cee_feedback_ptr, @irz_debug);
if (@return_code ¬= @irz_success) then do;
call LogEvent(trim(packagename()) || '#'
|| trim(caller_proc_name) || '(): '
|| 'Eror, IRZQSETS return code: '
|| trim(@return_code) || '.');
end;
return;
end IRZQSETSWrapper;
/*-------------------------------------------------------------------*
* Procedure: LogEvent
* Description: Common procedure for logging events that may be exte
* nded as needed.
*------------------------------------------------------------------*/
LogEvent: procedure(text) internal;
dcl text char(*) varying byaddr;
put skip list(datetime() || ' ' || text);
put list('');
return;
end LogEvent;
end WSPOC1;
end WSPOC1Package;