We are beginning to implement Gateway at our company, which most of our development is done in a .NET environment. With some new changes in GW SP03, there are a few new things which you must do during the request to perform a modifying (create, update, delete) request around the CSRF tokens. I wanted to share a basic example of how I was able to utilize the native data service client functionality within .NET to perform a Create request to a Gateway service. This particular example is around creation of a material in ECC using BOR objects.

 

I'm not going to go into the creation of the Gateway service, as I will assume this is already done.

 

Create a new C# project in Visual Studio. Once the project is created, we need to add the Gateway service to the project.

 

In Solution Explorer, right click on References then click on Add Service Reference. Once the window opens, add the service by putting the URL to the service in the Address box and click GO. You should see the service name in the Services box along with the collections available for the service. Assign it to a meaningful Namespace and click OK.

 

2012-04-26_08-39-27.png

 

You will now be able to use the native functionality for data services in .NET for your Gateway service.

 

For this example I created just a basic Windows forms application. I have a single form with a text box (to display error messages) and a button (to start the create process).

 

First off, create a few objects to be used in a couple different methods. These will be used to hold the data both received and sent to the Gateway service.

 

    public partial class Debug : Form
    {
        private string csrfToken = String.Empty;
        private string setCookie = String.Empty;
        private CookieContainer cookieJar;

 

Inside the button click method is where I have the following code to actually execute the create request.

 

Basically we check to see if we have the CSRF token stored already, if we don't we have to make a HTTP request to the Gateway server to get the token. Once we have the token and the corresponding cookies, we can proceed with the modifying request.

 

private void button2_Click(object sender, EventArgs e)
        {
            // Setup network credentials object to be used for requests to Gateway server
            System.Net.NetworkCredential credentials = new System.Net.NetworkCredential(Properties.Settings.Default.GW_Username, Properties.Settings.Default.GW_Password);
            
            // Create Gateway objects
            z_material material = new z_material();
            Z_MATERIALS materialClient = new Z_MATERIALS(new Uri(Properties.Settings.Default.GW_Uri));
            materialClient.Credentials = credentials;
            // Check to see if we already have the CSRF token...if not, request it from the server.
            if (this.csrfToken == String.Empty)
            {
                HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(Properties.Settings.Default.GW_Uri);
                HttpWebResponse resp;
                // Add custom header request to fetch the CSRF token
                req.Credentials = credentials;
                req.Method = "GET";
                req.Headers.Add("X-CSRF-Token", "Fetch");
                                
                // Setup cookie jar to capture cookies coming back from Gateway server. These cookies are needed along with the CSRF token for modifying requests.
                cookieJar = new CookieContainer();
                req.CookieContainer = cookieJar;
                try
                {
                    resp = (HttpWebResponse)req.GetResponse();
                }
                catch (System.Net.WebException ex)
                {
                    // Add your error handling here
                    return;
                }
                catch (Exception ex)
                {
                    // Add your error handling here
                    return;
                }
                // Assign values from response to class variables.
                this.csrfToken = resp.Headers.Get("X-CSRF-Token");
                this.setCookie = resp.Headers.Get("Set-Cookie");
            }        
            // Assign values to objects being passed into Gateway request.
            material.material_id = "MIKETEST2";
// commented out rest of value assignment for brevity
            // Use native .NET data service client to build request to add item to collection (CREATE/POST)
            materialClient.AddToz_materialCollection(material);
            // Add event handler to add additional data to service request
            materialClient.SendingRequest += new EventHandler<System.Data.Services.Client.SendingRequestEventArgs>(materialClient_SendingRequest);
            // Post changes to GW server
            try
            {
                materialClient.SaveChanges();
            }
            catch (Exception ex)
            {
                //Add your error handling here
            }  
        }

 

As you can see we've added an event handler to the materialClient object to do some additional processing of the request before it's sent to the server.

 

Here we are going to add the CSRF token to the request headers, along with setting the content type to be what the Gateway server is expecting. Also, we must include the cookies from the response above, or else you will receive an error from the Gateway server with something along the lines of "CSRF token validation failed".

 

        void materialClient_SendingRequest(object sender, System.Data.Services.Client.SendingRequestEventArgs e)
        {
            // If we have a CSRF token, add it to the request headers. Make sure to set Content-Type in headers to correct value.
            if (this.csrfToken != String.Empty)               
                e.RequestHeaders.Add("x-csrf-token", this.csrfToken);
            e.Request.ContentType = "application/atom+xml";
            // Append cookies from response above to modifying request.
            CookieCollection cookies = cookieJar.GetCookies(new Uri(Properties.Settings.Default.GW_Uri));
            foreach (Cookie cookie in cookies)
            {
                e.RequestHeaders.Add("Cookie", cookie.ToString());
            }            
        }

 

And that's it! As long as your Gateway service is setup properly and you're passing in all the appropriate values, you will create your material in the ECC system. This is a very generic example, but hopefully it will help someone out there with the CSRF token validation.

 

Mike Bowen

For all that would like to learn more about SAP NetWeaver Gateway and that are looking for a chance to "get their hands dirty" I can recommend the new course GW100. As of May we have scheduled courses in various locations. The first schedules are available for the following countries:

 

  • Belgium
  • Germany
  • South Africa
  • Switzerland
  • The Netherlands

 

Schedules for other countries will be available soon.

 

The complete schedule can be found on the SAP training web site.

 

Course Goals:

  • Understand the various development and installation options for SAP NetWeaver Gateway
  • Explain what functionality SAP NetWeaver Gateway do and does not provide
  • Understand how to generate a Gateway Service starting from an RFC ABAP Function Module or an Object from the Business Object Repository
  • Develop from scratch your own Gateway Service in ABAP
  • Consume a Gateway Service using either a Java application or a JavaScript (browser) based application

 

Course Content:

  • Introduction to Gateway
  • Introduction to REST
  • Introduction to OData
  • Using the BOR Generator Wizard - QUERY & READ
  • Using the BOR Generator Wizard - CREATE & UPDATE
  • OData Channel Programming (Read only)
  • Monitoring Gateway Services
  • OData Channel Programming (Update)
  • Testing the UPDATE & DELETE operations
  • Front-end Application Development
  • Consuming a Gateway Service using Java
  • Develop a Java Application to Consume a Gateway Service
  • Consuming a Gateway Service using JavaScript
  • Develop a JavaScript Application to Consume a Gateway Service
  • Develop an iPhone Application (Demo only)

 

Best Regards,

André

I recently downloaded the Linux pre-configured gateway trail along with the developer tool for XCode and ran into some issues that none of my newly created services were being displayed in the service list from the tool.

 

After doing some digging it seems the tool was originally developed for Gateway 2.0 SP02 and currently does not seem to support SP03 perfectly. When trying to discover the services it is checking the SData ICF Node versus the OData node which is where all services are defined for Gateway 2.0 SP03. Whats even more odd, is that the services show up only when the new OData Node is completely disabled.

 

If you are having issues discovering the services you have created (possibly in one of the awesome pre-configured gateway trials) open up the /IWFND/MAINT_SERVICE Tcode and try to disable the OData ICF Node. By default the services are created with both SData and OData nodes for backwards compatibility. Then refresh your services in the tool to check if the service is now available.

 

SAP-Gateway.jpg

 

Now .... Back to getting the tool to successfully reading one of my services

A couple of days ago, I was toying with the idea of doing something with SAP Gateway...I thought of using SUP, but as I recently wrote 2 blogs about it, I decided to go back to one of my favorite programming languages...R...

 

So...Gateway can be consumed as ODATA and JSON (If I'm not wrong) is not fully supported, so my only option was ODATA...but R doesn't support ODATA...so I was facing a real problem...

 

I was wrong ODATA is the protocol and JSON and XML are formats...Gateway generates XML right now and JSON is coming soon...special thanks to Wayne Brown (Solution Owner, SAP NetWeaver Gateway)

 

Gladly, R is one of those programming languages that comes to the rescue when you less expect them...by browsing around I found a library to do Web Scrapping...which means that basically I will read the whole XML generated by SAP Gateway, parse it to extract the information I need and the generate a nice graphic to impress someone...BTW...I'm filtering to get only the flights of 'AA', as getting the full list of 1,304 records will make it really hard for R to handle as R doesn't really shine when it comes to processing speed...also parsing that huge XML is a little stressful for anyone...

 

First, I create a simple SAP Gateway service based on BAPI_FLIGHT_GETLIST. Here's the resulting XML:

 

http://lscies1.sapdevcenter.com/sap/opu/sdata/sap/ZFLIGHT_MODEL/zflightCollection?$filter=airline_1 EQ 'QF'&sap-client=520&$format=xml

 

Gateway_R_XML.PNG

 

Then, I did some nice lines of code in R Studio. Basically, it looks for the line that contains the "cityto" tag and then extract everything else that is not, in order to extract only the name of the city. Then we simply, sort the values, sum them and generate the graphic.

 

R_and_Gateway.R

library("plotrix")

 

web_page <- readLines("http://lscies1.sapdevcenter.com/sap/opu/sdata/sap/ZFLIGHT_MODEL/zflightCollection?$filter=airline_1 EQ 'AA'&sap-client=520&$format=xml")

 

mypattern = '<d:cityto>([^<]*)</d:cityto>'
datalines = grep(mypattern,web_page,value=TRUE)
getexpr = function(s,g)substring(s,g,g+attr(g,'match.length')-1)
g_list = gregexpr(mypattern,datalines)
matches = mapply(getexpr,datalines,g_list)
result = gsub(mypattern,'\\1',matches)
names(result) = NULL
airlines <- sort(table(result), decreasing = TRUE)

lbls <- names(airlines)

 

pie3D(airlines,labels=lbls,explode=0.1,
      main="American Airlines")

 

And here's the result...

 

Gateway_R.PNG

 

See you next time

Hi gurus, I want to ask you a question about SAP Gateway.

 

Come on, you get used to read this sentence from upgrading to new SCN. And this is a joke.

 

When I downloaded SAP Netweaver Gateway from SCN it was very easy to setup it on Linux. Ok, I didn’t try to install it on Windows. I found some documents about Gateway. I read them all. It is good to know that documentation is very well on SAP Gateway. I implemented scenarios on the documents.

 

Pros:

  • Easy installation. That's standart ABAP installation
  • It is easy to expose ABAP functions. Just some clicks and voila!
  • Easy to use screens. Mapping screens are enough good to use.

    

Cons:

  • JSON is not supported
  • When you get an error, it is very hard to find where the error is.
  • Hard to remember transaction codes.

 

Well, that's my thoughts about SAP Netweaver Gateway. You can write your own thoughts below blog. Waiting for them!

Gateway allows consuming SAP data by REST and OData, but only for ABAP. Why isn’t SAP offering the same way of consuming data for the Java-based applications?


After all the years where SAP when was promoting web services as the only way for connecting and consuming data, without a doubt, NetWeaver Gateway is a paradigm shift of how SAP data can be consumed. Something is wrong when solution architects want to route all traffic between two systems over a PI system. Why Web Dynpro Java has to use a web service model that is retrieved from PI to talk to an ABAP system is not really obvious, especially when on the PI side no additional business logic is applied. Using PI as a web service proxy is an unnecessary overhead.

 

With Gateway the way to connect is more obvious. Without all the problems associated with web service, consuming REST/OData is relatively easy; and it can be done by Javascript. Not impossible when talking to a web service, but not as easy as with Gateway. From the different Javascript libraries and frameworks out there SAP created its own: SAP UI5: and that can talk directly to the data provided by Gateway.

 

And there we get a problem: Gateway publishes ABAP data. But what if your data is stored in a Java system? Gateway can show its true potential in combination with SAP UI5 or mobile applications. Here it is about giving end-users access to data. Without a doubt by far the largest part of data is stored in an ABAP system; but ignoring the Java part is ignoring the need of the end-user to access SAP data. Not talking about the clients that are using Java based solutions from SAP or developed their own solutions in Java.

 

A front end for SAP UI5 can be a portal. A portal is defined that it allows integration of data from different backends, thus breaking the information silos. NetWeaver Java or the SAP Portal allows integrating various SAP and non-SAP backends in a central place, with user management and single sign on in place. Using this infrastructure makes sense. As you can put SAP UI5 on top of NetWeaver Java, the consumption of the data there is not so easy with SAP UI5. Somehow the data needs to be made available. As there is an extensive API available, it’s meant to be used inside a Java application like a servlet or bean. So why not do a Gateway for Java? That`s not really complicated from a technical perspective.

 

For consuming Java data you can use beans. For consuming ABAP data, you can use the connector framework, JRA or CAF. Every one of these technologies allows for consuming ABAP data (BAPIs) in Java. For displaying them using REST and JSON, the developer can choose between a manual mode or by using a solution like Jersey.

 

Developers can choose between a more purist way and do everything by hand and gain full control over the JSON output or use CAF for designing the beans and then just consume the bean and transform it into JSON. Especially Jersey is a mature solution. Not only allows it for XML or JSON representation of the data, it comes with additional features like REST and OData support. The data representation can be configured in great detail and because it is an add-on solution it can be upgraded independently. Beans, POJO, the representation, as long as it`s Java it can be exposed and the way of doing so con be configured. That means: flexibility.

 

Plus, if I`m not completely mistaken, consuming SAP data by NetWeaver Java means that the business suite users are not charged by additional license costs.

Actions

Filter Blog

By author:
By date:
By tag: