Last active
May 16, 2017 07:38
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
method HANDLE_REQUEST. | |
* -0- call super | |
CALL METHOD SUPER->handle_request( ). | |
"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""$"$\SE:(1) Class CL_SOAP_HTTP_EXTENSION, Method HANDLE_REQUEST, End A | |
*$*$-Start: (1)---------------------------------------------------------------------------------$*$* | |
ENHANCEMENT 1 ZBCSL_SOAP_HTTP_EXT. "active version | |
TRY. | |
DATA: zzls_smis TYPE ZBCSL_SOAP_MSG_IS. | |
* Get request and response bodies | |
zzls_smis-request_payload = m_server->request->get_cdata( ). | |
zzls_smis-response_payload = m_server->response->get_cdata( ). | |
if m_config is bound. | |
DATA(zzlr_conf) = cast CL_SRT_WSP_RT_CONFIG( m_config ). | |
zzls_smis-name = zzlr_conf->IF_SRT_WSP_RT_CONFIG~INTERFACE-name. | |
zzls_smis-namespace = zzlr_conf->IF_SRT_WSP_RT_CONFIG~INTERFACE-namespace. | |
zzls_smis-operation = zzlr_conf->IF_SRT_WSP_RT_CONFIG~OPERATION-name. | |
endif. | |
GET TIME STAMP FIELD zzls_smis-timestamp. | |
zzls_smis-auth_user = sy-uname. | |
if m_server is bound. | |
DATA(zzlr_server) = cast CL_HTTP_SERVER_NET( m_server ). | |
zzls_smis-SOURCE_IP = zzlr_server->C_CALLER_IP. | |
zzls_smis-uri_path = m_server->request->get_header_field( '~path_translated' ). | |
endif. | |
CALL METHOD m_server->response->get_status | |
IMPORTING | |
reason = DATA(zzlv_reason) | |
CODE = zzls_smis-http_code. | |
zzls_smis-http_reason = zzlv_reason. | |
* Store record in database | |
CALL FUNCTION 'ZBCSL_SOAP_MSG_UPD' | |
EXPORTING | |
soap_msg = zzls_smis. | |
CATCH cx_root INTO DATA(lx_root). | |
* Don't want anything to stop the service call | |
* Log this event to the application log | |
DATA(zzlr_logger) = NEW zcl_bcu_logger( IV_OBJECT = 'ZSOAPSVCL' ). | |
zzlr_logger->logx( lx_root ). | |
zzlr_logger->save( ). | |
ENDTRY. | |
ENDENHANCEMENT. | |
*$*$-End: (1)---------------------------------------------------------------------------------$*$* | |
endmethod. "-- HANDLE_REQUEST |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*&---------------------------------------------------------------------* | |
*& Report ZBCSL_SM_SEARCH | |
*&---------------------------------------------------------------------* | |
*& Program to search through recorded SOAP message payloads | |
*& Martin Ceronio - May 2017 | |
*&---------------------------------------------------------------------* | |
report zbcsl_sm_search. | |
data: ls_smis type zbcsl_smis. | |
data: lv_timestamp_c type cpet_created_at. | |
* Search parameters | |
parameters: p_scht type string lower case. | |
parameters: p_svcn type zbcsl_smis-name. | |
parameters: p_oper type zbcsl_smis-operation. | |
select-options: p_trange for lv_timestamp_c visible length 30 no-extension matchcode object cpe_timestamp. | |
selection-screen begin of line. | |
selection-screen pushbutton 35(15) pbl5m user-command tsl5m. | |
selection-screen pushbutton (15) pblhr user-command tslhr. | |
selection-screen pushbutton (15) pbldy user-command tsldy. | |
selection-screen pushbutton (15) pblyr user-command tslyr. | |
selection-screen end of line. | |
parameters: p_maxh type i default 1000. | |
data: lr_query_sql type ref to cl_sql_statement. | |
data: gr_alv type ref to cl_salv_table. | |
data: gr_html_request type ref to cl_gui_html_viewer. | |
data: gr_html_response type ref to cl_gui_html_viewer. | |
*data: gr_xml_request type ref to cl_gui_xml_editor. | |
*data: gr_xml_response type ref to cl_gui_xml_editor. | |
data: gv_height type i. | |
* Search result: Everything except the payload from ZBCSL_SMIS | |
types: begin of ts_srres, | |
guid type guid_16, | |
timestamp type timestamp, | |
http_code type zbcsl_http_code, | |
http_reason type zbcsl_http_reason, | |
operation type zbcsl_service_operation, | |
name type zbcsl_service_name, | |
namespace type zbcsl_service_namespace, | |
auth_user type uname, | |
source_ip type rfcipv6addr, | |
uri_path type zbcsl_uri_path, | |
end of ts_srres. | |
types: tt_srres type standard table of ts_srres. | |
data: gs_srres type ts_srres. | |
data: gt_srres type tt_srres. | |
form create_indexes raising cx_sql_exception. | |
data(lv_ddl1) = |CREATE FULLTEXT INDEX ZBCSL_SMIS_REQP ON ZBCSL_SMIS (REQUEST_PAYLOAD)|. | |
data(lv_ddl2) = |CREATE FULLTEXT INDEX ZBCSL_SMIS_RESP ON ZBCSL_SMIS (RESPONSE_PAYLOAD)|. | |
data(lr_ddl) = new cl_sql_statement( ). | |
lr_ddl->execute_ddl( lv_ddl1 ). | |
lr_ddl->execute_ddl( lv_ddl2 ). | |
endform. | |
form delete_indexes raising cx_sql_exception. | |
data(lv_ddl1) = |DELETE FULLTEXT INDEX ZBCSL_SMIS_REQP|. | |
data(lv_ddl2) = |DELETE FULLTEXT INDEX ZBCSL_SMIS_RESP|. | |
data(lr_ddl) = new cl_sql_statement( ). | |
lr_ddl->execute_ddl( lv_ddl1 ). | |
lr_ddl->execute_ddl( lv_ddl2 ). | |
endform. | |
* Carry out the search using the entered parameters | |
form perform_search raising cx_sql_exception. | |
refresh gt_srres. | |
* TODO: Should we limit selection to everything except the payload fields and add those later? | |
data(lv_query) = |SELECT GUID, TIMESTAMP, HTTP_CODE, HTTP_REASON, OPERATION, NAME, NAMESPACE, AUTH_USER, SOURCE_IP, URI_PATH FROM ZBCSL_SMIS WHERE |. | |
data: lt_terms type string_table. | |
* Add free text search term | |
if p_scht is not initial. | |
append |CONTAINS ((request_payload, response_payload), '{ p_scht }')| to lt_terms. | |
endif. | |
* Add service name term | |
if p_svcn is not initial. | |
append |NAME = '{ p_svcn }'| to lt_terms. | |
endif. | |
* Add operation term | |
if p_oper is not initial. | |
append |OPERATION = '{ p_oper }'| to lt_terms. | |
endif. | |
* Add term to make search client-dependent | |
append |MANDT = '{ sy-mandt }'| to lt_terms. | |
* Add term for timestamp range | |
read table p_trange index 1. | |
if sy-subrc = 0. "And it should always be! | |
append |TIMESTAMP BETWEEN { p_trange-low } AND { p_trange-high }| to lt_terms. | |
endif. | |
* Combine terms into query | |
concatenate lines of lt_terms into data(lv_terms) separated by ' AND '. | |
lv_query = |{ lv_query } { lv_terms } ORDER BY TIMESTAMP DESC LIMIT { p_maxh }|. | |
data(lr_sql) = new cl_sql_statement( ). | |
data(lr_res) = lr_sql->execute_query( lv_query ). | |
lr_res->set_param_table( ref #( gt_srres ) ). | |
data(lv_recs) = lr_res->next_package( ). | |
gr_alv->get_columns( )->set_optimize( abap_true ). | |
gr_alv->refresh( ). | |
message |{ lv_recs } records retrieved| type 'S'. | |
endform. | |
* Set from and to timestamps from until p_seconds ago | |
form set_time_interval using p_seconds type i. | |
clear p_trange[]. | |
data(lr_ts_util) = cl_abap_timestamp_util=>get_instance( ). | |
get time stamp field data(lv_tst). | |
write lv_tst to p_trange-high. | |
if p_seconds ne 0. | |
data(lv_tsf) = lr_ts_util->tstmp_add_seconds( iv_timestamp = lv_tst iv_seconds = conv #( p_seconds ) ). | |
else. | |
lv_tsf = 0. | |
endif. | |
write lv_tsf to p_trange-low. | |
append p_trange. | |
endform. | |
class lcl_evt_handler definition. | |
public section. | |
types: tt_tab type standard table of text255 with empty key. | |
class-methods: handle_result_doubleclick | |
for event double_click of cl_salv_events_table | |
importing row, | |
string_to_table importing str type string returning value(table) type tt_tab. | |
endclass. | |
class lcl_evt_handler implementation. | |
method handle_result_doubleclick. | |
* The double-click handler loads the request and response payloads for the selected record and displays them in the controls | |
read table gt_srres into data(ls_srres) index row. | |
check sy-subrc = 0. "But why wouldn't it be? | |
select single * from zbcsl_smis into @data(ls_smis) | |
where guid = @ls_srres-guid. | |
if sy-subrc = 0. | |
* Populate Request HTML control | |
data lv_requrl type c length 255. | |
* Little hack to ensure that the response payload will display as formatted XML in browser control: | |
if find( val = ls_smis-request_payload sub = '<?xml' ) = -1. | |
ls_smis-request_payload = |<?xml version="1.0" encoding="UTF-8"?> { ls_smis-request_payload }|. | |
endif. | |
data(lv_reqht) = string_to_table( ls_smis-request_payload ). | |
gr_html_request->load_data( exporting url = 'requestdata.htm' importing assigned_url = lv_requrl changing data_table = lv_reqht ). | |
gr_html_request->do_refresh( ). | |
gr_html_request->show_data( exporting url = lv_requrl ). | |
* Populate Response HTML control | |
data lv_resurl type c length 255. | |
* Little hack to ensure that the response payload will display as formatted XML in browser control: | |
if find( val = ls_smis-response_payload sub = '<?xml' ) = -1. | |
ls_smis-response_payload = |<?xml version="1.0" encoding="UTF-8"?> { ls_smis-response_payload }|. | |
endif. | |
data(lv_resht) = string_to_table( ls_smis-response_payload ). | |
gr_html_response->load_data( exporting url = 'responsedata.htm' importing assigned_url = lv_resurl changing data_table = lv_resht ). | |
gr_html_response->do_refresh( ). | |
gr_html_response->show_data( exporting url = lv_resurl ). | |
endif. | |
endmethod. | |
method string_to_table. | |
data(lv_str) = str. | |
data(lv_len) = strlen( lv_str ). | |
while lv_len > 255. | |
append lv_str(255) to table. | |
shift lv_str left by 255 places. | |
subtract 255 from lv_len. | |
endwhile. | |
if lv_len > 0. | |
append lv_str to table. | |
endif. | |
endmethod. | |
endclass. | |
* Selection-scren output | |
at selection-screen output. | |
* Initialize controls on first output | |
if gr_alv is not bound. | |
try. | |
* Create main splitter control and place it under the parameters on the screen | |
data(lr_splitter) = new cl_gui_easy_splitter_container( parent = cl_gui_container=>default_screen | |
orientation = cl_gui_easy_splitter_container=>orientation_horizontal sash_position = 60 ). | |
lr_splitter->get_height( importing height = gv_height ). | |
cl_gui_cfw=>flush( ). | |
* Resize to show entire control | |
lr_splitter->set_height( gv_height - 80 ). | |
lr_splitter->set_top( 50 ). | |
* Create the ALV Grid control to hold the search results | |
cl_salv_table=>factory( | |
exporting | |
r_container = lr_splitter->top_left_container | |
importing | |
r_salv_table = gr_alv | |
changing | |
t_table = gt_srres ). | |
gr_alv->get_columns( )->set_optimize( abap_true ). | |
gr_alv->get_columns( )->get_column( 'GUID' )->set_visible( abap_false ). | |
* Set the handler for double-clicking on a search result | |
data(lr_tevent) = gr_alv->get_event( ). | |
set handler lcl_evt_handler=>handle_result_doubleclick for lr_tevent. | |
gr_alv->display( ). | |
* Create the HTML control for displaying the request and response payloads | |
data(lr_splitres) = new cl_gui_easy_splitter_container( parent = lr_splitter->bottom_right_container | |
orientation = cl_gui_easy_splitter_container=>orientation_vertical ). | |
gr_html_request = new cl_gui_html_viewer( parent = lr_splitres->top_left_container ). | |
gr_html_response = new cl_gui_html_viewer( parent = lr_splitres->bottom_right_container ). | |
catch cx_salv_msg. " | |
endtry. | |
endif. | |
* Remove Execute and Save functions on report selection screen | |
perform insert_into_excl(rsdbrunt) using 'ONLI'. | |
perform insert_into_excl(rsdbrunt) using 'SPOS'. | |
at selection-screen. | |
case sy-ucomm. | |
when 'TSL5M'. | |
perform set_time_interval using -300. | |
when 'TSLHR'. | |
perform set_time_interval using -3600. | |
when 'TSLDY'. | |
perform set_time_interval using -86400. | |
when 'TSLYR'. | |
perform set_time_interval using 0. | |
when 'CRFTI'. "Create full text index | |
perform create_indexes. | |
when space. | |
try. | |
perform perform_search. | |
catch cx_sql_exception into data(lx_sql). | |
message lx_sql->get_text( ) type 'I'. | |
endtry. | |
endcase. | |
initialization. | |
* Prepare a list of services and operations that have been captured so far for selecting | |
select name, operation | |
from zbcsl_smis | |
group by name, operation | |
order by name, operation | |
into table @data(gt_operation). | |
* Prepare a unique list of services captured so far for selection | |
select name from zbcsl_smis group by name order by name | |
into table @data(gt_service). | |
* Default from/to timestamps to last hour | |
perform set_time_interval using -3600. | |
* Set button texts | |
pbl5m = 'Last 5 min.'(005). | |
pblhr = 'Last Hour'(006). | |
pbldy = 'Last Day'(007). | |
pblyr = 'All Time'(008). | |
* Determine some useful index info for user at start | |
select count(*) as count, min( timestamp ) as first_ts | |
from zbcsl_smis into @data(ls_info). | |
message |{ ls_info-count } recorded messages since { ls_info-first_ts timestamp = space timezone = sy-zonlo } in current client| type 'S'. | |
* Selection of service name and operation (on operation field) | |
at selection-screen on value-request for p_oper. | |
data: lt_dynpm type table of dselc. | |
lt_dynpm = value #( ( fldname = 'F0001' dyfldname = 'P_SVCN' ) ). | |
call function 'F4IF_INT_TABLE_VALUE_REQUEST' | |
exporting | |
retfield = 'OPERATION' | |
dynpprog = sy-repid | |
dynpnr = '1000' | |
dynprofield = 'P_OPER' | |
value_org = 'S' "'C' | |
tables | |
value_tab = gt_operation | |
dynpfld_mapping = lt_dynpm | |
exceptions | |
parameter_error = 1 | |
no_values_found = 2 | |
others = 3. | |
* Selection of service name only | |
at selection-screen on value-request for p_svcn. | |
data: lt_dynpm type table of dselc. | |
call function 'F4IF_INT_TABLE_VALUE_REQUEST' | |
exporting | |
retfield = 'NAME' | |
dynpprog = sy-repid | |
dynpnr = '1000' | |
dynprofield = 'P_SVCN' | |
value_org = 'S' "'C' | |
tables | |
value_tab = gt_service | |
exceptions | |
parameter_error = 1 | |
no_values_found = 2 | |
others = 3. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
ZBCSL_SMIS SOAP messages for indexed search | |
Table field Short Description Data element Key Data Type Length | |
MANDT Client MANDT X CLNT 3 | |
GUID GUID in 'RAW' format GUID_16 X RAW 16 | |
NAME Service Name ZBCSL_SERVICE_NAME CHAR 132 | |
NAMESPACE Service Namespace ZBCSL_SERVICE_NAMESPACE CHAR 132 | |
OPERATION Service operation ZBCSL_SERVICE_OPERATION CHAR 132 | |
AUTH_USER User Name UNAME CHAR 12 | |
TIMESTAMP UTC Time Stamp in Short Form (YYYYMMDDhhmmss) TIMESTAMP DEC 15 | |
SOURCE_IP IP Address in IPv6 Format RFCIPV6ADDR CHAR 45 | |
HTTP_CODE HTTP Code ZBCSL_HTTP_CODE INT4 10 | |
HTTP_REASON HTTP Reason ZBCSL_HTTP_REASON CHAR 25 | |
URI_PATH Path to service ZBCSL_URI_PATH STRING | |
REQUEST_PAYLOAD Request Payload ZBCSL_REQUEST_PAYLOAD STRING | |
RESPONSE_PAYLOAD Response Payload ZBCSL_RESPONSE_PAYLOAD STRING |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function zbcsl_soap_msg_upd. | |
*"---------------------------------------------------------------------- | |
*"*"Local Interface: | |
*" IMPORTING | |
*" VALUE(SOAP_MSG) TYPE ZBCSL_SOAP_MSG_IS | |
*"---------------------------------------------------------------------- | |
data: ls_msg type zbcsl_smis. | |
move-corresponding soap_msg to ls_msg. | |
* Ignore the exception, because that will just cause the update to fail, which is fine, | |
* because inability to generate a UUID would indicate something severly wrong | |
ls_msg-guid = cl_system_uuid=>create_uuid_x16_static( ). | |
insert zbcsl_smis connection r/3*_bal_trace from ls_msg. | |
commit connection r/3*_bal_trace. | |
endfunction. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment