Quantcast
Channel: SAP Gateway
Viewing all 253 articles
Browse latest View live

OData 4.0 is now an OASIS Standard

$
0
0

A new, streamlined and enhanced version of the Open Data Protocol has been approved as an OASIS Standard; see the press release from OASIS. After eighteen months of intense work, several public reviews, and careful consideration of all the feedback received, a joint team from Microsoft, IBM, Red Hat, Citrix, Progress, SAP, and many others now proudly presents OData Version 4.0. The specification consists of four documents:

 

OData fosters easy access to business data and interoperability between different product lines. OData Version 2.0 is supported by many SAP products; to name just a few:

  • SAP NetWeaver Gateway
  • SAP HANA XS
  • SAP Mobile Platform
  • SAP Sybase SQL Anywhere
  • SAP Jam
  • SuccessFactors Employee Central
  • SAP Crystal Reports

 

The new OData Version 4.0 has been shaped by the feedback we received from many product teams using OData at SAP, and our tools and infrastructure teams have closely accompanied the standardization process, providing a valuable reality check for the specification team in the OASIS Technical Committee. One of these teams is driving the Apache Olingo incubator project, providing OData server and client libraries for Java and JavaScript. Initiated by SAP, this open-source project has recently been joined by Microsoft Open Technologies and is now implementing OData 4.0 for Java servers and clients as well as JavaScript clients.

 

I'm looking forward to many SAP products speaking OData 4.0 in addition to the prior version 2.0, allowing to build even more powerful applications.

 

An overview of What's New in OData Version 4.0 has been published by the specification team, and I will write  about the features that are most important for SAP here on SCN.

 

The standardization of OData is an ongoing effort, and the specification team is now focussing on extension specifications, the most important being the OData Extension for Data Aggregation Version 4.0. It recently has reached Committee Specification status, meaning it is ready for implementation.

 

Please have a look at the specifications and comment here on the OData 4.0 features you are most eager to see implemented!


Connecting Google Docs to SAP NetWeaver Gateway

$
0
0

I'll gladly admit: I was really excited when the announcement came last week that Google Docs and Sheets would be open to third-party add-ons developed in Google Apps Script.  It opens the door to all sorts of interesting application integration capabilities, and enhances them with the collaboration tools and ubiquity of Google Drive.

 

The software developer in me immediately thought "I'll bet I can plug that into Gateway!"  The power of SAP NetWeaver Gateway to take anything in a Business Suite system and expose it for consumption through OData REST services means that a wide variety of consumers can make use of this data - and Docs and Sheets are no exception.  There's a built-in API for communicating with other internet services, powerful XML parsing, and even support for an html-based UI paradigm.

 

So here's how I created a simple add-on to read and display data from a Gateway service in a Google Sheets document.  When it's all finished and pulling data, it should look something like this (including the sample data I pulled from my service):

final look apps script project.PNG

 

Prerequisites:

  • A Google account, so you can create documents on your Drive.
  • A Gateway service that returns some sort of useful entity data.  I created a simple service that just spits out contrived data for contracts that I stored in a z-table on the SAP side - but this could be any service you want.
  • Basic knowledge of javascript.  Really not much expertise needed - it doesn't take much code to hook up this minimalist tool.

 

Set up the Apps Script Project:

  • Create a spreadsheet anywhere in your Drive:
    • Sign in at docs.google.com
    • Click the "Create" button on the left side
    • Choose "Spreadsheet"
  • Create an Apps Script project:
    • Open the new spreadsheet
    • Click the "Tools" menu
    • Choose "Script Editor..."
    • On the wizard that appears, choose "Blank Project"

You should see an untitled project with one source code file (Code.gs) and an empty myFunction() declaration like this:

beginning apps script project.PNG

You can name the project anything you like.  When the project is complete and running in your spreadsheet, the name of the project will be the first layer of the add-on menu to navigate to this functionality. 


Build Your Code:

We can code up this simple example in about 150 lines of javascript and html.  I'll split the coding into 3 blocks so as to explain what is going on.

 

First, take out all the existing code in the Code.gs file.  Replace it with the below code:


function onInstall() { 
   onOpen(); 

  
function onOpen() { 
   SpreadsheetApp.getUi().createAddonMenu() 
     .addItem('Retrieve SAP Data', 'showSidebar') 
     .addToUi(); 

  
function showSidebar() { 
   var ui = HtmlService.createHtmlOutputFromFile('Sidebar') 
              .setTitle('Data Viewer'); 
  
   SpreadsheetApp.getUi().showSidebar(ui); 
  


This code is adding the menu under the "Add-ons" menu that appears on the spreadsheet.  It enables you to have the menu structure you wish for your application.  In the next step we'll create the html file necessary to render a sidebar menu.


Why is there an onInstall() and an onOpen(), and onInstall() just calls onOpen()?  It has to do with how installations work in Apps Script.  When you install an add-on, your document is already open and thus does not trigger the onOpen() event.  The onOpen() method is added to onInstall() so that when the script is installed, it also performs the menu setup and other tasks that would normally occur when the document opens.


The addItem() call is registering the function showSidebar() to be triggered when you click on "Retrieve SAP Data".  This is how we're going to open the sidebar menu that we create.


Here's what mine looks like:

menu structure.png

Next, create an html file in your project.  In the menus follow File...New...Html file, and name your html file "Sidebar".  Put the following code in:


<link rel="stylesheet" href="https://ssl.gstatic.com/docs/script/css/add-ons.css"> 
<!-- The CSS package above applies Google styling to buttons and other elements. --> 
  
<div class="sidebar branding-below"> 
   <form> 
   <div class="block" id="credentials">SAP Connection Information<br> 
     <input type="text" id="serviceaddress" placeholder="Service Address"><br> 
     <input type="text" id="userid" placeholder="User ID"><br> 
     <input type="password" id="password" placeholder="Password"> 
   </div> 
   <div class="block" id="button-bar"> 
     <button class="blue" id="read-data">Read Data</button> 
   </div> 
  </form> 
</div> 
  
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"> 
</script> 
<script> 
  
   $(function() { 
     $('#read-data').click(readData); 
   }); 
  
   function readData() { 
  
     var token = $('#userid').val() + ':' + $('#password').val(); 
     var serviceaddress = $('#serviceaddress').val(); 
  
     //Call out to the Code.gs script function readContracts 
     google.script.run 
       .readData(token, serviceaddress); 
  
  } 
  
</script> 


Here we've defined a simple user interface that has four components: an input that accepts a URI for the Gateway service you want to read, an input that accepts an SAP user name, an input that accepts an SAP password, and a button that triggers the read activity.  We've also used the included jQuery to register an event on the button so that when you click "Read Data" you'll call out to the appropriate function to read the data you've chosen.  The nice thing about the html files used for the sidebar is that they can be customized with javascript/css/html like any other part of the web, so they can be very flexible and built to suit a lot of different needs.


Next, go back to the Code.gs file, and insert the below code after the showSidebar() function.


function readData(authinfo, serviceaddress) { 
  
   //Clean up anything currently on the spreadsheet 
   SpreadsheetApp.getActiveSheet().clear(); 
  
   try { 
     var options = { 
       headers: { 
         'Authorization': 'Basic ' + Utilities.base64Encode(authinfo) 
       }, 
     }; 
  
     //UrlFetchApp is a powerful built-in library from Google 
     var response = UrlFetchApp.fetch(serviceaddress, options); 
  
     //Various XML parsing. 
     var xml = response.getContentText(); 
     var document = XmlService.parse(xml); 
     var root = document.getRootElement(); 
     var atom = XmlService.getNamespace('http://www.w3.org/2005/Atom'); 
     var entries = document.getRootElement().getChildren('entry', atom); 
  
     //This loop handles the writing of the response data 
     //to the spreadsheet. 
     var row = 1; 
     for (var i = 0; i < entries.length; i++) { 
       //Navigate the xml response document to get properties/values
       var content = entries[i].getChildren('content', atom); 
       var properties = content[0].getChildren(); 
       var values = properties[0].getChildren(); 
    
       //First pass through the outer loop we will use to also write 
       //the header row, using the properties as column headers. 
       if (i == 0) { 
         var headercolumn = 0; 
         for (var j = 0; j < values.length; j++) { 
           headercolumn++; 
           SpreadsheetApp 
             .getActiveSheet() 
             .getRange(1, headercolumn) 
             .setValue(values[j].getName()); 
         } 
       } 
    
       //Now write the values of the properties 
       row++; 
       var column = 1; 
       for (var j = 0; j < values.length; j++) { 
         SpreadsheetApp 
           .getActiveSheet() 
           .getRange(row, column) 
           .setValue(values[j].getText()); 
    
         column++; 
       }
     } 
   } 
   catch(err) { 
     //Write any retrieve or parse errors into A1 of the main sheet 
     SpreadsheetApp 
       .getActiveSheet() 
       .getRange('A1') 
       .setValue(err.message); 
   }   


This function is the meat and potatoes of this demo.  We're handling basic authorization, the http request and retrieve of service data, and parsing/writing that information into the document.  If I was writing this code for a professional application you can bet I'd be following a few more Code Complete conventions.


(You can see that in this demo we use basic authentication: taking the user ID and password from the sidebar, using the Google provided Utilities.base64Encode(), and passing that into the header of the request. To turbocharge your security/single sign-on, Google also provides some built-in OAuth handling you can check out in the documentation.)


UrlFetchApp is another powerful built-in tool in Apps Script.  This lets you handle the http/https requests and get the responses.  In this case to get at the xml that Gateway is handing back to us, we use the HTTPResponse method getContentText().  It's not built into a full document model yet, so we use yet another built-in tool to create and parse the xml: XmlService.  Any of the response, document, entry, or properties variables in this code are based on parsing that xml.

 

The <entry> node holds a single data record of the response, which is why we base the outer for loop on the number of <entry> nodes.  On the first pass through the loop we also examine the properties of the data, so that we can write out a header line for the data.  After that, it's just a matter of popping the data into cells of the spreadsheet.

 

That's basically it!  We now have a small script that can pull out data from a Gateway service.  This is very very basic stuff - if you want to do anything interesting, you'll obviously have a lot more work in front of you.  Nevertheless, I hope this is food for thought!

There is a Gateway for that ...

$
0
0

For decades, SAP customers and the partners in the ecosystem have been building solutions that access SAP data. For a long time, such access was only possible via a number of proprietary technologies offered by SAP such as RFC, BAPI, IDocs and even Enterprise Services.

 

With the recent popularity of REST (Representational state transfer) against SOA (Service-oriented architecture) which is typically based on the SOAP (Simple Object Access Protocol), SAP is embracing OData (Open Data Protocol) as the protocol to provide standards based access to SAP data.

 

Concept Gateway

Concept Gateway is the vision for a harmonized integration layer by which all SAP solutions can be accessed via OData. To do that individual solutions provide design-time tools for exposing their data as OData services based on their native platforms. The concept also suggest that based on OData services coming from various SAP solutions, a consistent user-experience can be provided by leveraging standards like HTML5 and CSS3 – e.g. SAP UI5.

 

Following diagram depicts “Concept Gateway” inside SAP’s ever increasing solutions portfolio.

CGW.png

SAP NetWeaver Gateway

Built on the traditional ABAP technology, SAP NetWeaver Gateway is a technology solution that provides design-time and runtime features to expose SAP Business Suite data as OData services (i.e. RESTful APIs).

 

SAP NetWeaver Gateway became generally available in October 2011 and by the end of 2013, in about two years it was adopted by more than 7000 customers, productively.

 

NWGW.png

 

With SAP NetWeaver Gateway, customers can build OData services based on existing SAP APIs such as RFC, BAPI, BOR, BOL, MDX, SAP HANA and others. Furthermore, SAP NetWeaver Gateway comes with design-time tools to allow modeling of OData services as well as provisioning of such services from scratch by custom coding, in ABAP.

 

While SAP NetWeaver Gateway is great for exposing SAP data from an ABAP based SAP system, it does not provide tools for exposing data from non-ABAP based SAP systems.

 

Integration Gateway

Over the last 40 years, SAP’s solutions portfolio has grown from traditional ERP to cover 10+ LoBs, 20+ industries in 100+ countries (i.e. localizations) through technology innovations and acquisitions. As a result, a harmonized design-time (as well as user experience) and a harmonized Integration Layer across the portfolio have become essential to bring the benefits that SAP NetWeaver Gateway offers SAP Business Suite customers.

 

Integration Gateway is a technology component that provides design-time tools and the associated run-time for modeling, composing and provisioning OData services based on one or more APIs from various SAP and non-SAP data sources. Among the data sources supported today are, SOAP (Simple Object Access Protocol), JPA (Java Persistence API) and JDBC (Java Database Connectivity) to access non-SAP data sources as well as OData Channel (ODC) for accessing OData services provisioned via SAP NetWeaver Gateway.

 

IGW.png

 

Integration Gateway has been first delivered inside SAP Mobile Platform 3.0 as an on-premise solution. In this version, Integration Gateway has been fully implemented in Java and it runs on SAP Lean Java Server, a lightweight OSGi (Open Services Gateway) based application server.

 

In the future, Integration Gateway will be included in other on-premise or cloud based SAP solutions in their native platforms. However, at this time there are no plans to deliver it as a standalone solution.

 

Integration Gateway and SAP NetWeaver Gateway – Two sides of a coin

SAP NetWeaver Gateway focuses on exposing SAP data from an ABAP based SAP solution as OData services. Hence, it has design-time tools that natively support creating OData services, based on existing SAP APIs (RFCs, BAPIs, etc.) as well as from scratch.

 

Integration Gateway however, takes SAP one step closer to realizing the vision of “Concept Gateway” by bringing OData provisioning beyond SAP Business Suite by supporting several integration protocols and technologies that are well accepted in the industry. Furthermore, when it comes to accessing an SAP Business Suite backed (ABAP based), it relies on the OData services provisioned by SAP NetWeaver Gateway as it supports the ODC (OData Channel) protocol.

 

NGWvsIGW.png

 

NGWvsIGWchart.png

 

Answers to frequently asked questions

 

Q: I need to build an app that will access both SAP and non-SAP data (legacy, solutions from other vendors). Which Gateway do I need?

A: You will need both SAP NetWeaver Gateway and Integration Gateway.

Q: I am building a mobile app and I don’t need to access SAP backend. Do I need SAP NetWeaver Gateway?

A: No. If you don’t need to access SAP Business Suite backend, you may only need Integration Gateway.

Q: Where can I download Integration Gateway?

A: Integration Gateway is not available as a standalone solution. Currently, it only comes with SAP Mobile Platform 3.0.

Q: Where can I download SAP NetWeaver Gateway?

A: SAP NetWeaver Gateway is included in SAP NetWeaver 7.40. For earlier versions (starting from SAP NetWeaver 7.0) you will need to download it as an Add-on from SAP Service Marketplace – http://service.sap.com/swdc (SAP Service Marketplace username password required).

 

 

Best regards,

Mustafa.

Consuming an External RESTful Web Service with ABAP in Gateway

$
0
0

Look, you don't need to tell me.  I already know the truth, deep in my bones: ABAP is not the language the cool kids use.  Not even remotely on their radar.  They've got their Scalas, and their Rusts, and all 30 billion javascript frameworks to build hot startups with.  You can't even play with ABAP unless you work for a place that runs SAP or you're willing to download and install the massive (50 GB!) ABAP trial version

 

But when you look under the covers at the system functionality that ABAP exposes in SAP systems, it becomes apparent that the frameworks, libraries, and system tools that you have at your command can be crafted into an engine to power a phenomenal array of projects.  Just this morning I put together something that - while admittedly not incredibly useful all by itself - shows some of what you can accomplish if you have some familiarity with the tools SAP gives you in ABAP and Gateway. 

 

Let me show you.  It's not a ridiculously complex build, and it's just a slice of what you could do. 

 

At a high level what I've done is find an external RESTful web service, write some ABAP to consume it from the SAP side, and expose that data back out through Gateway.  It's a little bit contrived, since you could easily call this service without Gateway mediating the connection...but I think there are occasional valid reasons to mediate the service through Gateway.  You might have an account with the external service and need to manage your calls to it, or you might want to join the service data with other things from Business Suite services and make it all available in one entity type.  Or you're like me, and you just want to see if it could be done. 

 

I created a developer account with world weather online, so that I could use its API for free.  This lets you use a simple call to get a set of information on weather for a particular location, and in my case I use it to get the day's forecast with a given zip code.  If you sign up, you can use their neat API explorer to test out different ways to use the service. 

 

If I call the main weather service with my home zip code, I get the following structure back (some unnecessary stuff has been trimmed):

<?xml version="1.0" encoding="UTF-8"?>
<data>
   
<request>
       
<type>Zipcode</type>
       
<query>55426</query>
   
</request>
   
<weather>
       
<date>2014-03-27</date>
       
<tempMaxC>5</tempMaxC>
       
<tempMaxF>40</tempMaxF>
       
<tempMinC>-6</tempMinC>
       
<tempMinF>22</tempMinF>
       
<windspeedMiles>15</windspeedMiles>
       
<windspeedKmph>24</windspeedKmph>
       
<winddirection>ESE</winddirection>
       
<winddir16Point>ESE</winddir16Point>
       
<winddirDegree>123</winddirDegree>
        <weatherDesc>
            <![CDATA[Light rain]]>
       
</weatherDesc>
       
<precipMM>9.6</precipMM>
   
</weather>
</data>


Knowing the structure of what comes back to me, I can build some simple ABAP to do the same thing.  I set up a dictionary z-structure to hold the bits of data that I want to use:

weather structure.PNG


I then set up a function module to do pull data from the service and put it into that structure:

 

 

FUNCTION zweather_read_zip.
*"---------------------------------------------------------------
*"*"Local Interface:
*"  IMPORTING
*"     VALUE(IM_ZIPCODE) TYPE  AD_PSTCD1
*"  TABLES
*"      ET_WEATHER STRUCTURE  ZWEATHER
*"---------------------------------------------------------------

  DATA: lo_http_client TYPE REF TO if_http_client,
        lv_service TYPE string,
        lv_result TYPE string,
        lo_ixml TYPE REF TO if_ixml,
        lo_streamfactory TYPE REF TO if_ixml_stream_factory,
        lo_istream TYPE REF TO if_ixml_istream,
        lo_document TYPE REF TO if_ixml_document,
        lo_parser TYPE REF TO if_ixml_parser,
        lo_weather_element TYPE REF TO if_ixml_element,
        lo_weather_nodes TYPE REF TO if_ixml_node_list,
        lo_curr_node TYPE REF TO if_ixml_node,
        lv_value TYPE string,
        lv_node_length TYPE i,
        lv_node_index TYPE i,
        ls_weather TYPE zweather,
        lv_node_name TYPE string,
        lv_node_value TYPE string.

  lv_service = 'http://api.worldweatheronline.com/free/v1/weather.ashx'.

  lv_service =
lv_service && '?q=' && im_zipcode && '&format=xml'.

  lv_service = lv_service && '&key=[use your own!]'.

  cl_http_client=>create_by_url(
    EXPORTING
      url                = lv_service
    IMPORTING
      client             = lo_http_client
    EXCEPTIONS
      argument_not_found = 1
      plugin_not_active  = 2
      internal_error     = 3
      OTHERS             = 4 ).

  lo_http_client->send(
    EXCEPTIONS
      http_communication_failure = 1
      http_invalid_state         = 2 ).

  lo_http_client->receive(
    EXCEPTIONS
      http_communication_failure = 1
      http_invalid_state         = 2
      http_processing_failed     = 3 ).

  "Prepare XML structure
  CLEAR lv_result .
  lv_result = lo_http_client->response->get_cdata( ).
  lo_ixml = cl_ixml=>create( ).
  lo_streamfactory = lo_ixml->create_stream_factory( ).
  lo_istream = lo_streamfactory->create_istream_string(
                                   lv_result ).
  lo_document = lo_ixml->create_document( ).
  lo_parser = lo_ixml->create_parser(
                         stream_factory = lo_streamfactory
                         istream        = lo_istream
                         document       = lo_document ).

  "This actually makes the XML document navigable
  lo_parser->parse( ).

  "Navigate XML to nodes we want to process
  lo_weather_element = lo_document->find_from_name_ns(
'weather' ).
  lo_weather_nodes = lo_weather_element->get_children( ).

  "Move through the nodes and assign appropriate values to export
  lv_node_length = lo_weather_nodes->get_length( ).
  lv_node_index = 0.
  CLEAR ls_weather.
  WHILE lv_node_index < lv_node_length.
    lo_curr_node = lo_weather_nodes->get_item( lv_node_index ).
    lv_node_name = lo_curr_node->get_name( ).
    lv_node_value = lo_curr_node->get_value( ).

    CASE lv_node_name.
      WHEN 'date'.
        REPLACE ALL OCCURRENCES OF '-' IN lv_node_value WITH ''.
        ls_weather-forecast_date = lv_node_value.
      WHEN 'tempMaxF'.
        ls_weather-high_temp_f = lv_node_value.
      WHEN 'tempMinF'.
        ls_weather-low_temp_f = lv_node_value.
      WHEN 'windspeedMiles'.
        ls_weather-wind_speed = lv_node_value.
      WHEN 'winddir16Point'.
        ls_weather-wind_direction = lv_node_value.
      WHEN 'weatherDesc'.
        ls_weather-description = lv_node_value.
      WHEN 'precipMM'.
        ls_weather-precipitation = lv_node_value.
    ENDCASE.

    ADD 1 TO lv_node_index.
  ENDWHILE.

  APPEND ls_weather TO et_weather.

ENDFUNCTION.


 

I sprinkled some comments in the code to help, but I use the cl_http_client class to do the call to the service (and it can be set up and done in just 3 method calls), and then use a few of the xml library classes to parse the result and put it into the structure.  You can see here that though I've only made the zip code dynamic in the call, you could actually be pretty dynamic in choosing services to leverage. 

 

Why did I use a function module?  It's actuallyprettyeasy to use a function module as a basis for building services in SEGW on your Gateway system, so it can be convenient to wrap custom functionality into a function module and then just import definitions.  That's what I did to set up the entity and entity set for this simple service: 

weather demo segw setup.PNG

 

Note especially that the GetEntity method is mapped with zip code as the incoming parameter:

weather demo get entity.PNG


After this, when I activated the service, it's as simple as calling the URI with a parameter of some zip code that I want to see :


weather service result.PNG


Like I mentioned before, by itself this isn't much use.  But combine this with some other information and you start to see what you can really pull together and expose through Gateway.  It's pretty awesome to think that anything you could pull from a REST service on the web can also be a resource for your application. 

Step by Step development for CREATE_DEEP_ENTITY operation

$
0
0

This blog I will explain creation of SAP NW GW OData service which will implement  Create Deep Entity operation.


SAP documentation for deep understanding.


Deep Insert - SAP NetWeaver Gateway - SAP Library


Create Custom RFC  given below Structures.


Structure-1 - Header

Structure-2 - ItemO

Structure-3 - ItemT


1-rfc-sig.PNG21-st-head.PNG2-str-head.PNG22-st-itmt.PNG


Create Project in SEGW

 

Create three entity types and Entity Sets


Entity Type-1- Header    

Entity Type-2- ItemO

Entity Type-3- ItemT


Entity Set-1- HeaderSet

Entity Set-2- ItemOSet

Entity Set-3- ItemTSet



Entity Type - Header

segw-1.PNG

Entity Type - ItemO

segw-1-itemo.PNG

Entity Type - ItemT

segw-2-itemt.PNG

Entity Sets -  HeaderSet,ItemOSet,ItemTSet

segw-eneitysets.PNG



Create Associations given below


Association-1 -  Header_ItemO (Without key fields mapping)

Association-2 -  Header_ItemT (Without key fields mapping)


asso-1-2.PNG


Create Navigation given below


Navigation-1 -  HeadItemO

Navigation-2 -  HeadItemT


novg-1-2-.PNG


Now let’s generate runtime artifacts. Click on generate runtime objects button. It will display

popup . Keep the default class names as-is and click on enter button.

 

Once generation is successful, you will get 4 classes. 2 for Data provider and 2 for Model provider.

serv-reg.PNG

 

Once registration done successfully .Goto Gateway Client ( call transaction /IWFND/GW_CLIENT to open SAP NW Gateway client)

Append $metatda to base service URL and press execute button. If everything is fine then you will HTTP

Response as below. Metadata provides information such as Entity type, key property, properties and Entity Set

name and also check service document append ?$format=xml.

 

metadata.PNGservice doc.PNG

 

 

Build Types for Deep Entity

 

build-deep-str.PNGbuild-deep-str2.PNG

 

Code Snippet


*----------------------------------------------------------------------*
*       CLASS ZCL_ZPROJ_GR_MULTIDEEP_MPC_EXT DEFINITION
*----------------------------------------------------------------------*
*
*----------------------------------------------------------------------*
CLASS zcl_zproj_gr_multideep_mpc_ext DEFINITION
PUBLIC
INHERITING FROM zcl_zproj_gr_multideep_mpc
CREATE PUBLIC .

PUBLIC SECTION.

TYPES :
BEGIN OF ts_deep_entity,
id TYPE char10,
name
TYPE char30,
name2
TYPE char30,
headitemo
TYPE STANDARD TABLE OF ts_itemo WITH DEFAULT KEY,
headitemt
TYPE STANDARD TABLE OF ts_itemt WITH DEFAULT KEY,
END OF ts_deep_entity.

METHODS define
REDEFINITION
.

 

Redefine the DEFINE method of Extended Model Provider class ZCL_ZPROJ_GR_MULTIDEEP_MPC_EXT

 

 

red-mpc.PNG


Code Snippet


METHOD define.
super
->define( ).
DATA:
lo_annotation    
TYPE REF TO /iwbep/if_mgw_odata_annotation,
lo_entity_type   
TYPE REF TO /iwbep/if_mgw_odata_entity_typ,
lo_complex_type  
TYPE REF TO /iwbep/if_mgw_odata_cmplx_type,
lo_property      
TYPE REF TO /iwbep/if_mgw_odata_property,
lo_entity_set    
TYPE REF TO /iwbep/if_mgw_odata_entity_set.

***********************************************************************************************************************************
*   ENTITY - Deep Entity
***********************************************************************************************************************************

lo_entity_type
= model->get_entity_type( iv_entity_name = 'Header' ). "#EC NOTEXT

lo_entity_type
->bind_structure( iv_structure_name  = 'ZCL_ZPROJ_GR_MULTIDEEP_MPC_EXT=>TS_DEEP_ENTITY' ). "#EC NOTEXT

ENDMETHOD
.


Now we have create one custom method (CUSTOME_CREATE_DEEP_ENTITY) in class ZCL_ZPROJ_GR_MULTIDEEP_DPC_EXT



CUSTOM-MET-1.PNGCUST-2-SIGN.PNG


IV_ENTITY_NAME                         Importing            Type      STRING

IV_ENTITY_SET_NAME                 Importing            Type      STRING

IV_SOURCE_NAME                       Importing            Type      STRING

IT_KEY_TAB                                   Importing            Type      /IWBEP/T_MGW_NAME_VALUE_PAIR

IT_NAVIGATION_PATH                Importing            Type      /IWBEP/T_MGW_NAVIGATION_PATH

IO_EXPAND                                   Importing            Type Ref To        /IWBEP/IF_MGW_ODATA_EXPAND

IO_TECH_REQUEST_CONTEXT    Importing            Type Ref To        /IWBEP/IF_MGW_REQ_ENTITY_C

IO_DATA_PROVIDER                    Importing            Type Ref To        /IWBEP/IF_MGW_ENTRY_PROVIDER

ER_DEEP_ENTITY                           Exporting             Type      ZCL_ZPROJ_GR_MULTIDEEP_MPC_EXT=>TS_DEEP_ENTITY


/IWBEP/CX_MGW_BUSI_EXCEPTION

/IWBEP/CX_MGW_TECH_EXCEPTION

 

 

Code Snippet

 

METHOD custome_create_deep_entity.

 
DATA: lr_deep_entity TYPE zcl_zproj_gr_multideep_mpc_ext=>ts_deep_entity,
lt_itemo
TYPE zcl_zproj_gr_multideep_mpc=>tt_itemo,
lt_itemt
TYPE zcl_zproj_gr_multideep_mpc=>tt_itemt,
ls_itemo
TYPE zcl_zproj_gr_multideep_mpc=>ts_itemo,
ls_itemt
TYPE zcl_zproj_gr_multideep_mpc=>ts_itemt.

DATA : ls_general_data TYPE zstr1_header,
lt_itemo_data
TYPE STANDARD TABLE OF zstr1_itemo,
ls_itemo_data
TYPE  zstr1_itemo,
lt_itemt_data
TYPE STANDARD TABLE OF zstr1_itemt,
ls_itemt_data
TYPE  zstr1_itemt.

FIELD-SYMBOLS: <ls_itemo> TYPE zcl_zproj_gr_multideep_mpc=>ts_itemo,
<ls_itemt>
TYPE zcl_zproj_gr_multideep_mpc=>ts_itemt.
 
*  Transform data into the internal structure

io_data_provider
->read_entry_data(
IMPORTING
es_data
= lr_deep_entity ).
 
**********Collect the header fields here
ls_general_data
-id = lr_deep_entity-id.
ls_general_data
-name1 = lr_deep_entity-name.
ls_general_data
-name2 = lr_deep_entity-name2.

********Collect  itemO fields
LOOP AT lr_deep_entity-headitemo ASSIGNING <ls_itemo>.
CLEAR  ls_itemo_data.
ls_itemo_data
-id = <ls_itemo>-ido.
ls_itemo_data
-name = <ls_itemo>-nameo.
APPEND  ls_itemo_data TO lt_itemo_data.
ENDLOOP.

*******Collect itemT fields
LOOP AT lr_deep_entity-headitemt ASSIGNING <ls_itemt>.
CLEAR  ls_itemt_data.
ls_itemt_data
-id = <ls_itemt>-idt.
ls_itemt_data
-name = <ls_itemt>-namet.
APPEND  ls_itemt_data TO lt_itemt_data.
ENDLOOP.
 
********Call RFC
 
CALL FUNCTION 'ZDEEP_RFC'
EXPORTING
ls_header
= ls_general_data
TABLES
lt_itemo 
= lt_itemo_data
lt_itemt 
= lt_itemt_data.

er_deep_entity
-id = ls_general_data-id.
er_deep_entity
-name = ls_general_data-name1.
 
ENDMETHOD
.



Now we have to Redefine the method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY


red-createdeep.PNG


Code Snippet



METHOD /iwbep/if_mgw_appl_srv_runtime~create_deep_entity.

DATA custome_create_deep_entity TYPE zcl_zproj_gr_multideep_mpc_ext=>ts_deep_entity.

CASE iv_entity_set_name.
*-------------------------------------------------------------------------*
*             EntitySet -  HeaderSet
*-------------------------------------------------------------------------*
WHEN 'HeaderSet'.
*       Call the entity set generated method
*      TRY.

CALL METHOD me->custome_create_deep_entity
EXPORTING
iv_entity_name         
= iv_entity_name
iv_entity_set_name     
= iv_entity_set_name
iv_source_name         
= iv_source_name
it_key_tab             
= it_key_tab
it_navigation_path     
= it_navigation_path
io_expand              
= io_expand
io_tech_request_context
= io_tech_request_context

          io_data_provider        = io_data_provider
IMPORTING
er_deep_entity         
= custome_create_deep_entity.

copy_data_to_ref
(
EXPORTING
is_data
= custome_create_deep_entity
CHANGING
cr_data
= er_deep_entity
).
ENDCASE.
ENDMETHOD
.


Coding Part done!!!....Let's move to Testing



Testing


  • Select HTTP method as POST
  • Place the Request URI : /sap/opu/odata/sap/ZPROJ_GR_MULTIDEEP_SRV/HeaderSet
  • Place the External Break point at METHOD CUSTOME_CREATE_DEEP_ENTITY
  • Execute the Service (F8/Execute)


Request Payload

 

 

<?xml version="1.0" encoding="UTF-8"?>
<atom:entry
xmlns:atom=
"http://www.w3.org/2005/Atom"
xmlns:d=
"http://schemas.microsoft.com/ado/2007/08/dataservices"
xmlns:m=
"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
<atom:content type=
"application/xml">
<m:properties>
<d:Id>100</d:Id>
<d:Name>Test</d:Name>
<d:Name2>Test Header2</d:Name2>
</m:properties>
</atom:content>
<atom:link
rel=
"http://schemas.microsoft.com/ado/2007/08/dataservices/related/HeadItemO"
type=
"application/atom+xml;type=feed"
title=
"ZPROJ_GR_MULTIDEEP_SRV.Header_ItemO">
<m:inline>
<atom:feed>
<atom:entry>
<atom:content type=
"application/xml">
<m:properties>
<d:IdO>10</d:IdO>
<d:NameO>Test Item11</d:NameO>
</m:properties>
</atom:content>
</atom:entry>
<atom:entry>
<atom:content type=
"application/xml">
<m:properties>
<d:IdO>20</d:IdO>
<d:NameO>Test Item12</d:NameO>
</m:properties>
</atom:content>
</atom:entry>
</atom:feed>
</m:inline>
</atom:link>
<atom:link
rel=
"http://schemas.microsoft.com/ado/2007/08/dataservices/related/HeadItemT"
type=
"application/atom+xml;type=feed"
title=
"ZPROJ_GR_MULTIDEEP_SRV.Header_ItemT">
<m:inline>
<atom:feed>
<atom:entry>
<atom:content type=
"application/xml">
<m:properties>
<d:IdT>10</d:IdT>
<d:NameT>Test Item21</d:NameT>
</m:properties>
</atom:content>
</atom:entry>
<atom:entry>
<atom:content type=
"application/xml"
>
<m:properties>
<d:IdT>20</d:IdT>
<d:NameT>Test Item22</d:NameT>
</m:properties>
</atom:content>
</atom:entry>
</atom:feed>
</m:inline>
</atom:link>
</atom:entry>

test-1.PNGbreak-1-testing.PNG

 

Before executing method read_entry_data values in lr_deep_entity is initial

brk-2-bfr.PNGbrk-2-bfr2.PNG


After executing method read_entry_data values in lr_deep_entity is not initial


aft-brk-1.PNGaft--brk-2.PNG


Now RFC Will receive the three structure values


rfc1.PNG


Once come out from the debugger ...record will be created in Backend.


succs.PNG

 



      ***************************   Your Done !!! **************************


      Appreciate your suggestions and comments.

Upcoming Webinar: Integration Gateway in SAP Mobile Platform 3.0

$
0
0


This session will introduce you to Integration Gateway and the unique value it adds to SAP Mobile Platform 3.0.


Integration Gateway is a reusable technology component that brings SAP one step closer to realizing its vision of delivering, a REST based, harmonized integration layer amongst all the solutions in SAP portfolio and beyond. To achieve that, Integration Gateway implements a runtime that supports various protocols and standards such as HTTP, ODC, SOAP, JPA and JDBC to access data. Furthermore, it comes with design-time tools that allow modelling and provisioning of new RESTful (OData) web services based on the data sources supported by the runtime. As a result, Integration Gateway complements SAP Gateway by provisioning (RESTful) OData services that expose data not only from any SAP system, but also non-SAP. Best of all, as a reusable component, Integration Gateway capabilities will be available across many SAP solutions consistently.


Please join us by clicking the applicable registration link below:


SAP Internal Employee Session Americas: 

May 14th, 2014  12:00 Noon - 1:00pm (EST)


SAP Internal Employee Session APJ:

May 15th, 2014  12:00 Noon - 1:00pm (SGT)


SAP External (Partners and Customers)* Session Americas:

May 21st, 2014 12:00 Noon - 1:00pm(EST)


SAP External (Partners and Customers)* Session APJ:

May 22nd, 2014  12:00 Noon - 1:00pm(SGT)

 

*Partner and Customers need an S-User for the registration. You can order the S-User here:  http://service.sap.com.

oData for Everything? may be not!

$
0
0

While building ui5 applications using oData, there were may instances where I had to make any adjustments to represent everything coming-out/going-into SAP in terms of oData. Most of the times, these were work-arounds thus telling me that oData is not the one-data-model-fits-all solution.

 

Think about a scenario where I need to validate a user entered VIN number on a UI5 application. All I require is a 'Valid' or 'Invalid' from this functionality. I can create an entity for VIN but that is an overkill for my functionality.

Some other scenarios I can think off are

     - “Update notes for a Sales Order”.

     - “Get drop down values/ dependent values ”

 

Wait! What about Function-Imports? Are they not designed for this exact purpose? Yes, they sound like. But either they return a complex type or an entity type or nothing at all. I do not want to create a complex type for knowing Valid/Invalid. Solution might be to allow Function-Import to return edm types, thoug NW Gateway is not yet supporting it (but part of oData 2.0 spec). Even with this feature, what about the various cover information part of the oData grammar? The other problem with the Function-Import is that it does not allow the request body, thus you need a work around even if you have a simple hierarchical information to be passed to the server.

 

I was going through HANA development training and found something useful. It allows creation of a XSJS service which solves most of these problems. I felt that HANA product has allowed XSJS services in addition to XSODATA services to suit exactly the scenarios I am talking about.

 

But we have ICF services in ABAP server which can do exactly the same by linking with an ABAP Class as request handler. But this would need enhancement to handle system aliases so that I can rout my ICF request from the Gateway system to the right back-end system. CSRF protection might be a good enhancement too.

 

Another solution would be to integrate the new ABAP push channel (Web-socket framework) to NW Gateway and allow it to make use of routing features.

But even with ICF services and ABAP Push channels not integrated with NW Gateway, UI5 developer can make use of these features for the scenarios I discussed, and need not always try to fit everything into an oData Entity.

How To: Enhancing an SAP Fiori App Gateway Service (PO Tracking)

$
0
0

SAP Fiori applications are pretty useful and user-friendly right out of the box.  Side-by-side with this initial usefulness is a set of tools and process that you can use to enhance and extend the delivered services with your own business logic.  As a developer, the first thing I wanted to do was mess around with stuff anyway - so it's nice to know that SAP built in ways for me to do that.

 

My colleague Gavin Quinn got our development environment set up with the available Fiori apps, and I just looked at one of them to try some enhancement stuff.  This is a very very simple example, but I wanted to present what I've done so folks can either learn for themselves or critique my work.  Hopefully a little of both.

 

Things you should note:

  • In this example, I'm using the Track Purchase Order application.  I'm tackling the service enhancements first, and will post later about the Fiori UI enhancement process. 
  • SAP publishes an overview of the apps.  Note that most of these ERP apps have separate pages detailing their extensibility and identify the specific enhancement points. 
  • This app is part of the first wave of Fiori apps.  I can't make any promises that this process will fit all next-gen apps, and in fact future releases of Fiori will probably follow a bit more standardized process for extensions - which I'll make sure to blog about when we get our hands on the next wave. 
  • I am following some of the things on this SAP page, but I have added some steps of my own as I discovered how to get this done.
  • To do the play-at-home version you need the appropriate Fiori installation set up in your ECC system.
  • After every step in enhancing things, I made sure to clean up cache on both my ECC and my Gateway systems.  I found that sometimes I didn't see the changes I wanted until I ran /IWBEP/CACHE_CLEANUP on both systems.  I recommend this as a general step in creating enhancement to the services - it seems to be something that comes up occasionally enough that it saved me time to just keep clearing it.

 

Scenario

The Track Purchase Order app lets you view PO/items/item detail for selected POs.  In the screenshot below, I have chosen the first item from one of our test POs and navigated to the item detail page.  You can see that the item is delivered to one of the plants in our system.  I am going to enhance the backend logic to include the distribution channel for that plant.

PO item detail.PNG

 

Enhancing the entity

If you navigate to SEGW in your ERP system and open project SRA020_PO_TRACKING, you'll see all the entity types available to this service.  The item detail page has its basis in the POItemDetailData entity, which is the entity we'll enhance.

po item detail entity.PNG

 

Instead of redefining the service and editing the entity directly like you would probably do for a custom-developed scenario, we have to edit a data dictionary structure and implement a couple of BAdIs.

 

The ABAP dictionary structure that defines this entity is SRA020_S_PO_ITEM_DETAILED.  If you open that structure and scroll to the bottom of the components list, you'll see that SAP has provided an append SRA020_S_PO_ITEM_DETAILED_INCL.  For my purposes I opened this include and created a customer append that held the field I wanted (vtweg, the distribution channel).

 

append structure for PO thing.PNG

 

Next, you'll need to create an implementation of BAdI SRA020_PO_TRACKING_MPC.  This provides the code hooks to update the runtime definition of the structures of the service.  Go to t-code SE18 and enter the BAdI name in the "BAdI Name" field.

 

Create an implementation with whatever naming conventions your organization uses.  Eventually you'll be led to implement method ENHANCE_GW_SERVICE_ENTITY_MPC in your implementation class.  The simple code I used below will accomplish adding the field to the entity at runtime.

 

METHOD if_sra020_po_tracking_mpc~enhance_gw_service_entity_mpc. 

 

  DATA: lo_property TYPE REF TO /iwbep/if_mgw_odata_property. 

 

  IF iv_entity_type_name = 'POItemDetailData'. 

   lo_property = io_entity_type->create_property( 

           iv_property_name = 'VTWEG' 

           iv_abap_fieldname = 'VTWEG' ). 

 

   lo_property->set_nullable( abap_true ). 

  ENDIF. 

 

ENDMETHOD.

 

At this point, you should be able to see a (blank) VTWEG field in your Gateway service.  As part of getting the Fiori application installed you will end up with a service you can test in Gateway from t-code /IWFND/GW_CLIENT.


 

Getting data at runtime

Now that there's a field in the entity to be a placeholder for the data you want to add, you can implement a different BAdI to fill the live system data you want to into this field.  Once again, t-code SE18 is your friend; enter BAdI SRA020_PO_TRACKING_DPC and do the same stuff.

 

When it's time to implement your code, you'll notice that this BAdI has a lot more available methods.  For the data we want to monkey around with, method CHANGE_POITEMDETAILDATA_API suits our needs.  Code I used:

 

METHOD if_sra020_po_tracking_dpc~change_poitemdetaildata_api. 

 

  TYPES: BEGIN OF ltyp_vtweg, 

       werks TYPE werks_d, 

       vtweg TYPE vtwiv, 

      END OF ltyp_vtweg. 

 

  DATA: lt_vtweg TYPE TABLE OF ltyp_vtweg, 

     ls_vtweg TYPE ltyp_vtweg, 

     lv_vtweg TYPE vtwiv, 

     lt_werks TYPE RANGE OF werks_d, 

     ls_werks LIKE LINE OF lt_werks. 

 

  FIELD-SYMBOLS: <ls_po_items_details> LIKE LINE OF ct_po_items_details. 

 

  LOOP AT ct_po_items_details ASSIGNING <ls_po_items_details>. 

   CLEAR ls_werks. 

   ls_werks-sign = 'I'. 

   ls_werks-option = 'EQ'. 

   ls_werks-low = <ls_po_items_details>-plant. 

   APPEND ls_werks TO lt_werks. 

  ENDLOOP. 

 

  CHECK lt_werks IS NOT INITIAL. 

 

  SELECT werks vtweg INTO CORRESPONDING FIELDS OF TABLE lt_vtweg 

   FROM t001w 

   WHERE werks IN lt_werks. 

 

  CHECK lt_vtweg IS NOT INITIAL. 

 

  SORT lt_vtweg BY werks. 

  LOOP AT ct_po_items_details ASSIGNING <ls_po_items_details>. 

   READ TABLE lt_vtweg INTO ls_vtweg WITH KEY 

    werks = <ls_po_items_details>-plant BINARY SEARCH. 

   IF sy-subrc IS INITIAL. 

    <ls_po_items_details>-vtweg = ls_vtweg-vtweg. 

   ENDIF. 

  ENDLOOP. 

 

ENDMETHOD. 

 

I hope it's obvious here that I'm just taking the PO items' plant (werks) and using that to select on T100W to get the plant's associated distribution channel.  The changing parameter CT_PO_ITEMS_DETAILS has the fields we need to change.

 

After implementing the DPC BAdI you're all done.  You should see the field come into the service data and filled with the appropriate distribution channel.  Proof:

vtweg proof.PNG

 

Hope this helps!  Remember, this doesn't get you all the way there - you still have to update your UI5 to reveal that field on your screen.  I'll be researching that soon and presenting what I find. 


Open Data Protocol

$
0
0

Open Data Protocol

Open Data Protocol (OData) is a data access protocol initially defined by Microsoft. Versions 1.0, 2.0, and 3.0 are released under the Microsoft Open Specification Promise. Version 4.0 is being standardized at OASIS,[1] and was released in March 2014.[2]

The protocol was designed to provide standard CRUD access to a data source via a website. It is similar to JDBC and ODBC although OData is not limited to SQL databases.

 

Architecture

OData is built on the AtomPub protocol and JSON where the Atom structure is the envelope that contains the data returned from each OData request. An OData request uses theREST model for all requests. Each REST command is a POST, GET, PUT, PATCH, or DELETE http request (mapping to CRUD) where the specifics of the command are in the url.

  • GET: Get a collection of entities (as a feed document) or a single entity(as an entry document).
  • POST: Create a new entity from an entry document.
  • PUT: Update an existing entity with an entry document.
  • PATCH: Update an existing entity with a partial entry document.
  • DELETE: Remove an entity.

Any platform that provides support for HTTP and XML is enough to form HTTP requests to interact with AtomPub. The OData specification defines how AtomPub is used to standardize a typed, resource-oriented CRUD interface for manipulating data sources.

 

Typical Workflow When Creating a New User Interface:-

1.png

2.png


3.png

 

Architectural Stack for online Application:-

 

4.png

 

Service Builder – Data Model:-

Create / Model OData  

Artifacts --

  • Entity Types 
  • Entity Sets     
  • Complex Types
  • Associations
  • Association Sets
  • Function Imports    

5.png                                   

-

Generation of runtime objects :-

 

 

6.png

 

 

Service implementation – CRUD methods:-

Direct navigation into the CRUD –

Methods--

  • Create
  • Read and Query
  • Update
  • Delete

 

7.png

8.png

 

Service Builder – runtime artifacts:-

ABAP classes for

  • Model definition
  • Service implementation

Service registration in the

backend


9.png

Service Builder – Result  :-

16.png

/iwfnd/maint_service :-

11.png

 

Service document in the browser and entity types in

SEGW

12.png

 

$metadata document

http://<host>:<port>/sap/opu/odata/sap/ZCD204_EPM_LECTURE_SRV/$metadata

13.png

 

Summary - Transactions you should know as a developer

 

14.png

Gateway Service Builder - development flow in detail

15.png

How to solve language issues in Android app, generated by GWPA

$
0
0

Intro


Within this Blog post, I’d like to share with you the trouble I had – and the solution for it.

 

 

 

Background


I had generated an Android application with SAPGateway Productivity Accelerator (GWPA).
For more information about GWPA please refer to the link section below.

The application connects to an SAP Backend on which Gateway is installed.
The application uses an API that was generated by GWPA.
The aim is to consume Backend-data, which is provided based on the ODATA protocol

When I ran the application on my real device, the backend data was provided in a different language than expected.
In my personal case, it was German.
The issue is not about the concrete language, or about existing or not existing translation of the backend data, short texts, descriptions, etc.
The problem is about how to control the language in which data is returned by the service-call.


Details

 

In my SAP Backend, there’s a Gateway Service.
Built in ABAP, the implementation of the Gateway Service uses BAPIs and RFCs in order to retrieve the desired backend data.
The data is then provided based the ODATA protocol, and can be accessed via the internet.
When requesting the Backend data via a Service call,  a URL is invoked, so the service can be explored with a simple Internet Browser, like e.g. Chrome, Firefox or the Internet Explorer.
In order to access the data, the browser fires an HTTP-request. For reading data it is a GET request.
When requesting data from the SAP Backend, a valid user in the respective system is usually required.
Such a user can have a default logon-language, according to his location and preferences.

 

1) The user logs into the SAP Backend System and provides his langage.
The result is: the data is presented in the desired language

 

2) When executing a service call, the language can be controlled with a parameter that is appended to the URL, after the question mark.
The following example tells the service to deliver the backend data in German translation, if available.

 

?&sap-language=de

 

3) Now, instead of calling the service with the browser, a typical use case is to consume the data with a mobile application.

To make life easy, SAP has provided the GWPA, a toolset that is installed in Eclipse and allows to generate a mobile application with just a few clicks.

Please find a tutorial mentioned in the link section below.


In my case, I used GWPA and happily generated an Android application.

Right after generation, the app could be launched and provided the desired data.

I launched the app on my real device, my real smartphone connected to my (real) PC via (real) USB cable.

I mean: I didn’t use the Android emulator. This makes a difference.


Soon after the first happiness about the successful retrieval of data, I got the first trouble:

The data looked strange…

Some properties were empty, others had strange German texts.

So it looked like the logon happened in German language and some texts were simply not translated (therefore empty), others weren’t properly translated, probably because the connected backend wasn't a productive system.

But why was the data delivered in German?


I set the default logon language of the specified user in the SAP Backend to English, without success.

I carefully checked the code: obviously, the generated code didn’t explicitly set the language to German.

I carefully checked the Android log file: no hint about a specific language setting.

It looked like the device-language was used.

 

What now?

 

 

The solution

 

So I had to control the language in my GWPA-based Android app.
After some research in the API that is provided by GWPA, the solution is to add the following 2 lines to the generated code:

 

requestHandler.getConnectivityHelper().setSendLanguageHeader(false);
requestHandler.getConnectivityHelper().getParameters().setLanguage("en");

 

That’s the solution.

 

The remaining question is: where to place these 2 lines?


The code snippets show that the generated Android application provides an object called RequestHandler which provides support for programmatically executing service calls to the service URL that is defined in the application.
It also provides one single entry for all the configuration that is required for executing service calls: e.g. the SAP backend-client, the user, the desired format (json or atom), the service-URL, etc
As a consequence, it is also the right place to configure the language settings.

In the generated code, the instance of the RequestHandler is obtained in the onCreate() method of the launcher-Activity .
You can also search the generated code for the member-variable named “requestHandler”.
Please note: since the RequestHandler is bound to the service, the name of the Java class is generated as a concatenation of service name and “RequestHandler”.

Example:  <MYSERVICENAME>RequestHandler

 

Once you’ve found the place where the RequestHandler is instantiated and configured, you can simply add the 2 lines mentioned above.

 


Alternative

 

The object com.sap.gwpa.proxy.connectivity.SDMConnectivityHelper provides access to the instance of com.sap.mobile.lib.request.ConnectivityParameters, which contains a specific method setLanguage() for the language parameter.
If you need to set an own custom parameter, you have a different option.

 

The object where you can get access to the URL in order to add your own parameters is the com.sap.gwpa.proxy.ODataQuery object.
The instance of this object is used in the generated methods of the RequestHandler.
As expected, the RequestHandler contains methods which correspond to the HTTP operations: GET, POST, DELETE, etc
Examples:


createProductSetEntry()
loadSalesOrderSet()
deleteBusinessPartnerSetEntry()

 

Each of such methods deals with the ODataQuery instance.
There, you can add your own parameter.
Example:

query.addParameter("sap-language", "en");


 

 

Conclusion

 

I hope that this blog post has been able to help anybody to get comfortable with configuring the code generated by GWPA.

If you have any suggestion or correction, please add it to the comment-section below.

Thanks.

 

 

Links

 

GWPA introduction: http://scn.sap.com/community/netweaver-gateway/blog/2013/05/10/new-gateway-tool--sap-netweaver-gateway-productivity-accelerator
GWPA announcement: http://scn.sap.com/community/netweaver-gateway/blog/2013/06/03/gateway-productivity-accelerator-10-launched
Getting started with GWPA: Prerequisites
Getting started with GWPA: Android Preparation
Tutorial for Android Starter Application: http://scn.sap.com/community/netweaver-gateway/blog/2012/07/18/developing-an-android-app-consuming-data-from-sap-is-just-a-few-clicks-away

Initiatives on integrating Google Apps with SAP Gateway

$
0
0

If you are familiar with NetWeaver Gateway, you know how Gateway can be open and flexible to connect devices, environments and platforms with any programming languages by leveraging REST services and OData protocol. Gateway has been widely adopted by many SAP products such Fiori, Duet Enterprise for Microsoft SharePoint, SAP Mobile Platform, SAP Lumira, etc.

 

With more enterprise companies using Google Apps (like Gmail, Docs, Sheets, etc.) in their daily business, the growing demand of consuming data from SAP to Google Apps shows its potential in the market.  Last fall, we had the opportunity to explore this Google integration channel with Gateway with 2 SAP customers in the U.S.

 

Initially, from SAP side, we provided the test landscape maintained by the SAP Developer Center. Then, Google team had successfully consumed a service of Product object as an example to display product information in the Google Sheets from SAP ERP system. The Google Apps runs on their Google cloud technology consume the REST services exposed by SAP NetWeaver Gateway. This shows huge potential of improving the productivity for our customers and even customers’ customers when more data from SAP can be accessed through Google Apps via cloud or mobility.

 

 

sap-goog-integration.png

 

The proof-of-concept projects are underway.  We are collaborating with Google and the customers as co-innovation projects identifying the following scenarios for the projects:

1. Create and update data in SAP backend using Google forms / Docs

2. Generate report in Google Sheets

3. SAP Workflow approval via Gmail client

 

On the other hand, for SAP Partners who build and sell enterprise solutions with SAP and Google technologies, they can participate in our new 2014 SAP and Google Application Challenge. Participating members will receive enablement and certification support. The finialists will get a chance to win a pair of Google Glass as well. For more details, check the page here.

https://www.sapappsdevelopmentpartnercenter.com/en/apps-challenges/

How to solve language issues in Android app, generated by GWPA

$
0
0

Intro


Within this Blog post, I’d like to share with you the trouble I had – and the solution for it.

 

 

 

Background


I had generated an Android application with SAPGateway Productivity Accelerator (GWPA).
For more information about GWPA please refer to the link section below.

The application connects to an SAP Backend on which Gateway is installed.
The application uses an API that was generated by GWPA.
The aim is to consume Backend-data, which is provided based on the ODATA protocol

When I ran the application on my real device, the backend data was provided in a different language than expected.
In my personal case, it was German.
The issue is not about the concrete language, or about existing or not existing translation of the backend data, short texts, descriptions, etc.
The problem is about how to control the language in which data is returned by the service-call.


Details

 

In my SAP Backend, there’s a Gateway Service.
Built in ABAP, the implementation of the Gateway Service uses BAPIs and RFCs in order to retrieve the desired backend data.
The data is then provided based the ODATA protocol, and can be accessed via the internet.
When requesting the Backend data via a Service call,  a URL is invoked, so the service can be explored with a simple Internet Browser, like e.g. Chrome, Firefox or the Internet Explorer.
In order to access the data, the browser fires an HTTP-request. For reading data it is a GET request.
When requesting data from the SAP Backend, a valid user in the respective system is usually required.
Such a user can have a default logon-language, according to his location and preferences.

 

1) The user logs into the SAP Backend System and provides his langage.
The result is: the data is presented in the desired language

 

2) When executing a service call, the language can be controlled with a parameter that is appended to the URL, after the question mark.
The following example tells the service to deliver the backend data in German translation, if available.

 

?&sap-language=de

 

3) Now, instead of calling the service with the browser, a typical use case is to consume the data with a mobile application.

To make life easy, SAP has provided the GWPA, a toolset that is installed in Eclipse and allows to generate a mobile application with just a few clicks.

Please find a tutorial mentioned in the link section below.


In my case, I used GWPA and happily generated an Android application.

Right after generation, the app could be launched and provided the desired data.

I launched the app on my real device, my real smartphone connected to my (real) PC via (real) USB cable.

I mean: I didn’t use the Android emulator. This makes a difference.


Soon after the first happiness about the successful retrieval of data, I got the first trouble:

The data looked strange…

Some properties were empty, others had strange German texts.

So it looked like the logon happened in German language and some texts were simply not translated (therefore empty), others weren’t properly translated, probably because the connected backend wasn't a productive system.

But why was the data delivered in German?


I set the default logon language of the specified user in the SAP Backend to English, without success.

I carefully checked the code: obviously, the generated code didn’t explicitly set the language to German.

I carefully checked the Android log file: no hint about a specific language setting.

It looked like the device-language was used.

 

What now?

 

 

The solution

 

So I had to control the language in my GWPA-based Android app.
After some research in the API that is provided by GWPA, the solution is to add the following 2 lines to the generated code:

 

requestHandler.getConnectivityHelper().setSendLanguageHeader(false);
requestHandler.getConnectivityHelper().getParameters().setLanguage("en");

 

That’s the solution.

 

The remaining question is: where to place these 2 lines?


The code snippets show that the generated Android application provides an object called RequestHandler which provides support for programmatically executing service calls to the service URL that is defined in the application.
It also provides one single entry for all the configuration that is required for executing service calls: e.g. the SAP backend-client, the user, the desired format (json or atom), the service-URL, etc
As a consequence, it is also the right place to configure the language settings.

In the generated code, the instance of the RequestHandler is obtained in the onCreate() method of the launcher-Activity .
You can also search the generated code for the member-variable named “requestHandler”.
Please note: since the RequestHandler is bound to the service, the name of the Java class is generated as a concatenation of service name and “RequestHandler”.

Example:  <MYSERVICENAME>RequestHandler

 

Once you’ve found the place where the RequestHandler is instantiated and configured, you can simply add the 2 lines mentioned above.

 


Alternative

 

The object com.sap.gwpa.proxy.connectivity.SDMConnectivityHelper provides access to the instance of com.sap.mobile.lib.request.ConnectivityParameters, which contains a specific method setLanguage() for the language parameter.
If you need to set an own custom parameter, you have a different option.

 

The object where you can get access to the URL in order to add your own parameters is the com.sap.gwpa.proxy.ODataQuery object.
The instance of this object is used in the generated methods of the RequestHandler.
As expected, the RequestHandler contains methods which correspond to the HTTP operations: GET, POST, DELETE, etc
Examples:


createProductSetEntry()
loadSalesOrderSet()
deleteBusinessPartnerSetEntry()

 

Each of such methods deals with the ODataQuery instance.
There, you can add your own parameter.
Example:

query.addParameter("sap-language", "en");


 

 

Conclusion

 

I hope that this blog post has been able to help anybody to get comfortable with configuring the code generated by GWPA.

If you have any suggestion or correction, please add it to the comment-section below.

Thanks.

 

 

Links

 

GWPA introduction: http://scn.sap.com/community/netweaver-gateway/blog/2013/05/10/new-gateway-tool--sap-netweaver-gateway-productivity-accelerator
GWPA announcement: http://scn.sap.com/community/netweaver-gateway/blog/2013/06/03/gateway-productivity-accelerator-10-launched
Getting started with GWPA: Prerequisites
Getting started with GWPA: Android Preparation
Tutorial for Android Starter Application: http://scn.sap.com/community/netweaver-gateway/blog/2012/07/18/developing-an-android-app-consuming-data-from-sap-is-just-a-few-clicks-away

Initiatives on integrating Google Apps with SAP Gateway

$
0
0

If you are familiar with NetWeaver Gateway, you know how Gateway can be open and flexible to connect devices, environments and platforms with any programming languages by leveraging REST services and OData protocol. Gateway has been widely adopted by many SAP products such Fiori, Duet Enterprise for Microsoft SharePoint, SAP Mobile Platform, SAP Lumira, etc.

 

With more enterprise companies using Google Apps (like Gmail, Docs, Sheets, etc.) in their daily business, the growing demand of consuming data from SAP to Google Apps shows its potential in the market.  Last fall, we had the opportunity to explore this Google integration channel with Gateway with 2 SAP customers in the U.S.

 

Initially, from SAP side, we provided the test landscape maintained by the SAP Developer Center. Then, Google team had successfully consumed a service of Product object as an example to display product information in the Google Sheets from SAP ERP system. The Google Apps runs on their Google cloud technology consume the REST services exposed by SAP NetWeaver Gateway. This shows huge potential of improving the productivity for our customers and even customers’ customers when more data from SAP can be accessed through Google Apps via cloud or mobility.

 

 

sap-goog-integration.png

 

The proof-of-concept projects are underway.  We are collaborating with Google and the customers as co-innovation projects identifying the following scenarios for the projects:

1. Create and update data in SAP backend using Google forms / Docs

2. Generate report in Google Sheets

3. SAP Workflow approval via Gmail client

 

On the other hand, for SAP Partners who build and sell enterprise solutions with SAP and Google technologies, they can participate in our new 2014 SAP and Google Application Challenge. Participating members will receive enablement and certification support. The finialists will get a chance to win a pair of Google Glass as well. For more details, check the page here.

https://www.sapappsdevelopmentpartnercenter.com/en/apps-challenges/

Intelligent Automation for the Enterprise through SAP Gateway

$
0
0

Quantilus is excited to have the SAP Gateway team showcase our demo apps at SAPPHIRE NOW 2014. Our mission has been to build innovative applications to streamline business workflows, and SAP Gateway has given us the perfect tool to utilize the power of cutting edge technologies like augmented reality and machine vision in practical business applications.

SAP Gateway has allowed us to focus on building our applications without having to spend time and effort on backend integration, since the integration is seamless and instantaneous.   As a result, our total development time for these products has been exceptionally quick.


Visual Showroom

3D product visualization using augmented reality

 

vissho.png

 

Visual Showroom is an app developed for retailers that allows customers to shop in a virtual 3D environment in the context of their real environment. Using a tablet or a smartphone, users view 3D catalog items in situ, and place orders directly from the app.

Practical applications for this include but are definitely not limited to:

  • Interior Decorating and Design - Customers can visualize an item exactly where they want to place it in their home or office.  They can view a couch against a wall in the living room, or an entertainment center across from it. Users can select different colors, textures and materials for the furniture and visualize in situ.
  • Clothing/Apparel – Customers can view renderings of clothing in different styles and colors on a 3D image of their own bodies. They can capture screenshots and compare different “looks” before placing orders online.
  • Accessories - Customers can visualize 3D renderings of watches, sunglasses, jewelry and other accessories against their own bodies or on others. This can now solve the eternal question of "This looks good on the screen, but how will it look on me?"

 

It is painstaking and time consuming process (even for a professional designer) to estimate the fit and look of a product in a space or on a person.  Visual Showroom gives your customers a very real idea of how things will fit and how they will look.

 

This video demonstrates the features of the Visual Showroom app:


Visual Showroom Architecture:


SAP_arch.png



SAP Gateway is used to extract and display product information, their variants, inventory level, delivery date etc. SAP Gateway is also used to place orders directly from the application into the SAP Business Suite.

Visual Showroom is a multi-platform app, and is currently supported on iOS 7 (iPad 3 and above), and Android (most tablets and phones running Android 4.3 and above).

 

GoToWork

Wearable devices (Google Glass) for workflow automation

gotowrk.png


GoToWork is a Google Glass app developed to significantly increase the efficiency of technical support personnel using machine vision and a voice user interface. Technicians can interact with the app in multiple modes while maintaining focus on tasks with both hands free. The primary features of GoToWork are:

  • GoToWork uses advanced voice recognition technology, enabling users to work “hands-free”.
  • Machine Vision is used to scan and identify products and parts. Data points are compared to product data in SAP to uniquely identify products.
  • Technicians can get step-by-step instructions, watch instructional videos, or share their viewport with experts for diagnosis and troubleshooting.
  • Users can directly check for the availability of specific parts in inventory and place orders for replacement parts.

 

This video demonstrates the use of GoToWork in a technical support scenario, where the technician can use both of her hands while getting instructions and product/inventory data through Google Glass:

 

The features of GoToWork can be easily customized for various business scenarios, such as:

  • Assembly Instructions – Users can get instructions for assembling and installing a product (furniture, electronics, etc.) by scanning a code or the product packaging. Users can also identify missing parts in the package and order the parts through the app. 
  • Locating Products in a store - The app can guide a user to the physical location of a product (aisle, bin, etc.) in a store. Users can place an order for a product in-app and go to the store to pick it up – the app will act as a “store GPS”. 
  • User Guides – User can get instructions on how to use a device or equipment (kitchen appliances, exercise equipment, computers, etc.) Users can scan the equipment and have GoToWork guide them on proper usage. GoToWork can also provide cross-selling suggestions for users to purchase from within the app.

 

SAP Gateway is used to retrieve the 3D model from SAP and to receive product master data. SAP Gateway is also used to check inventory levels of products and parts, and to place orders directly through the GoToWork app.  


GoToWork is currently built for and deployed on Google Glass, and can be extended for use on other wearable Android-based hardware.

 

We look forward to demonstrating these applications at SAPPHIRE, receiving your feedback and answering any questions that you may have. Feel free to reach out to us at info@quantilus.com for information about our apps or about our experience working with SAP Gateway.



Recognizing file name and type in browser after downloading file from Netweaver Gateway

$
0
0

Let's consider that we have working solution of file download from gateway as it is described for example in this blog How to Read Photo from SAP system using SAP NetWeaver Gateway.

 

When we point to the file, browsers does not handle the file name correctly, as they consider $value as name of the file. Thus it is not comfortable to open the file. Also, file name is shown as $value too which is inconvenient for the user when he wants to save the file.

 

To solve this issue we can set content-disposition response header according to rfc 1806 to inline and set the name of file there. Then browser will be able to recognize the name, user can save it with the name as it is set in SAP system.

 

 

Here is the sample code of method GET_STREAM implementation:

METHOD /iwbep/if_mgw_appl_srv_runtime~get_stream.     DATA: ls_stream      TYPE ty_s_media_resource,           er_entity      TYPE REF TO data,           lr_entity      TYPE REF TO data,                      ls_file  TYPE cl_sample_mpc=>ts_file,           ls_lheader     TYPE ihttpnvp.     CASE iv_entity_name.       WHEN 'File'.
* Load ls_file info here         ls_stream-value = ls_file-content.         ls_stream-mime_type = ls_file-mime_type.         ls_lheader-name = 'Content-Disposition'.         ls_lheader-value = 'inline; filename="'.         CONCATENATE ls_lheader-value ls_file-file_name INTO ls_lheader-value.         CONCATENATE ls_lheader-value '"' INTO ls_lheader-value.         set_header( is_header = ls_lheader ).         copy_data_to_ref( EXPORTING is_data = ls_stream                           CHANGING  cr_data = er_stream ).     ENDCASE.   ENDMETHOD.

 

 

 

 

UPDATE: Escaping characters

If the file name contains specials characters, or just space, it is necessary to escape characters in the backend. To do so, following method can be used:

ls_file-file_name = escape( val = ls_file-file_name                                                   format = cl_abap_format=>e_url ).

Uploading files to SAP using HTML5 /AJAX/Gateway media links with real-time progress bar

$
0
0

Dear All,

This blog will walk you through step-by-step to upload files from an HTML5 webapp.

Here is the short overview of what technologies we are going to use to successfully load a binary file from a client machine to a remote SAP server.

 

HTML5 File reader : The FileReader object lets web applications asynchronously read the contents of files (or raw data buffers) stored on the user's computer. We use readAsArrayBuffer method to read the contents of a specified Blob or File.

 

Jquery AJAX:To exchange data to and from server, and updating parts of a web page - without reloading the whole page.

Putting much simpler, AJAX is to load data in the background(asynchronous) and display it on the webpage.

 

HTML5 progress bar: To track real time progress when file is getting uploaded...

 

Gateway media links: The OData Channel from gateway provides us the interface to receive binary data from the front end and then

stored it in an SAP Business Suite backend system whatever applies.

 

Enough theory.Lets get started...

 

<!DOCTYPE html>

<html>

  <head>

  <script src="https://code.jquery.com/jquery-1.11.0.min.js" type="text/javascript" > </script>

    <script type="text/javascript">

    var token1 = '';

    var xhr = new window.XMLHttpRequest();

    var file = " ";

    function upload() {

         file = document.getElementById('attafh').files[0];

 

        if (file) {

            UploadMe(file);

        }

    }

 

    function UploadMe(readFile) {

        var reader = new FileReader();

        reader.readAsArrayBuffer(readFile); //array buffer

        reader.onload = loaded;

//         reader.onerror = errorHandler;

    }

 

    function loaded(evt) {

 

        var fileString = evt.target.result;                  

          ///**** Save Personal Details & Questions & Files *****/

         // Begin of Get X-CSRFT token

             $.ajax({

                 url: 'https://test.com:8080/sap/inv/opu/odata/sap/Z_GET_ATTACHMENTS_SRV/$metadata',

                 type: "GET",

                 contentType: "application/atom+xml;type\x3dentry;",

                 dataType: "",

                 headers: {

                     "x-csrf-token": "fetch",

                     Authorization: "Basic ZDDDDDDDDD="

                 },

             success: function (data, textStatus, request) {

             token1 = request.getResponseHeader('x-csrf-token');

    

    

                 $.ajax({       

                  type: 'POST',

                  url: "https://test.com:8080/sap/inv/opu/odata/sap/Z_GET_ATTACHMENTS_SRV/Documents/",                   

                   xhr: function()

                 {           

                    //Upload progress

                     xhr.upload.addEventListener("progress", function(evt){

                      if (evt.lengthComputable) {

                        var percentComplete = Math.round(evt.loaded * 100 / evt.total);

                     $('.progress').val(percentComplete);

                       //Do something with upload progress

                       console.log(percentComplete);

                      }

                    }, false);

                             

                  xhr.addEventListener("error", function(evt){

                alert("There was an error attempting to upload the file.");

                return;

                    }, false);

         

                    return xhr;

                 },

        

                contentType: "application/json",

                processData: false,                   

                data: fileString,

                dataType: "text",

                headers: {

                          "x-csrf-token" : token1,

                          "Authorization" : "Basic ZDDDDDDDDDD",

                          "slug": file.name + "|" + file.type + "|" + file.size + "|"

                },

                success: function(data){

                   alert("File uploaded successfully");

                  }

                });

           

                  }

             });

    };

 

    function abortRead() {

    xhr.abort();

    $('.progress').val(0);

      }

    </script>

  </head>

  <body>

    <input type="file" id="attafh"  class="AlltextAccount"  />

      <input type="button" value="upload" onclick="upload()" />

      <button onclick="abortRead();">Cancel</button>

      <progress class="progress" value="0" max="100"> </progress>

 

 

  </body>

</html>

 

What above code does is, we had a file placed in the Body and when choose file and upload, we extracted the contents using File reader.

For sending this to SAP gateway, we need X-CSRF-Token to make any modifications request. Please note the AJAX heaeders when making POST request.

"ProcessData" has to be set false. Also parameter "Slug" can be used to send file name, type and size. Later this can be split in the server using "SPLIT" statement.

For tracking progress in real time we make of this event. xhr.upload.addEventListener("progress", function(evt).

 

Upload_1.png

 

We can custom tailor the progress bar theme too...

HTML:

   <progress class="progress" value="0" max="100" class="html5">

  </progress>

 

CSS:

 

progress[value] {

  -webkit-appearance: none;

   appearance: none;

 

 

  width: 150px;

  height: 22px;

  padding-top: 5px;

  display:none

 

}

 

 

progress[value]::-webkit-progress-bar {

  background-color: #eee;

  border-radius: 2px;

  box-shadow: 0 2px 5px rgba(0, 0, 0, 0.25) inset;

}

 

 

progress[value]::-webkit-progress-value {

background-image:

  -webkit-linear-gradient( 135deg,

  transparent,

  transparent 33%,

  rgba(0,0,0,.1) 33%,

  rgba(0,0,0,.1) 66%,

  transparent 66%),

    -webkit-linear-gradient( top,

  rgba(255, 255, 255, .25),

  rgba(0,0,0,.2)),

     -webkit-linear-gradient( left, #09c, #690);

     border-radius: 2px;

    background-size: 35px 20px, 100% 100%, 100% 100%;

}

 

 

Result:

Upload2.png

 

You can check below link to know more on this.

http://css-tricks.com/html5-progress-element/

http://lea.verou.me/polyfills/progress/

 

Coming to server side we just needd to create an Entity type with "Media" flag set. And implement the steps covered in these blogs.

How To Upload and Download Files Using SAP NW Gateway SP06

 

scn.sap.com/community/netweaver-gateway/blog/2013/02/22/how-to-read-photo-from-sap-system-using-sap-netweaver-gateway

 

Thanks to the above blogs for their valuable contributions.

 

Code :

method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_STREAM.

 

 

  FIELD-SYMBOLS:<FS_DOC> TYPE ZUPLOAD_DOC.

  Data:ls_doc type ZUPLOAD_DOC,

       lt_file_info type table of string,

       ls_file_info like line of lt_file_info,

       ls_result type ZBAPIRETURN,

       lv_file_info type string.

 

  Data:

       lv_file_name type /GC1/DTE_MSG_TXT,

       lv_file_type type /GC1/DTE_MSG_TXT,

       lv_file_length type string,

       lv_index type sy-tabix.

 

 

  data: lt_doc type table of ZUPLOAD_DOC.

 

 

  CREATE DATA ER_ENTITY TYPE ZUPLOAD_DOC.

  ASSIGN:ER_ENTITY->* TO <FS_DOC>.

 

//File name and other arguements will be received here..

  lv_file_info = iv_slug.

 

 

  split lv_file_info at '|' into table lt_file_info.

  IF sy-subrc eq 0.

    LOOP AT lt_file_info into ls_file_info.

      lv_index = sy-tabix.

      CASE  lv_index.

        WHEN 1.

          lv_applid = ls_file_info.

        WHEN 2.

          lv_file_name = ls_file_info.

        WHEN 3.

          lv_file_type = ls_file_info.

        WHEN 4.

          lv_file_length = ls_file_info.

        WHEN 5.

      ENDCASE.

      clear:ls_file_info,lv_index.

    ENDLOOP.

 

    ls_doc-FNAME = lv_file_name.

    ls_doc-FTYPE = lv_file_type.

    ls_doc-FLENGTH = lv_file_length.

    ls_doc-fcontent = is_media_resource-value."File content will be here.

   append ls_doc to lt_doc[].

        <FS_DOC> = ls_doc.

    endif.

  ENDIF.

 

endmethod.

 

 

Result after reaching server:

Upload3.png

 

Upload_4.png

 

File received successfully.

 

The above logic can handle filesof type .doc, .docx, .pdf, .png, .jpg, .xls, .xlsx.

Please note that this functionality only in modern browsers which supports HTML5 - File API.

I am planning to do a writeup on handling legacy browsers IE9 and below too and also to handle multiple files as well.

 

Please share your feedback and welcome your corrections to improve this content.

 

Cheers

Prabaharan

Disabling Cache for CRUD/FI OData scenarios for a UI5 Application on Internet Explorer

$
0
0

This Blog attempts to make its audience understand the way to disable the cache content for UI5 Applications using SAP Netweaver Gateway/OData. It should be noted that there are mechanisms to disable the cache in a UI5 development environment but the blog focusses on disabling them using SAP Netweaver Gateway Implementation.

 

Understanding the Scenario - I'm Curious

 

Q: What is the need to disable the CACHE in a UI5 Application that consumes OData Services ?

A: While performing a specific change/functionality in a UI5 application, it is desired that the Application loads fresh data from the backend and does not display stale/unchanged data.

 

Q: When does this happen ?

A: Specifically, When an OData service is called to perform an UPDATE operation, A Read is not enforced to fetch the updated DATA.

 

Q: So Why use GATEWAY/OData to disable cache on a service layer, Why not UI5 environment on an application layer ?

A: UI5 applications are browser specific applications. For some of the browsers: IE, Firefox - The browser engine does not force a cache READ and has its limitations when trying to READ the data after an update is performed.

 

Q: Is this a restriction on only CRUD Services ?

A: This behaviour is exhibited for CRUD and Function Import/Non CRUD Operations as well.

 

Q: Is this a common development to adapt for for all the browsers ?

A: IE specifically, Firefox and Chrome are scenario centric.

 

 

Feeling contented.... Read Further ...

 

~~ How do I do it ?

  • Ok, Let's get down to some Business. What OData scenario am I looking at ?

          How about a CRUD Operation : Let's say an Update !

      

  1. Navigate to your DPC Ext Implementation and locate the CORE_SRV_RUNTIME~READ_ENTITYSET Implementation.
  2. Redefine the method by clicking on the icon as shown in the snapshot.1.png
  3. Copy the code from below into the redefined method !

 

Code Snippet

 

data: ls_header type ihttpnvp.

 

ls_header-name = 'Cache-Control'.

ls_header-value = 'no-cache, no-store'.

APPEND ls_header TO ct_headers.

ls_header-name = 'Pragma'.

ls_header-value = 'no-cache'.

APPEND ls_header TO ct_headers.

 

CALL METHOD SUPER->/IWBEP/IF_MGW_CORE_SRV_RUNTIME~READ_ENTITYSET

    EXPORTING

      iv_entity_name                = iv_entity_name

      iv_source_name              = iv_source_name

      is_paging                          = is_paging

      it_order                               = it_order

      it_filter_select_options  = it_filter_select_options

      is_request_details           = is_request_details

    CHANGING

      ct_headers                         = ct_headers

      cr_entityset                       = cr_entityset     .

 

Looks Simple ? Does it solve my problem.......?

 

Wait !! This is a READ ENTITYSET Implementation.

What if the Data that I'm trying to update is expected from an Entity and not an Entity Set ??     .

As every problem has a solution so does this one ! 

 

4. Navigate to your DPC Ext implementation and Locate the CORE_SRV_RUNTIME~READ_ENTITY Implementation.

2.png

 

5. Redefine the method by clicking on the icon in the first snapshot as shown above.

 

6. Next, copy the code from below into the redefined method !

 

Code Snippet

 

data: ls_header type ihttpnvp.

 

ls_header-name = 'Cache-Control'.

ls_header-value = 'no-cache, no-store'.

APPEND ls_header TO ct_headers.

ls_header-name = 'Pragma'.

ls_header-value = 'no-cache'.

APPEND ls_header TO ct_headers.

 

CALL METHOD SUPER->/IWBEP/IF_MGW_CORE_SRV_RUNTIME~READ_ENTITY

   EXPORTING

     iv_entity_name       = iv_entity_name

     iv_source_name     = iv_source_name

     is_request_details  = is_request_details

   CHANGING

     ct_headers            = ct_headers

     cr_entity               = cr_entity.


Hmmm.....What If I'm calling a Function Import Service to update the Data ? Does the above Read Entity/Read Entity Set implementation takes care of the behaviour as well ?

Not Really. We need to implement something more now !

 

7. Navigate to your DPC Ext implementation and Locate the CORE_SRV_RUNTIME~EXEC_SERVICE_OPERATION Implementation.

3.png

 

8. Redefine the method by clicking on the icon in the first snapshot as shown above..

 

9. Copy the code from below into the redefined method !

 

Code Snippet

 

data: ls_header type ihttpnvp.

 

ls_header-name = 'Cache-Control'.

ls_header-value = 'no-cache, no-store'.

APPEND ls_header TO ct_headers.

ls_header-name = 'Pragma'.

ls_header-value = 'no-cache'.

APPEND ls_header TO ct_headers.

 

CALL METHOD SUPER->/IWBEP/IF_MGW_CORE_SRV_RUNTIME~EXEC_SERVICE_OPERATION

   EXPORTING

     iv_action_name     = iv_action_name

     iv_return_type     = iv_return_type

     iv_multiplicity    = iv_multiplicity

     is_request_details = is_request_details

   CHANGING

     ct_headers         = ct_headers

     cr_data            = cr_data.

 

10. Lastly, Remember to activate all the implementations.

 

That's it. That's all you need to implement.

You can access your UI5 OData application on Internet Explorer without pondering over - Why the Data was not getting updated ? !!!

 

Thank you for spending time on this space. Glad if it helped you !!

Upcoming Webinar: Integration Gateway in SAP Mobile Platform 3.0

$
0
0

This session will introduce you to Integration Gateway and the unique value it adds to SAP Mobile Platform 3.0.

 

Integration Gateway is a reusable technology component that brings SAP one step closer to realizing its vision of delivering, a REST based, harmonized integration layer amongst all the solutions in SAP portfolio and beyond. To achieve that, Integration Gateway implements a runtime that supports various protocols and standards such as HTTP, ODC, SOAP, JPA and JDBC to access data. Furthermore, it comes with design-time tools that allow modelling and provisioning of new RESTful (OData) web services based on the data sources supported by the runtime. As a result, Integration Gateway complements SAP Gateway by provisioning (RESTful) OData services that expose data not only from any SAP system, but also non-SAP. Best of all, as a reusable component, Integration Gateway capabilities will be available across many SAP solutions consistently.

 

Date/Time: June 18, 2014, 4:00pm-5:00pm (CEST)

 

Please join us by clicking the registration link: Integration Gateway in SAP Mobile Platform 3.0 - Adobe Connect

 

(Note: The registration will be closed midnight, June 17, 2014 and it is mandatory for the conference call details)

 

Please contactSAP Virtual Event Servicesif you have registration problems.

 

Cancellation Rules: 

Upcoming SAP CodeJam events around SAP Gateway in June in Germany and Switzerland

$
0
0

29.05. changed a typo since the links to both sessions were mixed up.

 

---------

 

After my last SAP CodeJam event around SAP Gateway and SAPUI5 in Antwerpen beginning of this year it's time to continue with additional SAP CodeJam sessions.


In June there will be two additional SAP CodeJam events around SAP Gateway.

 

The events will take place June 18, 2014 in in Bern (Switzerland) and June 25, 2014 in Bielefeld (Germany).

 

While the event in Bielefeld will be hosted by our partner Lynx-Consulting GmbH the event in Bern will be hosted by our partner NOVO Business Consultants AG.

 

In Bielefeld we will also cover the the development of SAP UI5 applications whereas the focus in Bern be solely on OData Service development.


So I am looking forward to see you there!

 

Best Regards,

André

Open Data Protocol

$
0
0

Open Data Protocol

Open Data Protocol (OData) is a data access protocol initially defined by Microsoft. Versions 1.0, 2.0, and 3.0 are released under the Microsoft Open Specification Promise. Version 4.0 is being standardized at OASIS,[1] and was released in March 2014.[2]

The protocol was designed to provide standard CRUD access to a data source via a website. It is similar to JDBC and ODBC although OData is not limited to SQL databases.

 

Architecture

OData is built on the AtomPub protocol and JSON where the Atom structure is the envelope that contains the data returned from each OData request. An OData request uses theREST model for all requests. Each REST command is a POST, GET, PUT, PATCH, or DELETE http request (mapping to CRUD) where the specifics of the command are in the url.

  • GET: Get a collection of entities (as a feed document) or a single entity(as an entry document).
  • POST: Create a new entity from an entry document.
  • PUT: Update an existing entity with an entry document.
  • PATCH: Update an existing entity with a partial entry document.
  • DELETE: Remove an entity.

Any platform that provides support for HTTP and XML is enough to form HTTP requests to interact with AtomPub. The OData specification defines how AtomPub is used to standardize a typed, resource-oriented CRUD interface for manipulating data sources.

 

Typical Workflow When Creating a New User Interface:-

For all browser based application data has to invoke from secure

diag.png


 

 

 

Service Builder – Data Model:-

Create / Model OData  

Artifacts --

  • Entity Types 
  • Entity Sets     
  • Complex Types
  • Associations
  • Association Sets
  • Function Imports    

1.png    

Can make association on principle to dependent entity with the key field (ex : cardinality 0 :M  maintain )

5.png                            

-

Generation of runtime objects :-

After generation of odata artifacts it will create 4 class (1 model provider class and 2 data provider class) and 2 service (technical model and service name) .

 

 

3.png2.png

 

 

Service implementation – CRUD methods:-

Direct navigation into the CRUD –

Methods--

  • Create
  • Read and Query
  • Update
  • Delete

On service implementation Node you can implement your business logic .  

 

6.png

 

 

Service Builder – runtime artifacts:-

ABAP classes for

  • Model definition
  • Service implementation

Service registration in the backend

Service registration in the backend. You need to maintain system alias In transaction SPRO open theSAP Reference IMG and navigate to SAP NetWeaverGateway Service Enablement  -Backend OData Channel -Service Development for Backend OData Channel-Maintain Modelsand Maintain Services.

4.png

 

/iwfnd/maint_service :-


Can call your service directly on browser and also on gateway client

7.png

 

Service document in the browser and entity types in

SEGW

There are 5 method you can use as per your business logic and execute .

As you see in below result association on ID . for more information on Odata links  

you can open your service on browser

http://<host>:<port>/sap/opu/odata/sap/<Service Name >

8.png

 

 

 

Summary - Transactions you should know as a developer:-


Gateway Node Activation

SICF

Includes various functions for monitoring, analysis, and troubleshooting in the ICF environment. You can also make use of the central Application Server analysis functions to identify issues such as performance problems in ICF applications.

Gateway Client

/IWFND/GW_CLIENT

SAP NetWeaver Gateway is a powerful tool that enhances the existing Error Log. Also allows you to simulate service execution. (Similar to tools like RESTClient for Firefox)

Error Log

/IWFND/ERROR_LOG

The Error Log for SAP NetWeaver Gateway hub systems is a helpful addition to the existing Application Log Viewer and provides detailed context information about errors that have occurred at runtime.

Gateway Service Builder

SEGW

A completely new design-time transaction, which provides developers with an easy-to-use set of tools for creating services. It has been conceived for the code-based OData Channel and supports developers throughout the entire development life cycle of a service.

Register/Test Backend System

SM59

Your backend system has to be registered as an SAP system alias in the SAP NetWeaver Gateway Implementation Guide (IMG) on your SAP NetWeaver Gateway system. In addition, an RFC destination has to be defined in transaction SM59.

 

Gateway Service Builder - development flow in detail

 

this image reference : CD204 presentation Teched @ 2012

 

15.png


Viewing all 253 articles
Browse latest View live


Latest Images