Experiences with SAP Gateway

"My foots always in my mouth i just can't stomach defeet" – Hilltop Hoods

Windows 8 Metro Style Apps and Gateway

leave a comment »

Unfortunately I will have to keep this post brief.  Below are some screen shots from my first Windows 8 Metro Style Application consuming SAP Netweaver Gateway data.

At present there are not many examples of how to consume OData in a Metro Style application, even harder to find an example using javascript.

I used the following blog as a guideline

http://blogs.msdn.com/b/lightswitch/archive/2012/03/13/using-lightswitch-odata-services-in-a-windows-8-metro-style-application-elizabeth-maher.aspx

Once I got started it was actually very easy.

I did however have a slight problem getting Datajs to parse Xml, for which I luckily found a simple work around.

My mind isn’t completely made up about Windows 8 development, I think I will have to code a couple more applications first, I will say it is a completely different experience to the other tools and platforms I have been developing on lately, it is very familiar and very simple, which kind of scares me.

Useful Resources:

Writing code for Metro style apps (JavaScript): http://msdn.microsoft.com/en-US/library/windows/apps/hh770842

Data Model: http://msdn.microsoft.com/en-us/library/windows/apps/hh758329.aspx

Asynchronous programming in JavaScript: http://msdn.microsoft.com/en-US/library/windows/apps/hh700330

Debugging apps: http://msdn.microsoft.com/en-US/library/windows/apps/hh441474

Advertisements

Written by rsol1

May 7, 2012 at 12:43 pm

Using Gateway data in Excel 2010 PowerPivot

with one comment

I thought I would quickly show how to use PowerPivot in Excel with data from SAP Netweaver Gateway.

PowerPivot is a free add-in to the 2010 version of the spreadsheet application Microsoft Excel. It extends the capabilities of the PivotTable data summarisation and cross-tabulation feature by introducing the ability to import data from multiple sources. As such, PowerPivot falls under Microsoft’s Business Intelligence offering, complementing it with its self-service, in-memory capabilities [http://en.wikipedia.org/wiki/PowerPivot]

To start with you need to download and install the PowerPivot add-in, you can find it at http://www.microsoft.com/en-us/bi/powerpivot.aspx

Once installed, open up Excel and click PowerPivot tab then PowerPivot Window.

Choose Get External Data -> From Data Feeds

Enter the connection details

Press Advanced button to enter authentication details

Select and import the tables you want to use

Then Create Relationships between the tables

Select PivotTable -> Chart and Table (Horizontal)

From there you can drag the fields you want for the axis and values, in this example Products by count of Orders

This shows how simple it is to start, now you can go further and add slicers and filters etc. or add data from other sources.

Written by rsol1

April 13, 2012 at 1:27 pm

Posted in Uncategorized

Tagged with , , , , ,

Posting to Gateway with SAPUI5

leave a comment »

It has been a while since my last post, been busy building apps on Android.

Anyway thought I would quickly share how easy it is to post to SAP Netweaver Gateway using the SAPUI5 library.

Image

To start with you need to reference the datajs library.

jQuery.sap.require("sap.ui.model.odata.datajs");

Once you have referenced it, you can use the library to post as follows.

For this example I extended the existing “New Contact” popup form on the Shell layout to capture the needed input, to get the values from the popup I did the following

var firstName = sap.ui.getCore().byId("firstNameTextField").getValue(),
lastName = sap.ui.getCore().byId("lastNameTextField").getValue(),
handle = sap.ui.getCore().byId("handleTextField").getValue(),
email = sap.ui.getCore().byId("emailTextField").getValue(),
status = sap.ui.getCore().byId("statusTextField").getValue();

I then used the values to create the data entry object

var contactEntry = {Handle: handle,
FirstName: firstName,
LastName: lastName,
Email: email,
Status: status};

Declare a variable the service uri

var serviceURI = "http://<host>:<port>/sap/opu/sdata/sap/<service>/Contacts";

Then build a request based on the form data and service uri, making sure you add the applicable XML headers

var request =
{ headers: {"X-Requested-With": "XMLHttpRequest",
"Accept": "application/atom+xml,application/atomsvc+xml,application/xml",
"Content-Type": "application/atom+xml",
"DataServiceVersion": "2.0" },
requestUri: serviceURI,
method: "POST",
user: "developer",
password: "ch4ngeme",
data: contactEntry };

Finally post the request, passing the callback functions
OData.request( request,
function (data) {
//Success Callback
sap.ui.commons.MessageBox.show("New contact saved successfully.", sap.ui.commons.MessageBox.Icon.SUCCESS, "Contact Saved", sap.ui.commons.MessageBox.Action.OK);
},
function (err) {
//Error Callback:
..
}
)

I am hoping with future releases this can be incorporated into the sap.ui.model.odata.ODataModel

Written by rsol1

April 5, 2012 at 3:34 pm

Posted in Uncategorized

Tagged with , , , ,

SAPUI5 data binding master slave with Gateway services

with 6 comments

Spent the day trying out the SAPUI5 framework, of all the new products and initiatives I saw at SAP TechEd last year, this library (collection) sparked my interest the most, mainly because over the years I have used reluctantly JQuery, DOJO, Prototype, YUI, ExtJS etc. on SAP projects, now there is something supported by SAP I can imagine a lot of that reluctance will disappear .

There is a lot in SAPUI5,  it will take me some time to get familiar and comfortable enough to start using on customer sites, I hope they don’t stop here and there is a lot more features and functionality to come. My first impressions are very positive, for some reason the data binding takes me back to a time before WD4A and after HTMLB, reminding me of the flexibility and freedom of BSP or an early WD4J.

It seems appropriate the first thing I developed with SAPUI5 was a data binding master slave solution, it was the first thing I learnt with WD4J and WD4A , it gives a good perspective of what is possible, next up will be MVC.

I have shared on google code a simple example of master slave data binding, it uses the ODATA.org Northwind service (see pic below) , I got it working with an association, but I also show in the code how it is possible using filters.

Written by rsol1

February 16, 2012 at 3:32 pm

Posted in Uncategorized

Tagged with , , , ,

SAP Netweaver Gateway Java Library

leave a comment »

Just finished building my first Android app with the SAP Netweaver Gateway Java Library.  I really like this library it compliments Android nicely.

The generated proxies have a lot of potential, they are easy to use and very flexible. With future releases I hope we get to see a lot more examples, especially around the power of SAP annotations and semantics.

For those interested the app was built with the help of Android In Action http://www.manning.com/ableson3/, by far the best Android book I have read, nicely paced, it pulls no punches and assumes you know what your doing and that you are ready to learn more.

Written by rsol1

February 10, 2012 at 1:41 pm

Posted in Uncategorized

Tagged with , , , ,

Filter String How To

leave a comment »

Today I was asked during a demo to share how I use IV_FILTER_STRING and get round the Filter String Gotcha.

To start with the following code is not optimized and should be used for reference purposes only, for example it uses string values, not types and the select should use an index key select first before getting results.

I use a Paging Query Provider (see image below), it has a method SET_FILTER_STR which converts the provided IV_FILTER_STRING into a table of Filter String Select Options, these values are then passed to a method SET_WHERE_FILTER which is used to assign filter select options to one of 10 available range tables.

The range tables are then used to create a WHERE clause for a generic SQL SELECT statement which looks similar to below.

SELECT ( m_fields )
UP TO ( m_up_to )
INTO  TABLE et_results
FROM ( m_table )
WHERE ( m_where_str )
ORDER BY ( m_order_str )

The Code for the filter string conversion looks something like –

* <SIGNATURE>---------------------------------------------------------------------------------------+
 * | Instance Public Method ZCL_GWPAGINGQUERYPROVIDER->ZIF_GWPAGINGQUERY~SET_FILTER_STR
 * +-------------------------------------------------------------------------------------------------+
 * | [--->] IV_FILTER_STRING               TYPE        STRING
 * +--------------------------------------------------------------------------------------</SIGNATURE>
 METHOD zif_gwpagingquery~set_filter_str.

   DATA:
     lt_filter_select_options TYPE /iwbep/t_mgw_select_option,
     lt_filter_string TYPE TABLE OF string,
     lt_key_value TYPE /iwbep/t_mgw_name_value_pair,
     ls_filter_string TYPE string,
     lv_input TYPE string,
     lv_name TYPE string,
     lv_value TYPE string.

   CONSTANTS:
     co_substringof TYPE string VALUE 'substringof(',
     co_startswith TYPE string VALUE 'startswith(',
     co_endswith TYPE string VALUE 'endswith('.

   FIELD-SYMBOLS:
     <fs_range_tab> LIKE LINE OF lt_filter_select_options ,
     <fs_select_option> TYPE /iwbep/s_cod_select_option,
     <fs_key_value> LIKE LINE OF lt_key_value.

   lv_input = iv_filter_string.

 *--- get rid of ) & ' and make AND's uppercase
   REPLACE ALL OCCURRENCES OF ')' IN lv_input WITH ''.
   REPLACE ALL OCCURRENCES OF `'` IN lv_input WITH ''.
   REPLACE ALL OCCURRENCES OF 'and' IN lv_input WITH 'AND'.
   REPLACE ALL OCCURRENCES OF 'eq' IN lv_input WITH 'EQ'.
   SPLIT lv_input AT 'AND' INTO TABLE lt_filter_string.

 *--- build a table of key value pairs based on filter string
   LOOP AT lt_filter_string INTO ls_filter_string.
     APPEND INITIAL LINE TO lt_key_value ASSIGNING <fs_key_value>.

     IF ls_filter_string CS co_substringof.
       ls_filter_string = substring_after( val = ls_filter_string sub = co_substringof ).
       CONDENSE ls_filter_string.
       SPLIT ls_filter_string AT ',' INTO lv_value lv_name.
       <fs_key_value>-value = |*{ lv_value }*|.
     ELSEIF ls_filter_string CS co_startswith.
       ls_filter_string = substring_after( val = ls_filter_string sub = co_startswith ).
       CONDENSE ls_filter_string.
       SPLIT ls_filter_string AT ',' INTO lv_name lv_value.
       <fs_key_value>-value = |{ lv_value }*|.
     ELSEIF ls_filter_string CS co_endswith.
       ls_filter_string = substring_after( val = ls_filter_string sub = co_endswith ).
       CONDENSE ls_filter_string.
       SPLIT ls_filter_string AT ',' INTO lv_name lv_value.
       <fs_key_value>-value = |*{ lv_value }|.
     ELSE.
       CONDENSE ls_filter_string.
       SPLIT ls_filter_string AT ' EQ ' INTO lv_name lv_value.
       <fs_key_value>-value = |{ lv_value }|.
     ENDIF.
     <fs_key_value>-name = to_upper( lv_name ).
    ENDLOOP.

 *--- add key value pairs to filter select options
   LOOP AT lt_key_value ASSIGNING <fs_key_value>.
     APPEND INITIAL LINE TO lt_filter_select_options ASSIGNING <fs_range_tab>.
     <fs_range_tab>-property = <fs_key_value>-name.
     APPEND INITIAL LINE TO <fs_range_tab>-select_options ASSIGNING <fs_select_option>.
     <fs_select_option>-sign = 'I'.
     IF <fs_key_value>-value CS '*'.
       <fs_select_option>-option = 'CP'.
     ELSE.
       <fs_select_option>-option = 'EQ'.
     ENDIF.
     <fs_select_option>-low = <fs_key_value>-value.
   ENDLOOP.
 *--- call method that create where string for filter select options
   me->set_where_filter( lt_filter_select_options ).
 ENDMETHOD.
.
.
 * <SIGNATURE>---------------------------------------------------------------------------------------+
 * | Instance Public Method ZCL_GWPAGINGQUERYPROVIDER->ZIF_GWPAGINGQUERY~SET_WHERE_FILTER
 * +-------------------------------------------------------------------------------------------------+
 * | [--->] IT_FILTER_SELECT_OPTIONS       TYPE        /IWBEP/T_MGW_SELECT_OPTION
 * +--------------------------------------------------------------------------------------</SIGNATURE>
 METHOD zif_gwpagingquery~set_where_filter.

   DATA:
     lv_property TYPE string,
     lv_range_name TYPE string.

   FIELD-SYMBOLS:
     <fs_filter_select_option> LIKE LINE OF it_filter_select_options,
     <fs_range> TYPE /iwbep/t_cod_select_options.

   LOOP AT it_filter_select_options ASSIGNING <fs_filter_select_option>.
     ADD 1 TO m_range_tabix. "Assumption max 10 filters
     lv_range_name = |MRA_RANGE{ m_range_tabix }|.

     ASSIGN (lv_range_name) TO <fs_range>.
     <fs_range> = <fs_filter_select_option>-select_options.

     lv_property = to_upper(<fs_filter_select_option>-property).
     "build where string
     IF m_where_str IS NOT INITIAL.
       m_where_str = |{ m_where_str } AND |.
     ENDIF.

     m_where_str = |{ m_where_str }{ lv_property } IN { lv_range_name }|.

   ENDLOOP.
 ENDMETHOD.

At runtime.

The result.

Written by rsol1

January 25, 2012 at 2:35 pm

Posted in Uncategorized

Tagged with , , , , ,

Back it up!

leave a comment »

Spent the last 3 days rebuilding my SAP NetWeaver Gateway Pre-Packaged Trial Version for Linux, could have easily been avoided.

Thought i would share a couple of things I had to do post installation.
Update SAP Profile Parameters
– set FQDN
– increased ABAP/BUFFERSIZE
– increased abap/timeout
– increased rdisp/max_wprun_time
– SSL parameters
TODO set SICF time outs optimized for debugging

Found the following blogs useful for the SSL
Setup HTTPS for the SAP NetWeaver Testdrive SR1 on Linux
he Full Monty – Part 5 – HTTPS & Sapcrypto
note: had to enable STRUSTSSO2 before activating SSL service in SMICM

I used WinSCP to edit and FTP files, find this quicker

Ran SGEN (Generate All Objects)
– 65000 objects takes approximately 6 hours

Setup a static ip address – found the following blog very useful
HowTo Configure a network card in Suse/openSUSE 11.x for LAN and Internet Access

Recreated the Gateway services
– backed up everything to SAPLink nuggets, including all the mimes 🙂

Started to use external storage to back up the VM

Written by rsol1

January 24, 2012 at 1:05 pm

Posted in Uncategorized

Tagged with , , ,