SAP SOAP XML Interface with Workflow
The following example describes a mechanism with generic code examples to process an
XML message submitted to SAP via SOAP Web service.
Function Module to Process Incoming Message
Note FM is enabled as a web service.
function z_inbound_xml .
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(XML_STREAM) TYPE XSTRING
*" VALUE(REQUEST_QNAME) TYPE QNAME OPTIONAL
*" EXPORTING
*" VALUE(RECEIVED) TYPE CHAR1
*"----------------------------------------------------------------------
* Data Declaration for Class
data: lr_wf_class type ref to zcl_xml. “Class to process message
* Processing starts
* First convert the XString in a string
class cl_abap_conv_in_ce definition load.
*
conv_in = cl_abap_conv_in_ce=>create(
encoding = 'UTF-8'
input = xml_stream ).
* define xml string for xslt transformation
clear l_xml_stream.
call method conv_in->read( importing data = l_xml_stream ).
*
* Maintain data from received inbound web services as log entry
* for day-to-day tracking & Audit Purposes.
*"----------------------------------------------------------------------
*"*"Local Interface:
*" IMPORTING
*" VALUE(XML_STREAM) TYPE XSTRING
*" VALUE(REQUEST_QNAME) TYPE QNAME OPTIONAL
*" EXPORTING
*" VALUE(RECEIVED) TYPE CHAR1
*"----------------------------------------------------------------------
* Data Declaration for Class
data: lr_wf_class type ref to zcl_xml. “Class to process message
* Processing starts
* First convert the XString in a string
class cl_abap_conv_in_ce definition load.
*
conv_in = cl_abap_conv_in_ce=>create(
encoding = 'UTF-8'
input = xml_stream ).
* define xml string for xslt transformation
clear l_xml_stream.
call method conv_in->read( importing data = l_xml_stream ).
*
* Maintain data from received inbound web services as log entry
* for day-to-day tracking & Audit Purposes.
* Uses generated unique UUID
try.
call method cl_system_uuid=>if_system_uuid_static~create_uuid_x16
receiving
uuid = lv_guid.
catch cx_uuid_error .
endtry.
*
clear ls_log-zid. " will be written by processing class
* Populate timestamp along with Messagetype details.
move sy-mandt to ls_log-zmandt.
move lv_guid to ls_log-zguid. " key used to process
move lc_msg1 to ls_log-zmessagetype. " message for this XML could also be setup as input parameter REQUEST_QNAME-NAME
move sy-datum to ls_log-zdate.
move 'I' to ls_log-zstatus.
move l_xml_stream to ls_log-zxml.
get time stamp field ls_log-ztime.
append ls_log to li_log.
modify z_log from ls_log.
commit work and wait.
if sy-subrc = 0.
* Trigger Workflow, The class is called and event is set by the method to
try.
call method cl_system_uuid=>if_system_uuid_static~create_uuid_x16
receiving
uuid = lv_guid.
catch cx_uuid_error .
endtry.
*
clear ls_log-zid. " will be written by processing class
* Populate timestamp along with Messagetype details.
move sy-mandt to ls_log-zmandt.
move lv_guid to ls_log-zguid. " key used to process
move lc_msg1 to ls_log-zmessagetype. " message for this XML could also be setup as input parameter REQUEST_QNAME-NAME
move sy-datum to ls_log-zdate.
move 'I' to ls_log-zstatus.
move l_xml_stream to ls_log-zxml.
get time stamp field ls_log-ztime.
append ls_log to li_log.
modify z_log from ls_log.
commit work and wait.
if sy-subrc = 0.
* Trigger Workflow, The class is called and event is set by the method to
* start WF processing of XML message. This effectively separates the
capture
* of the XML data inputs to log from the subsequent time and process
* intensive handling of the XML mesage contents.
try.
create object lr_wf_class.
lr_wf_class->execute_xml( exporting i_guid = lv_guid ).
catch cx_ai_system_fault.
catch cx_ops_se.
catch cx_appl_proxy_badi_processing.
endtry.
* Set Acknowledgement
move '1' to received.
endif.
endfunction.
try.
create object lr_wf_class.
lr_wf_class->execute_xml( exporting i_guid = lv_guid ).
catch cx_ai_system_fault.
catch cx_ops_se.
catch cx_appl_proxy_badi_processing.
endtry.
* Set Acknowledgement
move '1' to received.
endif.
endfunction.
TOP include for Function Group
data : ls_log type z_log,
li_log type table of z_log.
data : lv_guid type sysuuid_x16,
lv_index type i.
li_log type table of z_log.
data : lv_guid type sysuuid_x16,
lv_index type i.
constants: lc_msg1(3) value '850',
lc_msg2(3) value '856',
lc_msg3(3) value '855'.
lc_msg2(3) value '856',
lc_msg3(3) value '855'.
Table Definitions
Transparent
Table: Z_LOG
Z_LOG
Short description: Interface Log
Transparent table
Field Structure
Number of fields: 11
Total of field lengths: 337
Field
Name
|
Key
|
Data
Element
|
Type
|
Length
|
Short
Text
|
ZMANDT
|
X
|
MANDT
|
CLNT
|
3
|
Client
|
ZGUID
|
X
|
SYSUUID_X16
|
RAW
|
16
|
16 Byte UUID inv16 Bytes(Raw Format)
|
ZMESSAGETYPE
|
X
|
ZMESSAGETYPE
|
CHAR
|
10
|
Message
Type
|
ZDATE
|
X
|
ZDATE
|
DATS
|
8
|
Date
|
ZTIME
|
X
|
ZTIMESTAMP
|
DEC
|
21
|
Time
|
ZID
|
ZID
|
CHAR
|
50
|
ID
|
|
ZRESEND_ON
|
ZRESEND_ON
|
DATS
|
8
|
Resend
On
|
|
ZSTATUS
|
ZSTAST
|
CHAR
|
1
|
Status
|
|
ZDATA
|
ZDATA
|
STRG
|
Data
|
||
ZXML
|
ZXML
|
STRG
|
XML
Received
|
||
ZERR_MSG
|
BAPI_MSG
|
CHAR
|
220
|
Message Text
|
Processing Class ZCL_XML
To set event for Processing WF
Method Execute_XML
method execute_xml.
* Data Declarations
data: lv_objtype type sibftypeid,
lv_event type sibfevent,
lv_objkey type sibfinstid,
lr_event_parameters type ref to if_swf_ifs_parameter_container,
lv_param_name type swfdname,
lv_id type string,
lv_guid type sysuuid_x16.
* Setting values of Event Name
lv_objtype = 'ZCL_XML'. " Class Name
lv_event = 'XML'. " Event Name.
* Instantiate an empty event container
call method cl_swf_evt_event=>get_event_container
exporting
im_objcateg = cl_swf_evt_event=>mc_objcateg_cl
im_objtype = lv_objtype
im_event = lv_event
receiving
re_reference = lr_event_parameters.
* Set up the name/value pair to be added to the container - GUID
lv_param_name = 'GUID'. " parameter name of the event
lv_guid = i_guid. " unique key from log for input data
* Add the name/value pair to the event container
try.
call method lr_event_parameters->set
exporting
name = lv_param_name
value = lv_guid.
catch cx_swf_cnt_cont_access_denied .
catch cx_swf_cnt_elem_access_denied .
catch cx_swf_cnt_elem_not_found .
catch cx_swf_cnt_elem_type_conflict .
catch cx_swf_cnt_unit_type_conflict .
catch cx_swf_cnt_elem_def_invalid .
catch cx_swf_cnt_container .
endtry.
* Raise the event passing the prepared event container
try.
call method cl_swf_evt_event=>raise
exporting
im_objcateg = cl_swf_evt_event=>mc_objcateg_cl
im_objtype = lv_objtype
im_event = lv_event
im_objkey = lv_objkey
im_event_container = lr_event_parameters.
catch cx_swf_evt_invalid_objtype .
catch cx_swf_evt_invalid_event .
endtry.
commit work and wait.
endmethod.
* Data Declarations
data: lv_objtype type sibftypeid,
lv_event type sibfevent,
lv_objkey type sibfinstid,
lr_event_parameters type ref to if_swf_ifs_parameter_container,
lv_param_name type swfdname,
lv_id type string,
lv_guid type sysuuid_x16.
* Setting values of Event Name
lv_objtype = 'ZCL_XML'. " Class Name
lv_event = 'XML'. " Event Name.
* Instantiate an empty event container
call method cl_swf_evt_event=>get_event_container
exporting
im_objcateg = cl_swf_evt_event=>mc_objcateg_cl
im_objtype = lv_objtype
im_event = lv_event
receiving
re_reference = lr_event_parameters.
* Set up the name/value pair to be added to the container - GUID
lv_param_name = 'GUID'. " parameter name of the event
lv_guid = i_guid. " unique key from log for input data
* Add the name/value pair to the event container
try.
call method lr_event_parameters->set
exporting
name = lv_param_name
value = lv_guid.
catch cx_swf_cnt_cont_access_denied .
catch cx_swf_cnt_elem_access_denied .
catch cx_swf_cnt_elem_not_found .
catch cx_swf_cnt_elem_type_conflict .
catch cx_swf_cnt_unit_type_conflict .
catch cx_swf_cnt_elem_def_invalid .
catch cx_swf_cnt_container .
endtry.
* Raise the event passing the prepared event container
try.
call method cl_swf_evt_event=>raise
exporting
im_objcateg = cl_swf_evt_event=>mc_objcateg_cl
im_objtype = lv_objtype
im_event = lv_event
im_objkey = lv_objkey
im_event_container = lr_event_parameters.
catch cx_swf_evt_invalid_objtype .
catch cx_swf_evt_invalid_event .
endtry.
commit work and wait.
endmethod.
Define the Event Linkage to Workflow
Transaction SWETYPV
Define workflow to Fetch and Process XML
The WF steps call the Class methods via standard Tasks.
Example Method to Fetch XML from log
method get_xml.
data: lv_log type zmm_log.
clear: lv_log.
select single * from zmm_log into lv_log
where zguid = i_guid.
if sy-subrc = 0.
move-corresponding lv_log to e_log_rec.
endif.
endmethod.
data: lv_log type zmm_log.
clear: lv_log.
select single * from zmm_log into lv_log
where zguid = i_guid.
if sy-subrc = 0.
move-corresponding lv_log to e_log_rec.
endif.
endmethod.
Example method to Process XML
Uses SAP transformation to translate the XML structure into
an ABAP Type structure
method process_xml.
data: gt_xml type standard table of xml_in,
gt_bapi type standard table of wa_h, "your header type
gs_bapi type wa_h,
bapi_line type wa_d. "your detail line type
* Fill the result table with a reference to the data table.
* Within the XSLT stylesheet
* Within the XSLT stylesheet
e_log_rec = i_log_rec.
refresh: gt_xml, gt_bapi.
get reference of gt_xml into gs_result_xml-value.
gs_result_xml-name = 'IXML'.
append gs_result_xml to gt_result_xml.
try.
call transformation z_xml_to_abap
source xml i_log_rec-zxml
result (gt_result_xml).
catch cx_root into gs_rif_ex.
gs_var_text = gs_rif_ex->get_text( ).
message gs_var_text type 'I'.
endtry.
* Develop Input
Records from XML
loop at gt_lxml into gs_xml.
loop at gs_xml-line into gs_line.
loop at gt_lxml into gs_xml.
loop at gs_xml-line into gs_line.
move gs_line-xml_id to gs_bapi-xml_id.
endloop.
endloop.
endloop.
>>>> STD ABAP to process input.
try.
call method me->create_bapi
exporting
im_hd = wa_hd
im_bapi = gs_bapi.
catch cx_sy_dyn_call_illegal_type.
v_err_msg = lcx_excp_type->get_text( ).
move v_err_msg to e_log_rec-zerr_msg.
e_log_rec-zerr_msg = 'Bad Type'.
catch cx_sy_no_handler.
v_err_msg = lcx_excp_hand->get_text( ).
move v_err_msg to e_log_rec-zerr_msg.
e_log_rec-zerr_msg = 'No Handler'.
catch cx_sy_ref_is_initial.
v_err_msg = lcx_excp_init->get_text( ).
move v_err_msg to e_log_rec-zerr_msg.
e_log_rec-zerr_msg = 'Initial'.
endtry.
call method me->create_bapi
exporting
im_hd = wa_hd
im_bapi = gs_bapi.
catch cx_sy_dyn_call_illegal_type.
v_err_msg = lcx_excp_type->get_text( ).
move v_err_msg to e_log_rec-zerr_msg.
e_log_rec-zerr_msg = 'Bad Type'.
catch cx_sy_no_handler.
v_err_msg = lcx_excp_hand->get_text( ).
move v_err_msg to e_log_rec-zerr_msg.
e_log_rec-zerr_msg = 'No Handler'.
catch cx_sy_ref_is_initial.
v_err_msg = lcx_excp_init->get_text( ).
move v_err_msg to e_log_rec-zerr_msg.
e_log_rec-zerr_msg = 'Initial'.
endtry.
No comments:
Post a Comment