How to SAPUI5 on SAP ICF – SMON and SICF
In my introduction to this blog series I laid out my objectives. I’ll restate them here to make sure we’re all on the same page: in this series we are going to build a lightweight proof-of-concept dashboard that displays SAP technical performance data in an interesting and visually stimulating way.
As you know by now I’m adhering to the following structure:
- Picking the Visualization – introducing D3.js and the concept of data joins;
- Introduction to the SAPUI5 Shell ‘bootstrap’ environment and how to integrate components;
- Description of the SAP SMON functions and how to creating a new service in the SAP ICF (you are here);
- Bringing it all together – this is the installment that I’ll use to describe each of the individual steps
SICF
So what is the SAP Internet Connection Framework?
I’ll leave that to DJ Adams who defines the ICF technology as:
”a collection of configuration, interfaces, classes and a core set of processes that allow us to build HTTP applications directly inside SAP”
This is epic! It means we have a full blown web server within SAP. ‘So what?’ I hear the cynics out there cry. Well it means we have a stack of functions that can receive Hyper Text Transfer Protocol requests from ‘the internet’ and invoke ABAP functions on the SAP back-end server, this logic can collect data and package it up as a RESTful reponse. What, we can call ABAP functions via HTTP, why did nobody tell me! What do I have to do to get this … nothing!?! Are you freaking kidding me! Tell me more.
The ICF can be called via SAP transaction SICF:
You will find a list of services that can be invoked:
Once active, each can be invoked via the following address pattern:
- http://<host>:<port>/<path to service>
- Example: http://myserver.com:8000/sap/bw/doc/metadata
A service looks like this:
Each service calls (at least) one Handler Class – that’s where we put the ABAP logic in a service we’ll create, see the next section for an introduction. And yes, each service can be configured for secure access. There are a number of security options but in the interests of keeping your attention I’m not going into those here, try this link for more, if you need it.
The Handler
SICF -> <path to your service> -> Handler List
The ‘handler’ is a class, that means object-orientated ABAP. Not a problem, you can create a new class in SAP transaction SE24 (or from SE80), be sure to implement the IF_HTTP_EXTENSION interface and add your own code into the method (don’t worry, all will be explained).
Here is the code we will deploy via our service to access the SAP performance functions to return the Memory consumption, CPU and Network data.
METHOD if_http_extension~handle_request. DATA: name TYPE string. DATA: l_tf_mem_all TYPE TABLE OF mem_all, l_tf_cpu_all TYPE TABLE OF cpu_all, l_tf_lan_single TYPE TABLE OF lan_single, s_mem_all LIKE LINE OF l_tf_mem_all, s_cpu_all LIKE LINE OF l_tf_cpu_all, s_lan_single LIKE LINE OF l_tf_lan_single, l_free_mem TYPE n LENGTH 8, l_phys_mem TYPE n LENGTH 8, l_swap_free TYPE n LENGTH 8, l_swap_max TYPE n LENGTH 8, l_free_mem_pc TYPE n LENGTH 8, l_swap_free_pc TYPE n LENGTH 8, l_lastcollwrt TYPE char25, l_idle_total TYPE n LENGTH 8, l_packets TYPE n LENGTH 8, json_string TYPE string. CALL FUNCTION ‘FILL_SNAPSHOT_DATA’ * EXPORTING * LOCAL_REMOTE = ‘LOCAL’ * LOGICAL_DESTINATION = * SYSTEM_ID = 0 IMPORTING * F_CPU_ALL_READ = * F_MEM_ALL_READ = * F_DISK_SINGLE_READ = * F_LAN_SINGLE_READ = * F_TOP_SINGLE_READ = * TAB_TYPE = * ACTIVEFLAG = * INTERVAL = * DETAILSCOLL = * DETAILSREQI = * DETAILSMODE = lastcollwrt = l_lastcollwrt * LASTCOLLINT = * NORMCOLLINT = * F_POOL_ALL_READ = * F_SPAG_ALL_READ = * F_STOR_ALL_READ = * F_CPU_SINGLE_READ = * F_POOL_SINGLE_READ = * F_CPU_VIRT_AIX_READ = TABLES tf_cpu_all = l_tf_cpu_all tf_mem_all = l_tf_mem_all * TF_DISK_SINGLE = tf_lan_single = l_tf_lan_single * TF_TOP_SINGLE = * TF_POOL_ALL = * TF_SPAG_ALL = * TF_STOR_ALL = * TF_CPU_SINGLE = * TF_POOL_SINGLE = * TF_CPU_VIRT_AIX = * EXCEPTIONS * INTERNAL_ERROR_ADRESS_FAILED = 1 * INTERNAL_ERROR_DIFFERENT_FIELD = 2 * INTERNAL_ERROR_NO_NEW_LINE = 3 * COLLECTOR_NOT_RUNNING = 4 * SHARED_MEMORY_NOT_AVAILABLE = 5 * COLLECTOR_BUSY = 6 * VERSION_CONFLICT = 7 * NO_NETWORK_COLLECTOR_RUNNING = 8 * SYSTEM_FAILURE = 9 * COMMUNICATION_FAILURE = 10 * OTHERS = 11 . IF sy-subrc <> 0. * MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO * WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4. ENDIF. *Get Timestamp CONCATENATE json_string ‘{“Timestamp”: “‘ l_lastcollwrt(24) ‘”, ‘ INTO json_string. * Get Memory Data LOOP AT l_tf_mem_all INTO s_mem_all. l_free_mem = s_mem_all-free_mem. l_phys_mem = s_mem_all-phys_mem. l_swap_free = s_mem_all-swap_free. l_swap_max = s_mem_all-swap_max. l_free_mem_pc = l_free_mem / l_phys_mem * 100. SHIFT l_free_mem_pc LEFT DELETING LEADING ‘0’. l_swap_free_pc = l_swap_free / l_swap_max * 100. SHIFT l_swap_free_pc LEFT DELETING LEADING ‘0’. CONCATENATE json_string ‘”free_mem_pc”: “‘ l_free_mem_pc ‘”, ‘ INTO json_string. ENDLOOP. * Get CPU data LOOP AT l_tf_cpu_all INTO s_cpu_all. l_idle_total = s_cpu_all-idle_total. SHIFT l_idle_total LEFT DELETING LEADING ‘0’. CONCATENATE json_string ‘”idle_total”: “‘ l_idle_total ‘”, ‘ INTO json_string. ENDLOOP. * Get Network data (currently only ‘lo’) LOOP AT l_tf_lan_single INTO s_lan_single WHERE lanname = ‘lo’. l_packets = s_lan_single-packets. SHIFT l_packets LEFT DELETING LEADING ‘0’. CONCATENATE json_string ‘”packets”: “‘ l_packets ‘”}’ INTO json_string. ENDLOOP. * Enable this service to be available to other sites * server->response->set_header_field( name = ‘Access-Control-Allow-Origin’ value = ‘*’ ). * * Return the results in a JSON string * server->response->set_cdata( data = json_string ).
|
SMON
I’ve been looking at the SMON package and a couple of the function modules SMON contains for a while now. I have previously put together a Flash widget that calls these functions, but that was before Flash ‘crashed’ (see what I did there).
These functions are used to access the SAP server performance data that is collected from the operating system by the SAPOSCOL service.
I decided to call the ‘FILL_SNAPSHOT_DATA’ function module because it’s the one that combines the various component functions to deliver a range of performance metrics.
Have a look at the earlier code snippet for a preview of the final solution which I’ll describe in the final post, coming up next.
The Same Origin Policy and SAP SICF
Before I ring off, a word of warning: when we deploy our mini-application on our local web server we will be calling functions from JavaScript that is sitting on a different domain. This is considered a security risk and a potential loophole that is closed by default.
We can however open up the policy on our SAP server, usually you would do this in an appropriate way, but we’ll use the following ‘*’ setting in our POC:
server->response->set_header_field( name = ‘Access-Control-Allow-Origin’ value = ‘*’ ).
As you can see from the code listing earlier we simply add this at an appropriate point on the handler method to allow cross-domain access (I struggled to understand this at first, so drop me a comment if its not clear to you too).
Well that’s all for this section. In the next and final instalment (the one you’ve probably been waiting for) I’ll go through each of these activities step-by-step to finalise the finished product. It may be a long weekend … and I may only begin after the Springboks have beaten the reigning rugby world champions in their antipodean back garden, let’s see how that goes … 😉
Andrew
Hi Andrew,
very nice blog and enthusiastic and entertaining writing style.
Hat off to DJ for his excellent summary of SICF.
You're totally right it's the next installment we are waiting for.
Rugby: there's only one team
all the best,
Andy.
Hi Andy, many thanks for the feedback. Worry not, I'm motivated to deliver on my promise too.
Andrew
PS Being RSA based, the only team I was ever able to support in the Premiership was 'the overseas Currie Cup side': Saracens 😉
Hi Andrew,
they're playing on Sunday
Andy.