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

SAP Certified - Google Sheets with SAP - CloudShuttle

$
0
0

It's been an incredible last few months as we worked through certifying our first product both with Google, and with SAP, just in time for D.Code! The product is now officially out on the SAP Store, and Google Marketplace.

 

You can find it here:

 

Screen Shot 2014-09-15 at 11.58.17 AM.png

With this tool, you can easily read and maintain any data in SAP from Google Sheets.

 

A wizard to get started (connect to Netweaver Gateway):

screenshot 1 - better.png

 

Select Fields or add Filters (Business Partners):

screenshot 2 - better.png

Use Sheets to share, collaborate, or work on any spreadsheet function you like (Material Master for example):

screenshot 3 - better.png

 

If you would like to learn more, please visit the official page: Cloud Shuttle - Mindset

 

Enjoy, and looking forward to seeing everyone at D.Code!


SAP Gateway 2.0 SP09 features now available with SAP NetWeaver 7.40 SP08

$
0
0

NW 7.4 SP08 was released on Sep 15th.

 

Now all new features that became recently available with SAP Gateway 2.0 SP9 that have been described in the SCN documents What's new in SAP Gateway 2.0 SP9?and Details about some new features in SAP Gateway 2.0 SP09 are now also available in the software component SAP_GWFND in SP08 of NW 7.4.

 

In SAP Note 1942072 - SAP NetWeaver Gateway 2.0 Support Package Stack Definitionit is described which SP level on 7.40 is equivalent to which SP level of SAP NetWeaver Gateway 2.0 running on a release 7.31 and earlier.

 

Please find here the release notes: http://help.sap.com/nw74.

 

With NW 7.4 SP10 we are now developing SAP Gateway on 7.40. As a result new features for SAP Gateway will become available with every new SP in SAP NW 7.4. A downport to SAP Gateway 2.0 is planned to be performed every two 7.4 SP's.

 

Best Regards,

André

Make CORS work with Gateway and Chrome for local development

$
0
0

Or as the subtitle could also read: Overcoming "Access-Control-Allow-Origin"- errors


Setup in this example is:

  • development machine with local (web) server running a WebApp from http://localhost:12345
  • Gateway server accessible under a different domain than the local development machine, such as http://example.gateway.com:8000
  • need to consume services onGateway server, originating from local machine => Cross-Domain Request!

There's a lot written out there why Cross-Domain read requests (not write requests!) aren't a good idea. They generally open up data transfer possibilities between domains. Which is something you don't necessarily want - for production environments, that is. What you should also never cater to - use a proxy-based approach to consolidate data read access under one domain, either software-based or with middleware.

 

But what about development?

There are legitimate reasons to read data across domains in development scenarios. Not the least is if you want to work with features offered by SAP Gateway - accessing SAP Backend logic that is exposed via OData Services. Which means issuing cross-domain REST requests from your development machine to a Gateway instance. If you don't have Gateway running on your development machine. Which is unlikely. So here we are...

 

The good and the caveat - SOP

First of all, in the Web's overall architecture, there's SOP or Same-Origin-Policy:

[It] restricts how a document or script 
loaded from one origin can interact 
with a resource from another origin.

Origin here means the combination of protocol (e.g. http), FQDN (e.g. my.domain.com) and port (e.g. 80). So https://www.js-soft.com:4711 is considered an origin - so would http://localhost:12345.

And "can interact" in the quote above should be read as "scripts running from one origin are generally forbidden to interact with scripts from another origin". (Does that mean you can't include content from different sites? No! Read on...)

 

The client side

Stir in some OData- and Gateway-spice and it adds up to the following:

The user agent (e.g. Firefox) is rendering the WebApp from origin1, let's say running on your development machine at http://localhost:12345/.

Now, if the WebApp is trying to retrieve JSON or XML via OData from http://example.gateway.com:8000/sap/opu/odata/sap/ZService/Entity(1), the user agent will send an "XMLHttpRequest cannot load"-error and block the request:


XMLHttpRequest cannot load http://example.gateway.com:8000/sap/opu/odata/sap/ZService/Entity(1).
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://localhost:12345/' is therefore not allowed access.

 

This is due to SOP being implemented in all major user agents: the scripts in the WebApp are forbidden to consume resources from origins other than (in our example) http://localhost:12345/. Retrieving OData from the same origin such as http://localhost:12345/the/odata/endpoint would be allowed, retrieving http://example.gateway.com:8000/sap/opu/odata/sap/ZService/Entity(1) is not.

 

Note that we're talking run-time and client-side here. SOP doesn't apply to including JavaScript-files per se, it applies to the run-time interpretation of the script itself. So if you include JS-files via the <script>-tag, (e.g.<script src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js">), the JS-file will be downloaded from the remote address first. Then it will run from your origin, being interpreted by a user agent - that's the moment that SOP restrictions will apply, not earlier.

 

Disclaimer: SOP is generally a Good Thing(tm). In prevents scripts from origin A to read data from origin B and transfer it back to A.

Which is exactly what you'd like to do in development

 

Resolution: start-flag for Chrome

Google Chrome offers a way to turn off SOP.

If you start the binary with the switch --disable-web-security, SOP gets disabled, allowing client-side cross-domain requests.

E.g. on OS X:

    /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --disable-web-security

On Windows:

    "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" --disable-web-security

 

We're half-way there - cross-domain requests are allowed on the client-side now.

 

The server side

Even though the client now allows requests across domain boundaries, the server still needs to grant access to those requests.

A standard way of doing this is utilizing CORS or Cross-Origin Resource Sharing on the server-side.

In essence, this means sending a an "Access-Control-Allow-Origin" header back to the client, authorizing the client's domain - or granting general access with '*'.

 

Note: '*'-access is exactly what all the Northwind OData Test Services do. And what explains their popularity in example code.

 

Resolution: CORS with Gateway

Per default, Gateway send similar headers such as these:

Content-Encoding:"gzip"

Content-Length:"43233"

Content-Type:"text/html; charset=utf-8"

Server:"SAP NetWeaver Application Server / ABAP 731"

dataserviceversion:"2.0"

sap-metadata-last-modified:"Tue, 08 Jul 2014 08:55:38 GMT"

 

In order to send an additional, custom header from a Gateway-service, use set_header from Interface /iwbep/if_mgw_conv_srv_runtime.

It takes a structure as argument, consisting of a key-value pair.

data:        ls            type ihttpnvp.
ls-name = 'Access-Control-Allow-Origin'.
ls-value = '*'.
/iwbep/if_mgw_conv_srv_runtime~set_header( is_header = ls ).

This will result in the desired CORS "Access-Control-Allow-Origin" header, granting all clients ("*") read access:

access-control-allow-origin:"*"

 

Conclusion

Bringing all the above together means that by

  • using a switch to Google Chrome, you can get around SOP on the client side
  • sending the 'Access-Control-Allow-Origin' header from the Gateway-service allows CORS on the server side

 

And there you are, hopefully hacking away happily on your local machine, calling Gateway OData back and forth

For development purposes only - don't unhinge these web security fundamentals just to make a quick transition into production scenarios, please!

 

tl;dr: Chrome --disable-web-security disables SOP, Gateway /iwbep/if_mgw_conv_srv_runtime~set_header allows CORS => developer happy

Let's code association/navigation and data provider expand in OData service!

$
0
0

 

Introduction

 

In my earlier blog Let’s code CRUDQ and Function Import operations in OData service! we understood the basic operation performed in OData service.


In this blog I will explain creation of simple SAP Gateway OData service having association and navigation between entities. Also we will see how to implement it through code based approach and finally conclude with implantation of GET_EXPANDED_ENTITYSET and GET_EXPANDED_ENTITY

invoked by $expand.

 

Note - Steps mentioned in this blog are performed in SAP Gateway System SP08 (Embedded Architecture)

 

Let’s see what is meant by association and navigation property.

 

Associationsdefine the relationship between two or more Entity Types (for example, Employee WorksFor Department). Instances of associations are grouped inAssociation Sets.

Navigation Propertiesare special properties on Entity Types which are bound to a specific association and can be used to refer to associations of an entity.

Finally, all instance containers (Entity Sets and Association Sets) are grouped in anEntity Container.

 

Reference - Overview | Open Data Protocol

 

Also let's understand the difference between association/navigation and $expand. In short, it is as below,

 

Association/NavigationGive me associated (dependent) entity/entities using Navigation propertyhttp://services.odata.org/OData/OData.svc/Categories(1)/Products?$format=json
$expand

Give me associated (dependent) entity/entities + Principal entity/entities

using Navigation property

http://services.odata.org/OData/OData.svc/Categories(1)?$expand=Products&$format=json

 

you can also refer this nice blog Implementing  Expand Entity/Entity Set by Srikanth Gajula

 

Scenario

 

We will read Sales order, items and product data from Enterprise Procurement Model (EPM). This is the pictorial representation of sales order, items and product with their association.

 

dpe.jpg

We will have 3 entities as displayed in below EDM diagram.

dpe1.jpg

SalesOrder will be associated with SalesOrderItem and SalesOrderItem with Product.

 

Principle EntityDependent EntityNavigation PropertyCardinality
SalesOrderSalesOrderItemOrderToItems1:N
SalesOrderItemProductItemToProduct1:1

 

We will use below BAPIs to get the Sales Order, Items and Product data in DPC_EXT class methods.

  • BAPI_EPM_SO_GET_LIST
  • BAPI_EPM_SO_GET_DETAIL
  • BAPI_EPM_PRODUCT_GET_DETAIL

 

We will code for association/navigation and data provider expand scenario and will also understand the framework expand.

 

Before that just look at difference between Data provider expand and framework expand

 

Framework Expand Data Provider Expand
Formerly called as generic expand Formerly called as basic expand
Requires no implementation effortRequires implementation effort
As this is handled by framework, same logic may be called multiple times in loop resulting in poor performance In some cases, this provides better performance depending on how the code is implemented

 

Reference - Expand in Framework and Data Provider - SAP NetWeaver Gateway - SAP Library

 

Procedure


Create entity SalesOrder by importing DDIC structure as shown below. Please note that Entity set will be created by default if the check box “Create Default Entity Set” is checked.

 

dpe2.jpg

Repeat the process for entities SalesOrderItem and Product. End result will be as displayed below.

dpe3.jpg

Now let’s create association, navigation etc. By using Create Association wizard, it is just 3 steps as displayed below. This will create Navigation property, Association set etc.

 

Create association between entities SalesOrder and SalesOrderItem with navigation property as OrderToItems.

dpe4.jpg

On similar lines, create association between entities SalesOrderItem and Product with navigation property as ItemToProduct.

dpe5.jpg

Please note that we do not have referential constraints created between SalesOrderItem and Product.

 

The final OData modeling will look like as below,

dpe6.jpg

 

Coding

 

In this section, we will redefine methods in DPC_EXT class. Please note that code provided in this blog is in simplest form. You may need to consider proper error handling and other best practices while writing the code.

 

Association/Navigation

 

First we will implement logic in method SALESORDERSET_GET_ENTITYSET by redefining it.

 

We will use below execution URI in Gateway Client (Transaction /IWFND/GW_CLIENT) to check the response payload.

 

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet

METHOD salesorderset_get_entityset.

 

  DATA: lt_salesorder TYPETABLEOF bapi_epm_so_header,

         ls_salesorder LIKELINEOF lt_salesorder,

         ls_entity   LIKELINEOF et_entityset,

         l_max_rows TYPE bapi_epm_max_rows.

 

  l_max_rows-bapimaxrow = '10'.

 

  CALLFUNCTION'BAPI_EPM_SO_GET_LIST'

    EXPORTING

      max_rows    = l_max_rows

    TABLES

      soheaderdata = lt_salesorder.

 

*Fill ET_ENTITYSET

  LOOPAT lt_salesorder INTO  ls_salesorder .

    MOVE-CORRESPONDING ls_salesorder TO ls_entity.

    APPEND ls_entity TO et_entityset.

  ENDLOOP.

ENDMETHOD.

 

Redefine method SALESORDERSET_GET_ENTITY as below and then execute with below URI

 

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000009')

METHOD salesorderset_get_entity.

 

  DATA: ls_salesorder TYPE bapi_epm_so_header,

        ls_key_tab    TYPE /iwbep/s_mgw_name_value_pair,

        lv_soid       TYPE bapi_epm_so_id.

 

*Get the key property values

  READTABLE it_key_tab WITHKEY name = 'SoId'INTO ls_key_tab.

 

  lv_soid = ls_key_tab-value.

 

  CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

    EXPORTING

      input = lv_soid

    IMPORTING

      output = lv_soid.

 

  CALLFUNCTION'BAPI_EPM_SO_GET_DETAIL'

    EXPORTING

      so_id     = lv_soid

    IMPORTING

      headerdata = ls_salesorder.

 

*Fill ER_ENTITY

  MOVE-CORRESPONDING ls_salesorder TO er_entity.

 

ENDMETHOD.

 

Redefine method SALESORDERITEMSE_GET_ENTITYSET as below with URI

 

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000008')/OrderToItems

METHOD salesorderitemse_get_entityset.

  DATA: ls_salesorder TYPE bapi_epm_so_header,

        lt_itemdata   TYPETABLEOF bapi_epm_so_item,

        ls_itemdata   TYPE  bapi_epm_so_item,

        ls_entity     LIKELINEOF et_entityset.

 

  DATA:  ls_key_tab  TYPE /iwbep/s_mgw_name_value_pair,

          lv_soid    TYPE bapi_epm_so_id.

 

*Get the key property values

  READTABLE it_key_tab WITHKEY name = 'SoId'INTO ls_key_tab.

 

  lv_soid = ls_key_tab-value.

 

  CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

    EXPORTING

      input = lv_soid

    IMPORTING

      output = lv_soid.

 

  CALLFUNCTION'BAPI_EPM_SO_GET_DETAIL'

    EXPORTING

      so_id     = lv_soid

    IMPORTING

      headerdata = ls_salesorder

    TABLES

      itemdata  = lt_itemdata.

 

 

  LOOPAT lt_itemdata INTO ls_itemdata.

    MOVE-CORRESPONDING ls_itemdata TO ls_entity  .

    APPEND ls_entity  TO et_entityset.

  ENDLOOP.

 

ENDMETHOD.

 

Notice that we used navigation property OrderToItems to get the associated entities.

 

Framework expand

 

By executing below URI, it will call framework expand by default.

 

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet?$expand=OrderToItems

 

This calls method SALESORDERSET_GET_ENTITYSET and SALESORDERITEMSE_GET_ENTITYSET in loop.

 

Check the values in header name sapgw-statistics for URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet?$expand=OrderToItems&sap-statistics=true

 

This will give you performance statistics for OData request. For more information, refer Some new features in SAP NW Gateway 2.0 SP08

dpe7.jpg

 

If we execute URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000009')?$expand=OrderToItems

 

It will call method SALESORDERSET_GET_ENTITY and SALESORDERITEMSE_GET_ENTITYSET.

 

For below URI to work

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000000')/OrderToItems(SoId='0500000000',SoItemPos='0000000010')

We need to implement logic with navigation property keys.

 

Alternatively we can read as /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderItemSet(SoId='0500000000',SoItemPos='0000000010')

 

Let’s implement SALESORDERITEMSE_GET_ENTITY so that we can read data for above URI as

METHOD salesorderitemse_get_entity.

  DATA: ls_salesorder TYPE bapi_epm_so_header.

 

  DATA:  ls_key_tab   TYPE /iwbep/s_mgw_name_value_pair,

          lv_soid  TYPE bapi_epm_so_id,

          lv_soitempos TYPE snwd_so_item_pos,

          lt_itemdata TYPETABLEOF bapi_epm_so_item,

         ls_itemdata TYPE  bapi_epm_so_item.

 

*Get the key property values

  READTABLE it_key_tab WITHKEY name = 'SoId'INTO ls_key_tab.

  lv_soid = ls_key_tab-value.

 

  READTABLE it_key_tab WITHKEY name = 'SoItemPos'INTO ls_key_tab.

  lv_soitempos = ls_key_tab-value.

 

  CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

    EXPORTING

      input = lv_soid

    IMPORTING

      output = lv_soid.

 

 

  CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

    EXPORTING

      input = lv_soitempos

    IMPORTING

      output = lv_soitempos.

 

*Get data from BAPI

 

  CALLFUNCTION'BAPI_EPM_SO_GET_DETAIL'

    EXPORTING

      so_id     = lv_soid

    IMPORTING

      headerdata = ls_salesorder

    TABLES

      itemdata  = lt_itemdata.

 

 

  READTABLE  lt_itemdata INTO  ls_itemdata WITHKEY so_id = lv_soid

                                                      so_item_pos = lv_soitempos.

  IF sy-subrc = 0.

    MOVE-CORRESPONDING ls_itemdata TO er_entity.

  ENDIF.

ENDMETHOD.

 

Use of Navigation Path to read navigation keys

 

To read the data for below URI, we need to implement logic as below in method PRODUCTSET_GET_ENTITY

 

Execution URI - /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000001')/OrderToItems(SoId='500000001',SoItemPos='0000000010')/ItemToProduct

METHOD productset_get_entity.

  DATA: ls_salesorder TYPE bapi_epm_so_header.

 

 

  DATA:  ls_key_tab   TYPE /iwbep/s_mgw_name_value_pair,

         lv_soid  TYPE bapi_epm_so_id,

         lv_soitempos TYPE snwd_so_item_pos,

         lt_itemdata TYPETABLEOF bapi_epm_so_item,

         ls_itemdata TYPE  bapi_epm_so_item.

 

  DATA: ls_navigation    TYPE /iwbep/s_mgw_navigation_path,

        lv_property                 TYPE string.

 

  DATA: lv_product_id TYPE bapi_epm_product_id,

        lv_product_header TYPE bapi_epm_product_header.

 

  IF iv_source_name = iv_entity_name.

 

*Get the key property values

    READTABLE it_key_tab WITHKEY name = 'ProductId'INTO ls_key_tab.

 

    IF sy-subrc = 0.

* MOVE-CORRESPONDING ls_itemdata to er_entity.

      lv_product_id = ls_key_tab-value.

 

      CALLFUNCTION'BAPI_EPM_PRODUCT_GET_DETAIL'

        EXPORTING

          product_id = lv_product_id

        IMPORTING

          headerdata = lv_product_header.

 

      MOVE-CORRESPONDING lv_product_header TO er_entity.

 

    ENDIF.

 

  ELSE.

 

    IF it_navigation_path ISNOTINITIAL.

      READTABLE it_navigation_path INTO ls_navigation INDEX1.

      IF sy-subrc EQ0.

        CASE ls_navigation-nav_prop.

          WHEN'OrderToItems'.

            LOOPAT ls_navigation-key_tab INTO ls_key_tab.

              CASE ls_key_tab-name.

                WHEN'SoId'.

                  lv_soid = ls_key_tab-value.

                WHEN'SoItemPos'.

                  lv_soitempos = ls_key_tab-value.

                WHENOTHERS.

 

              ENDCASE.

            ENDLOOP.

        ENDCASE.

      ENDIF.

 

    ENDIF.

 

    CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

      EXPORTING

        input = lv_soid

      IMPORTING

        output = lv_soid.

 

 

    CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

      EXPORTING

        input = lv_soitempos

      IMPORTING

        output = lv_soitempos.

 

*Get data from BAPI_EPM_SO_GET_DETAIL

 

    CALLFUNCTION'BAPI_EPM_SO_GET_DETAIL'

      EXPORTING

        so_id     = lv_soid

      IMPORTING

        headerdata = ls_salesorder

      TABLES

        itemdata  = lt_itemdata.

 

 

*Fill ER_ENTITY

    READTABLE  lt_itemdata INTO  ls_itemdata WITHKEY so_id = lv_soid

                                                        so_item_pos = lv_soitempos.

    IF sy-subrc = 0.

      lv_product_id-product_id = ls_itemdata-product_id.

 

      CALLFUNCTION'BAPI_EPM_PRODUCT_GET_DETAIL'

        EXPORTING

          product_id = lv_product_id

        IMPORTING

          headerdata = lv_product_header.

 

      MOVE-CORRESPONDING lv_product_header TO er_entity.

 

    ENDIF.

 

  ENDIF.

ENDMETHOD.

 

Also note that we can read product directly using URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/ProductSet('HT-1030')

 

Now try with this URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000000')?$expand=OrderToItems/ItemToProduct

Product details will not filled as in the navigation keys are empty because we do not have referential constraint.

 

Also try with /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderItemSet(SoId='0500000000',SoItemPos='0000000020')/ItemToProduct and check why it is not working.

 

Additionally you can query as

 

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000000')/$links/OrderToItems

/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000009')/$links/OrderToItems/$count

 

Data Provider Expand

 

In this section, we will see how to implement data provider expand by redefining GET_EXPANDED_ENTITYSET and GET_EXPANDED_ENTITY.

 

Implementing GET_EXPANDED_ENTITYSET

 

Let’s redefine GET_EXPANDED_ENTITYSET. With redefinition (just blank code) execute again the URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet?$expand=OrderToItems

 

You will not get any response as you need to implement the code yourself.

 

One of the important point while implementing logic is Data declaration! Based on level till which you want to expand, you need to define your internal table having nested structure or table type.

 

In below code, we want to expand Sales Order and its items. Hence the expand technical clause will be ORDERTOITEMS.

METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entityset.

 

  DATABEGINOF t_expand_so.

  INCLUDE             TYPE zcl_ztest_dp_expand_mpc_ext=>ts_salesorder.

  DATA: ordertoitems  TYPE zcl_ztest_dp_expand_mpc_ext=>tt_salesorderitem,

       ENDOF t_expand_so.

 

  DATA: lt_expand_so   LIKE  TABLEOF t_expand_so,

        ls_expand_so   LIKE t_expand_so,

        ls_item        TYPE zcl_ztest_dp_expand_mpc_ext=>ts_salesorderitem.

 

 

  DATA: lt_salesorder  TYPETABLEOF bapi_epm_so_header,

        ls_salesorder LIKELINEOF lt_salesorder,

        lt_itemdata   TYPETABLEOF bapi_epm_so_item,

        ls_itemdata   TYPE  bapi_epm_so_item,

        l_max_rows    TYPE bapi_epm_max_rows.

 

  CONSTANTS: lc_expand_tech_clause TYPE string VALUE'ORDERTOITEMS'.

 

 

* Read Sales Order and Item data

  l_max_rows-bapimaxrow = '10'.

  CALLFUNCTION'BAPI_EPM_SO_GET_LIST'

    EXPORTING

      max_rows    = l_max_rows

    TABLES

      soheaderdata = lt_salesorder

      soitemdata  = lt_itemdata.

 

* Data processing logic

  LOOPAT lt_salesorder INTO ls_salesorder.

    MOVE-CORRESPONDING ls_salesorder TO ls_expand_so  .

    LOOPAT lt_itemdata INTO ls_itemdata WHERE so_id = ls_salesorder-so_id .

      MOVE-CORRESPONDING ls_itemdata TO ls_item  .

      APPEND ls_item  TO ls_expand_so-ordertoitems.

      CLEAR: ls_item.

    ENDLOOP.

    APPEND ls_expand_so  TO lt_expand_so.

    CLEAR: ls_expand_so.

  ENDLOOP.

 

* Fill EE_ENTITYSET

  copy_data_to_ref(

    EXPORTING

      is_data = lt_expand_so

    CHANGING

      cr_data = er_entityset ).

 

* Insert Navigation property into ET_EXPANDED_TECH_CLAUSES

  INSERT lc_expand_tech_clause INTOTABLE et_expanded_tech_clauses.

ENDMETHOD.

 

 

Query with URI /sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet?$expand=OrderToItems&sap-statistics=true to check the runtime statistics and compare the values with before implementing data provider expand.

dpe8.jpg

Now we will try to expand to one level more i.e. we will expand sales order, its items and product of each item. In this case the expand technical clause will be ORDERTOITEMS/ITEMTOPRODUCT.

 

Below is the code we need to put to achieve the desired result.

 

METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entityset.

 

 

  DATABEGINOF t_orderitems.

  INCLUDE              TYPE  zcl_ztest_dp_expand_mpc_ext=>ts_salesorderitem.

  DATA: itemtoproduct TYPE  zcl_ztest_dp_expand_mpc_ext=>ts_product,

        ENDOF t_orderitems.

 

  DATABEGINOF t_expand_so.

  INCLUDE             TYPE zcl_ztest_dp_expand_mpc_ext=>ts_salesorder.

  DATA: ordertoitems  LIKETABLEOF t_orderitems,

       ENDOF t_expand_so.

 

  DATA: lt_expand_so   LIKE  TABLEOF t_expand_so,

        ls_expand_so   LIKE t_expand_so,

        ls_item        LIKE t_orderitems.

 

 

  DATA: lt_salesorder  TYPETABLEOF bapi_epm_so_header,

        ls_salesorder LIKELINEOF lt_salesorder,

        lt_itemdata   TYPETABLEOF bapi_epm_so_item,

        ls_itemdata   TYPE  bapi_epm_so_item,

        l_max_rows    TYPE bapi_epm_max_rows.

 

  DATA: lv_product_id TYPE bapi_epm_product_id,

         ls_product_header TYPE bapi_epm_product_header.

 

 

  CONSTANTS: lc_expand_tech_clause  TYPE string VALUE'ORDERTOITEMS/ITEMTOPRODUCT'.

 

 

* Read Sales Order and Item data

  l_max_rows-bapimaxrow = '10'.

  CALLFUNCTION'BAPI_EPM_SO_GET_LIST'

    EXPORTING

      max_rows    = l_max_rows

    TABLES

      soheaderdata = lt_salesorder

      soitemdata  = lt_itemdata.

 

* Data processing logic

  LOOPAT lt_salesorder INTO ls_salesorder.

    MOVE-CORRESPONDING ls_salesorder TO ls_expand_so  .

    LOOPAT lt_itemdata INTO ls_itemdata WHERE so_id = ls_salesorder-so_id .

      MOVE-CORRESPONDING ls_itemdata TO ls_item  .

      lv_product_id = ls_itemdata-product_id.

      CALLFUNCTION'BAPI_EPM_PRODUCT_GET_DETAIL'

        EXPORTING

          product_id = lv_product_id

        IMPORTING

          headerdata = ls_product_header.

      MOVE-CORRESPONDING ls_product_header TO ls_item-itemtoproduct.

      APPEND ls_item  TO ls_expand_so-ordertoitems.

      CLEAR: ls_item.

    ENDLOOP.

    APPEND ls_expand_so  TO lt_expand_so.

    CLEAR: ls_expand_so, lv_product_id.

  ENDLOOP.

 

 

* Fill EE_ENTITYSET

  copy_data_to_ref(

    EXPORTING

      is_data = lt_expand_so

    CHANGING

      cr_data = er_entityset ).

 

* Insert Navigation property into ET_EXPANDED_TECH_CLAUSES

  INSERT lc_expand_tech_clause INTOTABLE et_expanded_tech_clauses.

ENDMETHOD.

 

Please note that we need to insert complete expand clause in et_expanded_tech_clauses

 

Implementing GET_EXPANDED_ENTITY

 

Let’s implement GET_EXPANDED_ENTITY.

 

Below is the query to execute and code to for implementation.


/sap/opu/odata/sap/ZTEST_DP_EXPAND_SRV/SalesOrderSet('500000005')?$expand=OrderToItems/ItemToProduct

 

METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entity.

 

  DATABEGINOF t_orderitems.

  INCLUDE              TYPE  zcl_ztest_dp_expand_mpc_ext=>ts_salesorderitem.

  DATA: itemtoproduct TYPE  zcl_ztest_dp_expand_mpc_ext=>ts_product,

        ENDOF t_orderitems.

 

 

  DATABEGINOF t_expand_so.

  INCLUDE             TYPE zcl_ztest_dp_expand_mpc_ext=>ts_salesorder.

  DATA: ordertoitems  LIKETABLEOF t_orderitems,

       ENDOF t_expand_so.

 

 

  DATA: ls_expand_so   LIKE t_expand_so,

        ls_item LIKE t_orderitems.

 

 

  DATA:  ls_salesorder TYPE bapi_epm_so_header,

         lt_itemdata   TYPETABLEOF bapi_epm_so_item,

         ls_itemdata   TYPE  bapi_epm_so_item.

 

 

  DATA:  ls_key_tab   TYPE /iwbep/s_mgw_name_value_pair,

          lv_soid  TYPE bapi_epm_so_id.

 

  DATA: lv_product_id     TYPE bapi_epm_product_id,

        ls_product_header TYPE bapi_epm_product_header.

 

  CONSTANTS: lc_expand_tech_clause  TYPE string VALUE'ORDERTOITEMS/ITEMTOPRODUCT'.

 

*Get the key property values and Read Sales Order and Item data

  READTABLE it_key_tab WITHKEY name = 'SoId'INTO ls_key_tab.

  lv_soid = ls_key_tab-value.

 

  CALLFUNCTION'CONVERSION_EXIT_ALPHA_INPUT'

    EXPORTING

      input = lv_soid

    IMPORTING

      output = lv_soid.

 

  CALLFUNCTION'BAPI_EPM_SO_GET_DETAIL'

    EXPORTING

      so_id     = lv_soid

    IMPORTING

      headerdata = ls_salesorder

    TABLES

      itemdata  = lt_itemdata.

 

* Data processing logic

  MOVE-CORRESPONDING ls_salesorder TO ls_expand_so  .

  LOOPAT lt_itemdata INTO ls_itemdata WHERE so_id = ls_salesorder-so_id .

    MOVE-CORRESPONDING ls_itemdata TO ls_item  .

    lv_product_id = ls_itemdata-product_id.

    CALLFUNCTION'BAPI_EPM_PRODUCT_GET_DETAIL'

      EXPORTING

        product_id = lv_product_id

      IMPORTING

        headerdata = ls_product_header.

    MOVE-CORRESPONDING ls_product_header TO ls_item-itemtoproduct.

    APPEND ls_item  TO ls_expand_so-ordertoitems.

  ENDLOOP.

 

* Fill ER_ENTITY

  copy_data_to_ref(

    EXPORTING

      is_data = ls_expand_so

    CHANGING

      cr_data = er_entity ).

 

* Insert Navigation property into ET_EXPANDED_TECH_CLAUSES

  INSERT lc_expand_tech_clause INTOTABLE et_expanded_tech_clauses.

ENDMETHOD.

 

Closing Remarks

 

Important points to be considered while coding for association/navigation and data provider $expand,

  • Use of navigation path and navigation key. Entities can be directly accessed or via navigation property. Code for both scenario using navigation path and navigation keys.
  • Data declaration of internal tables in case of data provider expand. Understand the relations between entities. while declaring internal table, use navigation property name to address dependent entity structure. It should be same. Check below data declaration.

  DATABEGINOF t_orderitems.

  INCLUDE              TYPE  zcl_ztest_fw_expand_mpc_ext=>ts_salesorderitem.

  DATA: itemtoproductTYPE  zcl_ztest_fw_expand_mpc_ext=>ts_product,

        ENDOF t_orderitems.

 

 

  DATABEGINOF t_expand.

  INCLUDE             TYPE zcl_ztest_fw_expand_mpc_ext=>ts_salesorder.

  DATA: ordertoitems  LIKETABLEOF t_orderitems,

       ENDOF t_expand.

 

 

  DATA: lt_so   LIKE  TABLEOF t_expand,

        ls_so   LIKE t_expand,

        ls_item LIKE t_orderitems.

  • Parent and its immediate child will be separated using "/" for e.g $expand=OrderToItems/ItemToProduct  if we would have 2nd sibling at order level for e.g Partners of Sales order then we could have navigation property as OrderToPartners with say its child as PartnerToAddress then we need to access it as OrderToPartners/PartnerToAddress. To get the expanded result for both hierarchies, the expand clause will look as $expand=OrderToItems/ItemToProduct,OrderToPartners/PartnerToAddress (separated by ",")
  • Navigation property separated with "/" will be inserted into expanded technical clause. 2nd hierarchy will be appended in expanded technical clause

        In short, for example mentioned in point 3, it would be,

ls_expanded_clause_items = 'ORDERTOITEMS/ITEMTOPRODUCT'.

ls_expanded_clause_partners = 'ORDERTOPARTNERS/PARTNERTOADDRESS'.

APPEND ls_expanded_clause_items TO et_expanded_tech_clauses.

APPEND ls_expanded_clause_partners TO et_expanded_tech_clauses.

        also refer this thread Error with $expand and navigation: Resource not found for the segment 'NavAtp'

  • whether framework expand or data provider expand provides better result will depends on your scenario. Please notice that with $expand, we are making single call to read the parent and child data but at the same time ensure that the data to be retrieved is not too large.

 

I hope you enjoyed reading this blog and now will be able to play with association/navigation and data provider $expand!

 

Please feel free if you have any different thoughts to improve any section of this blog.

 

Happy Learning & Coding

Next Generation ABAP Developer...Miles to reach ?

$
0
0

Hello Everyone,

We all know how the ABAP Framework has been evolved and how it keeps on evolving to meet the next genearion

of Enterprise businesses. You got it ? Yes we are in the SMAC generation(Social Mobile Analytic Cloud).

SAP has been working diligently on this to succeed its customers and partners and as always at its best .

But the real question that strikes us is "Are the developers in "same page" and found to be comfortable with

SAP to learn/develop/architect the new cutting edge technologies that are rolled out in the market?

 

A small example to start with.Before/After evolution of SAP Gateway

 

Scenario:A fiori like project.App runs in desktops/mobile.

Bob:An ABAP developer

Before evolution of SAP Gateway :

His Skill sets required : ABAP-->All lived in SAP GUI sessions at the max. except WDA & BSP.

Resouce required : 1

 

After evolution of SAP Gateway :

Skill sets required : ABAP + OData services + API's (a new member to the family ).

Resouce required : 1 or 2 or 3 ?

 

How should consider the role of the Bob.

A : ABAP developer

B : ABAP + Gateway developer

C : ABAP + Gateway + API developer

 

I am just omitting SAPUI5 in the above context. If that included then we may have a next item called as D.

D:ABAP + Gateway + API's + SAPUI5

 

And this results in below queries to ask.

 

Q1: What should be the role of next generation developers?

Q2 :Do developer feel themselves comfortable with SAP's roadmap ? By comfort we mean the rapid changes that are happening.

Q3: We are aware these technologies keep developers alive to sustain in day-to-day competitive businesses.

      This will make "Businesses made/run simple" but will it make the developer complex to cope up with this?

 

Thoughts i have shared here are purely personal.I may be wrong.

 

Your feedback is appreciated.

 

Cheers

Prabaharan

Outside-in modelling (or "rehab" for RFC addicts)

$
0
0

Fellow Odaters,


I have previously published this blog,  Improved Inside-Out Modelling  mainly to try and point out the problems with mapping complex FM’s outwards and hopefully to discourage this practice. It was well-received and the follow-up is well overdue, sorry!

This current blog is not the blog I intended to write.

What I wanted to do was publish a blog to compare the cases for implementing the same scenario, using inside-out and outside-in modelling paradigms. Why would I wish to do this? Well, the truth is that an overwhelming number of help requests on SCN are related to problems with mapping RFC. This might not have been so bad, except that this is a bad habit to get into and not a good way of developing services.

An even worse trend is that developers are now writing custom function modules to act as service patterns – sorry guys, but you’ve got to stop doing this.

I've already pointed out elsewhere on SCN that SAP do not use RFC mapping generators to build Fiori services (although the lack of standardisation in Fiori services is another space topic for debate). Why don't they do it? Have a guess...

To cut a long story short, I had to abandon the approach on that blog because the average service (with several entities, navigations, filters, etc) is incredibly difficult to build using the RFC generator.

My colleagues and I have written many services - we do use functional modules at times, but we never use the RFC generator.

Here is one line from my original draft that I do wish to retain:

Unless the service is extremely simple, such as one read or query operation on one entity, using the RFC/BOR generator is not advisable.

 

While there are some pros and cons to using function mapping, the cons outweigh the pros and overall the tool is just there to assist developers and does nothing towards producing an OData compliant model. This is especially true when you consider the new functionality available with OData 4.0.

 

 

Pros

  • Parameter names and type are extracted into model.
  • Bound to Dictionary. Useful for documentation and automated data conversion.

 

 

Cons

  • Extracted names often need editing for OData conformity.
  • Bound to Dictionary, backend exposure.
  • One function rarely performs all CRUDQ operations...
  • …and separate functions needed to cover CRUDQ may not use the same data typing for the entity sources.

 

Furthermore, the RFC generator does nothing that you cannot do by writing ABAP in the first place. I am not against using tools if they are useful; prior to the release of Service Builder all data and model providers had to be written from scratch, with the model provider code being especially long-winded. Service builder pretty much removed the need to do any work within the MPC, the extensions only need to be used for features that service builder does not support.

With the DPC, the generated artifacts are built on top of a solid class foundation which does most of the heavy lifting, all you need to do is provide some code in the right places.

Which leads us to "Code-based implementation". I don't like this description, because it's misleading - implementations coming out of the RFC generator are also code-based!

I think I'm going to start calling them "Tailored implementations" instead. In fact the tailoring aspect is a good analogy.

Most FM's are too big/small for the client body or may not even be suitable for the intended body part (underpants for a hat?). If the client is particular oddly shaped, you may spend weeks looking for a suitable "fit" in a limited wardrobe. In this ill-fitted scenario it's more efficient to go to a tailor and tell them what you want. The main difference here is that you can be the tailor if you can sew a few bits of ABAP together, no high costs and waiting for delivery.

I’ll leave things at that for now. I do intend to follow this up with the practical example in a further blog but I’m really keen to get this topic aired properly. What I am hoping to do later is show a design that is outside-in but uses RFC functions without using the generator tools (to keep the RFC zealots happy; I’d use OO in preference any day).

That day has come: Outside-in modelling - a practical guide (RFC Rehab 1)


Regards

Ron.

Outside-in modelling - a practical guide (RFC Rehab 1)

$
0
0


Following on from this blog,Outside-in modelling (or "rehab" for RFC addicts), which urges you all to keep away from RFC based modelling (or at least be aware of your sins), here is the first part of the promised practical demonstration of the outside-in approach.



The “Customer Industry” scenario and service

 

Within CRM, a customer (represented by "business partner") can have an industry segment assigned. Each partner can have more than one industry assigned. This tends to be mostly relevant for “Organisation” partner types.

 

I wish to create a service whereby I can query, add and delete the industry assignments of the customer.

 

The service only needs query and read operations for the customer entity, which is straightforward if I only require basic properties. It needs to provide a collection of some customers; I don’t want all customers as some of them may not be in the country that I am wishing to analyse. This will require a customer search function that can filter by country.

 

The industry information cannot be reliably modelled in the flat entity representation of the customer.

If 0:1 industries were the norm, the industry information could simply be a property of the customer entity. However, the cardinality is 0:n; the industry needs to be a separate entity that has a relation to the customer, e.g. “/Customers(‘1’)/Industries”.

 

I will also need a feed containing all industry keys that are available for assignment to customers so that I know which keys are valid for POSTing when I add an industry.

 

The landscape involves a BEP-enabled CRM instance with embedded GW components.

 

 

On the outside, looking in...

 

I start by drawing up an abstract data model in the Eclipse OData Modeler. I'm not a CRM functional consultant so I have to do a bit of code diving to find out the pertinent parts. The key thing here to note is, if I had the business knowledge and wasn't a developer, I could do this job without any reference to function modules. The technical details are not important if you know that the backend system can do what you want in some way. Since the partner maintenance tools do exactly this, it's a good bet we can pull it off once it goes to a developer.

 

N.B. during the abstract design, I actually went through two major iterations in a short amount of time. My final service is a lot leaner than the one I started with as a first draft - this step is very important as it can significantly improve the build time!

 

There are three business partner types in CRM. I only want my service to relate to “Organisation” type (B2B), so I call the customer data “Organisation”, which will hopefully clarify that it won’t ever be “Consumer” data (B2C).

 

pic1.png

 

The IndustrySystem entity is not related to the Organisation - this is the master data set of available industries created in CRM. When an Industry entry is added to 'Organisations(x)/Industries', the industry key must be taken from that master data collection. 

 

I now export this model to an OData '.xml' and import it into the Service Builder in the CRM backend.

 

pic2.png

 

 

 

pic3.png

 

 

I tweak some of the settings so that the metadata reports the service usage more accurately - it won't actually affect way the service provides data but I will design my provisioning to match this.

 

pic4.png

 

I generate the service and activate it. Note that the proposed names have been shortened by me – I certainly don’t need two ‘Z’s in each class and service name.

 

pic5.png

 

 

Now I have the service metadata done, within 2 hours (including blog authoring time). After 2 hours of struggling with the RFC importer on my aborted blog, I was nowhere near as far as this.

 


Moving on to the data provisioning, the first thing I need to do is formulate the query - as stated above, this is going to be done "by country".

 

When I started my inside-out design experiment, I picked the function BAPI_BUPA_SEARCH as the template function. It can do what I want – find business partners by country – but trying to formulate a sensible service model by RFC import was a nightmare!

 

I’ll stick with the same function but wrap it in my own code. All I need as an input is a country code, which is supplied as a filter, e.g. Organisations?$filter=Country eq ‘GB’. One behaviour of this function that I don’t want to surface in my service is the fact that the partner type won’t be differentiated. It would return all “organisation”, “consumer” and “contact” type partners within the filtered country. I could add another filter criterion but that might not be as understandable as using an entityset name to describe what it contains; thus, I can use a fully descriptive entityset called Organisations and make the logic carry out the necessary alterations to only return organisations.

 

Let’s look at ORGANISATIONS_GET_ENTITYSET in the DPC_EXT and how it is redefined to fit the request.

pic6.png

Plus the subroutines:

pic7.png

This method extracts the expected filter for country. If the request does not contain one, it raises a runtime business exception.

pic8.png

This method is where the so-called “RFC” is buried. I say “so-called” because…

IMPORTANT POINT ONE

…the function used does not have to be RFC enabled.

 

Referring back to the end of ORGANISATIONS_GET_ENTITYSET, the data obtained is looped and converted into entity format...

 

IMPORTANT POINT TWO

The data going out is made to conform to the model that has been established without rigid reference to the internal data source. Additionally, not all of the data required by the model was obtained with BAPI_BUPA_SEARCH, the Name value was post-populated by getting it from BUT000. If this had been an RFC inside-out design, there would not have been a Name property at all.

 

IMPORTANT POINT THREE

Extrapolating from point 2, note some things about this service.

  • It does not use any ABAP DDIC structure base.
  • It certainly does not use any RFC interface signatures.
  • Despite the lack of “SAP integration”, we have a model and a service that works.


The reason it works? It’s an OData model and a true OData model should be agnostic of its data provision details. As long as it obtains data that can be mapped to Edm types, it’s happy.

 

IMPORTANT POINT FOUR

OData is not exclusive to SAP. It’s an open protocol so it does not make sense to tightly couple any of it to SAP technology. Creating models from RFC imports is very wrong if only for this fundamental reason.

 

At the risk of repeating myself, I tried to do all of the above with RFC importing and it was (a) not a nice experience and (b) a failure. Considering that this is only the upper level of the service, it would have been foolhardy to continue in that direction when I know it can be done another way.

I’m still convinced that the final model would not have been possible via RFC wizard without a lot of additional code effort, which we can do anyway without the obfuscation that the wizard puts in our way!  

If anyone is not convinced and wishes to produce the inside-out equivalent of the above and can honestly state they found it quick and simple, please let us know. I’ll be expecting you to do the same for part two ;).

This concludes part one, in part two I’ll move onto the navigation to industry, which is also based on FM data provision.

Congratulations, you have completed step one of RFC Rehab.

 

Regards

Ron.

Another TechEd season is upon us

$
0
0

As the last quarter of 2014 starts in full swing, we are ready for another exciting opportunity to meet you in person. This years' event is called SAP TechEd && d-code Las Vegas. If you haven't done so yet, hurry up and register to take your part in one of the most attended SAP event of the year. As always, TechEd will feature inspiring keynotes from SAP executives, and a total of 1200+ sessions, including 200+ hands-on, 500+ lecture, 80+ product roadmap presentations and others. Last but not least, you will also have the opportunity to meet and network with most active experts in SAP ecosystem.

 

In SAP Gateway, we will be delivering a number of sessions that are focused on SAP Gateway, SAP API Management and Integration Gateway. You can find a nice summary of all our sessions in my colleague Ning-Jing Gao's recent blog.

 

This year, I will be delivering the following sessions:

 

SessionSession TypeTime
DEV360 - Advanced OData Service Development with SAP Gateway2hr - Hands-on

Tue - 2pm-4pm

Thu - 10:30am-12:30pm

INT262 - OData in SAP HANA Cloud Integration2hr - Hands-on

Wed - 10:30am-12:30pm

Thu - 8am-10am

INT103 - OData in SAP Process Orchestration1hr - Lecture

Tue - 5:45pm-6:45pm

Thu - 4:30pm-5:30pm

EXP17596 - Integration Gateway in SAP Mobile Platform 3.0 - Q&A

Networking Session

(Lounge 9)

Tue - 11:30am-12:00 pm

Wed - 10:00am-10:30 am

 

Furthermore, if you would like to meet me in person, please go to Demo Pod 16 - SAP Integration Solutions and API Management where I will be most of my remaining time.

 

Looking forward to seeing you at TechEd && d-code Las Vegas.

 

Best,

Mustafa.


InES Development Day 2014 "Enterprise User Productivity"

$
0
0

Back to university ...

 

On September the 26th the InES Development Day 2014 "Enterprise User Productivity" took place.

 

The event was organized by the Institute for Enterprise Systems (InES) which is a central institution within the University of Mannheim.

 

The main purpose of InES is to actively enhance the valuable exchange between science and practice in the field of enterprise systems.

 

As part of this activities some students of InES have even developed some Gateway training materials which can be found here. I myself found it very impressive what the students achieved and delivered. You can have a look at those materials here: http://ines.uni-mannheim.de/en/transfer/training.html

Auditorium small.jpg

 

Together with our partner Microsoft we supported this event in order to show the capabilities of developing OData services on top of SAP Gateway and consumer applications based on Microsoft technology end-2-end.


The day started with an introduction by Prof. Mädche the managing director of InES.

 

Holger.jpg

 

The participants then got an introduction into SAP Gateway for Microsoft by Holger Bruchelt, followed by an overview of Microsoft Azure & Office 365 by Jürgen Grebe from Microsoft.

 

If soon became clear to the participants that there are numerous opportunities for developers to leverage Microsoft technologies as consumers for OData services based on SAP Gateway.

 

Finally Mr. Hadasch introduced the business scenario that should be tackeld by the participants in the following 3 weeks.

 

There are also prices that can be won by the participating teams based on the judgement of a jury that will have a look at the prototypes provided that these prototypes show a certain level of maturity.

 

Microsoft was so kind to sponsor two Nokia Windows Phones for this purpose.

 

Now it was time for lunch and first disucssions amongst the participants and the speakers.

Lunch.jpg

Discussions.jpg

 

All in all it was a great event and I am looking forward to see the results of the applications that will be built by the different teams.

 

Best Regards,

Andre

Release Information & Constraint Notes for Gateway Developer Tools

$
0
0

We deliver a number of developer tools and accelerators catering to SAP Gateway product family. Some of these tools, particularly the ones which are Eclipse based, can be downloaded and used by anonymous users via SAP Development Tools for Eclipse update site.

 

So far so good!

 

Now over a period of time we update the software and come up with new service packs containing enhancements, new features, bug-fixes etc. This information is communicated through version specific Release Information Note, Constraint Notes etc. and published via SAP Note mechanism.

 

There is a wrinkle though - To access SAP Note one needs a "Service User" account. For an SAP customer this is not a big deal but we are also talking about anonymous users who may not have this S-User account.

 

Sure, the anonymous users can get the latest updates via the update site, but they will not necessarily have access to all the release information and constraints which is only available to S-User account holders.

 

So in order to make it transparent to everyone, from now onwards wherever it makes sense we will also publish this information via SCN (more specifically via this particular blog). So you may want to "Follow" me or this blog for regular updates especially if you don't have an S-User account with SAP.

 

We will create individual posts but all the links will be posted in this central place in a reverse chronological sequence. Hope it makes finding relevant information a little bit easier

 


 

Eclipse Tools

(Latest on top)


SAP Mobile Platform Tools : RIN

Constraints for SAP Mobile Platform Tools 1.0

Constraints for SAP Mobile Platform Tools 1.0 Release

$
0
0

Symptom

This note contains known issues and constraints for SAP Mobile Platform Tools 1.0 release

 

Other Terms

Constraints, Notes, Known Issues,SMP, SAP Release Train for Eclipse,Release notes, release information, OData Modeler, SAP Mobile Platform Tools

 

Reason and Prerequisites

Constraints note for SAP Mobile Platform Tools 1.0 release

 

Solution

Constraints

OData Modeler
• Even if the OData file is read-only, the OData Model Editor does not stop the user from making changes to it. Only while attempting to save the file it shows the error in logs and the updates are not saved


API toolkit for SAP Mobile Platform
• Binding is currently not supported for “Function Imports”
• The mapping editor only loads the OData model structure when the mapping is initially created. If the model changes later it does not show the updates in mapping editor. To see the latest OData Model in mapping editor, user needs to explicitly invoke “Generate EDMX” using the context menu on the .odatasrv file
• The destination for SOAP services needs to be configured in the developer tool only. Unlike other data sources it is not currently supported in the Gateway Management cockpit
• In general, all the constraints of platform runtime are by default also inherited by developer tools

HANA Cloud Integration Mapping Editor constraints:

• If a proper element and schema definition is missing in the WSDL, Mapping editor will fail to parse such a WSDL. Currently the following restrictions exist.
• As the message mapping always expect an element definition as per the XML schema standard for display of the structure of source and target message, it is important that the WSDL Messages refer to a global element in the associated schema definition in the WSDL file.
• So a Document/literal-style message that formats its body according to a schema, that is included in the WSDL is preferred.
• WSDL with RPC style Messages, without the associated schema is not be supported.
• Multi-part WSDLs:- When the message definition contains multiple parts, the WSDL may not have  a single global element representing the complete structure of the input/output message expected by the operation. So the Mapping editor will not be able to display a single message structure with a single root element. Only individual elements referred by each part will be available for mapping.


<wsdl:message name="POMessage">
  <wsdl:part name="po" element="tns:PO" />
  <wsdl:part name="invoice" element="tns:Invoice" />
</wsdl:message>


• Message Parts with reference to type rather than element:- Mapping expects a global element to be present in the WSDL, when such an element is missing and the message directly refers to the type, mapping will not be possibe

<wsdl:message name="POMessage">
  <wsdl:part name="po" type="tns:POType" />
</wsdl:message>

• A WSDL with its definition spread across multiple files:- It is possible to have the definition of a Web service spread across multiple files.
• Currently, the Mapping editor expects the completed definition of WSDL to be in a single file. If not, it will fail to resolve the types and will not detect the structures available in other files and included via the ‘import’ or 'include' construct.

SAP Mobile Platform Tools : RIN

$
0
0

Symptom

This SAP Note provides information about the features released for SAP Mobile Platform Tools 1.0

 

Other Terms

Notes, SAP Mobile Platform Tools, API toolkit for SAP Mobile Platform, SAP Release Train for Eclipse, OData Modeler, Release notes, release information

 

Reason and Prerequisites

Maintain information about the features and updates delivered with each SAP Mobile Platform Tools release as mentioned in the https://tools.hana.ondemand.com/#gateway page.

 

Solution

 

We provide information for the latest release for SAP Mobile Platform Tools 1.0

SAP Mobile Platform tools is a collection of Eclipse based tools to help designing and provisioning OData services for SAP Mobile Platform.The OData Modeler is used to design OData models.

Features available in SAP Mobile Platform Tools:


OData Modeler: The OData Modeler provides wizards and a graphical editor that receive user actions and data in order to create OData models. The OData Modeler provides the following features:

 

OData Model Editor for OData Model Creation: The OData Modeler comprises of the OData Model Editor in Eclipse that enables you to start the OData service development phase by creating an OData model using the OData Model Elements available in the palette.

  •       Creating an OData Model: OData Models can be created using the following options:
    • Blank OData Model
    • From an OData service metadata url
    • From an OData service metadata file
    • From an existing OData service using the Service Catalog
    • From an Existing OData Model
  •       Working in the OData Model Editor: OData Model Editor offers the following options:
    • Add a OData model element by dragging and dropping the elements onto the editor
    • Copy and Paste the Elements
    • Use the Show/Hide All Usage option to show and hide the relationship between the elements in the OData Model Editor
    • Layouting option to select and create your own layouts to view the OData model
  • Exporting an OData Model from the OData Model Editor: Use the Export OData Model wizard to export an OData model file, *.odata, from a project in the OData Model Editor, to an XML file. Later, you can use the exported file in another tool, such as, the SAP NetWeaver Gateway Service Builder to quickly implement an OData service from the model.
  • Service Catalog: The Service Catalog feature allows you to view the metadata of an OData service in the SAP NetWeaver Gateway landscape, inside the OData Model Editor. You can browse and discover the OData services that are available in the SAP NetWeaver Gateway system.

More Informationhttps://help.hana.ondemand.com/odata_modeler_documentation/frameset.htm?5ad0d36c78ae4d49b7f7e8d72dbfa046.html

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------


API toolkit for SAP Mobile Platform: The API toolkit for SAP Mobile Platform enables application developers to create OData services from one or more data sources (both SAP and non-SAP). This includes SOAP, JDBC, JPA and SAP NetWeaver based data sources. The resulting OData service runs on an SAP Mobile Platform 3.0 server. The API toolkit for SAP Mobile Platform provides the following features:

Binding Data Sources: The SAP Mobile Platform allows our users to build and deploy applications on all the major mobile device operating systems. To do this, the users need an OData service to build their own applications. The API Toolkit for SAP Mobile Platform provides functions for OData service provisioning. The toolkit provides an environment to connect to different data sources and to create artifacts. Using the API Toolkit for SAP Mobile Platform developers can bind OData models, which were defined with SAP Mobile Platform Tools to additional datasources like SOAP, JPA, JDBC or ODC (from SAP NetWeaver Gateway).

Defining Custom Code: This feature allows you to define custom code for projets created in version SAP Mobile Platform 3.0 SP04 and above. Custom code is defined to support system query options for SOAP Query mapping.

Generating and Deploying Service Implementation Project allows you to generate and deploy the created service implementation project.

Support for SP03 and Lower Projects: Here are the features that support the projects created using the SAP Mobile Platform 3.0 SP03 and lower runtime versions:

  • Defining Custom Logic for SOAP Query Request: You can implement custom logic for projects created in SAP Mobile Platform 3.0 SP03 and lower runtime only. Custom logic is implemented to support system query options for SOAP Query mapping.
  • Changing Target Runtime: If you have created an OData Implementation Project in target runtime SAP Mobile Platform 3.0 SP3 and below, you can migrate your project to SAP Mobile Platform 3.0 SP4.

More Information

https://help.hana.ondemand.com/api_toolkit_for_sap_mobile_platform_documentation/frameset.htm?39b04f061083404b8f8795c4ed930f35.html


 

SAP NetWeaver Application Server ABAP 7.02 SP11 with Gateway SP04 Trial - Ready for SAP Gateway

$
0
0

Last week I blogged about installation of SAP NetWeaver App Server 7.03 SP03 - which can be used (among other things) to develop ABAP objects in Eclipse. Today I took a look at another distribution of SAP NetWeaver which can be used to evaluate another SAP technology – SAP Gateway. By using the Gateway we can expose SAP’s system functionality as REST-based OData (Open Data Protocol) services. So we can share data residing in SAP to external world like other platforms, devices etc to consume it. The Gateway is delivered as add-on to ABAP based NetWeaver system which is available right in this specific distribution. Note that this is on-premise installation which you can put on your machine. Of course there are also cloud based deployments of the Gateway but this is blog is not related to them. Refer to this link to see all the options.

 

Content:

1. Download of NetWeaver ABAP 7.02 SP11 with Gateway 2.0 SP04

2. Installation of the same

3. OData demo application development

 

Regarding HW and SW I used – please refer to my installation of SAP NetWeaver App Server 7.03 SP03.

 


1. Download of NetWeaver ABAP 7.02 SP11 with Gateway 2.0 SP04

To get installation files I had to download it from store.sap.com. I searched for: SAP Gateway. Actually I downloaded the installation files some weeks earlier. Today I could not find it at the store. However I believe files are still somewhere out there. Alternatively you can use SCN space SAP NetWeaver Gateway Developer Center which has a links to the installation media: SAP NetWeaver ABAP Trial with SAP NetWeaver Gateway 2.0 (installer). I’m not going to provide the link in here as it doesn’t work at the moment.

As usual once I found my media on SAP store I clicked on Trial version button. This offered me a registration form that I filled up. After this I received email with link to the installation file. See all the registration process in details at my previous blog. That was the file I downloaded:

ABAP_Trial_7_02_SP11_Win_64_bit_Version_with_Gateway_2_0_SP04.rar


 

2. Installation of NetWeaver ABAP 7.02 SP11 with Gateway 2.0 SP04

After unpacking the file to installation folder it had size of 3.9GB. Right after this I downloaded and installed JAVA (jre-7u67-windows-x64.exe, download it from java.com) as it is prerequisite to run SAP installation. I started the installation as itself by executing sapinst.exe file:

NWG_01.png


I got first screen of installation wizard where I choose that I wish to install: Central System.

NWG_02.png


Of course obligatory log-off and relog-on of my user:

NWG_03.png


I accepted license – notice I needed to scroll to very down to get the radio button:

NWG_04.png


I set master password for all the SAP users that are created during the installation:

NWG_05.png


Then I got obligatory warning about some of installation criteria that were not met on my system. However it is usually the case while installing demo/trial SAP NetWeaver systems that those warnings can be just ignored. Anyway you have a possibility to revise your parameters in order to remove the warnings and re-execute the checks.

NWG_06.png


As next I reviewed all the settings (I just changed SID of the system being installed from default ID NSP to NWG, to reflect that it is SAP gateway system and also to distinguish from earlier installed NSP) and kicked off installation phases:

NWG_07.png


Oooopps while processing phase no 16 I got stuck with following error. I looked that one of DLLs belonging to MaxDB was missing:

NWG_08.png


I located the reported DLL libSQLDBC77.dll and I put it folder where it was into PATH variable: C:\sapdb\NWG\db\pgm

NWG_09.png


I got through this issue and the installation continued for while with next phases.

Next issue happened in phase no 21. It appeared to be quite strange one. I reviewed log (there is a View Log button) and seems it had something to do with not maintained DB type in system default profile. So I entered into file c:\usr\sap\NWG\SYS\profile\DEFAULT.PFL and added following line in here:


dbms_type = ada

NWG_10.png


After that the installation continued and successfully finished:

NWG_11.png


Meanwhile I installed SAP GUI – version witch wasn’t contained in the installation files but I had it from my previous installation. There it was located under folder:  Frontend&tools\SAP_GUI_for_Windows_7.20_Patchlevel_7_SDN_version_20110701_1428.exe


Once I had my GUII entered the system for first time with DDIC user and password as specified in file: README/welcome.html.

NWG_12.png

 

Being logged in the system I set password for user BCUSER in transaction SU01. From now on I used that user to login to the system.

 


3. OData demo application development

Below I created very simple Read (part of CRUD) operation as service in Gateway. As it is really very simple it does nothing else just lists out users that are created in my newly installed Gateway system. Really notice that mu aim was just to try out it is working instead really focus on what The Gateway system can do. Therefore example is very simple.

First I created Gateway Data Model. I did it in TA SE80 -> GW Data Model.

NWG_13.png

 

Here I entered my new Data Model and filled up following pop-up:

NWG_14.png


Followed by next pop-up:

NWG_15.png


Now I entered into part where I introduced my Query operation. In my case query performs call of BAPI called BAPI_USER_GETLIST. I hit Search icon and entered the BAPI:

NWG_16.png


For the BAPI I needed to create mappings. I just highlighted the BAPI on left side and selected “Create Mapping” button:

NWG_17.png


Here I just selected one field that I was interested in: USERNAME.

NWG_18.png


I changed mapping for selected field into key field of structure: S_COR_ID-VALUE.

NWG_19.png


Then I just generated the data model:

NWG_20.png


Next was to create Consumption Model. This is done again in SE80:

NWG_21.png


I entered description as well:

NWG_22.png


Now I added GW Data Model into Consumption one:

NWG_23.png


I searched for my previously created GW Data Model:

NWG_24.png


Once I had it I tried to see metadata of my service:

NWG_25.png


Here it is, URL http://169.254.80.194:8000/sap/opu/sdata/sap/Z_GW_DM01/$metadata is opened in the web browser:

NWG_26.png


In order to really run the service and get the data I changed URL to following one:

http://169.254.80.194:8000/sap/opu/sdata/sap/Z_GW_DM01/z_gw_dm_01Collection?sap-client=001&$format=xml


So I got six entries:

NWG_27.png


In order to validate it I ran separately same BAPI (BAPI_USER_GETLIST) in SAP GUI. I got also six entries:

NWG_28.png


This concludes development of small SAP Gateway service.

In next part of my blog I name few issues I faced while development.


1. First I needed to customize System Alias. This can be done in transaction SPRO -> SAP NetWeaver -> Gateway -> OData Channel -> Configuration -> Connection Settings -> Manage SAP System Alias):

NWG_29.png

 

2. I had also an issue with user BCUSER. The thing was that I could not get activated my Data Model. It was caused by wrong developer key of my user. Correct developer key is 14421119653247674476. I found it by a lot of goggling at forum post. I even created forum post for this issue

 

NWG_30.png

 

3. Also if service name, URl etc is for some reason not generated you got to do it manually. Transaction /IWFND/MAINT_SERVICE must be used in here.


4. It may happen that Gateway in your system is not activated. You have to activate it in customizing under following path: transaction SPRO -> SAP NetWeaver -> Gateway -> OData Channel -> Configuration -> Connection Settings -> Activate of Deactivate SAP Gateway.

 

Where to go next:

SAP Gateway -- knowing all essentials and how to build apps in 5 min

Getting Started with SAP NetWeaver Gateway

Gateway Documentation

Learn Gateway at your own pace

Installing and Configuring SAP NetWeaver Gateway 2.0



PS: This blog is cross published on my personal blog site.

Create Standalone Annotation using SAP Gateway Service Builder

$
0
0

In my previous blog on Annotation, I explained the process to create Annotation from service builder using Vocabulary. But this annotation is very specific to the service and you can not reuse this annotation for other services.

 

Standalone annotation feature of SAP Gateway enables you to create an annotation model that will be independent in nature and can be assigned to any number of relevant OData services. The advantage you are getting out of this feature is following

  • You will be able to create reusable annotation.
  • You can annotate an existing service externally.

 

Service Builder tool will help you create an annotation model and assign a service to it. In principle, it is possible to assign mutiple services to an annotation model but service builder supports only one service assignment to an Annotation Model.

 

This blog will explain how you can create annotation model by referring an existing service and assign this Annotation model to the same referenced service using SAP NetWeaver Gateway Service Builder tool.

 

This feature is available from SAP Gateway IWBEP SP09.

 

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Step-by-Step Procedure

Following are steps which you need to follow

  • Upload Vocabularies into the Vocabulary Repository
  • Create a Project
  • Import a service for reference
  • Import a vocabulary file
  • Create Annotation
  • Generate Runtime Artifact
  • Access Annotation File

Upload Vocabularies into the Vocabulary Repository

Start the Service Builder by using the transaction SEGW.

 

 

To upload a vocabulary file into the Vocabulary Repository in the Service Builder, proceed as follows:

  1. From menu bar choose Extras ->Vocabulary Repository. The central Vocabulary Repository opens and shows a table for displaying the vocabulary ID, version, namespace, and description. Any previously uploaded vocabulary files are displayed here, otherwise the table is empty.UploadVocabulary.png
  2. Change to edit mode and choose Append Row to add a new row to the table.
  3. Enter a unique vocabulary ID for the vocabulary file you want to upload. Version 1 is assigned automatically to the first version of
    the vocabulary file you upload.
  4. Click the Upload icon in the Upload Vocabulary Content column to navigate to the vocabulary file you want to upload. The namespace of the vocabulary file is entered automatically.
  5. Enter a description for the newly uploaded vocabulary file.
  6. Save the changes and choose Enter.

 

Create a Project

  1. Create a New Project by clicking on 4.jpg

 

  2. Select Service with Annotation Model for Referenced Servicein order to create standalone annotation model.

ProjectType.PNG

 

Import a service for reference

 

The Service Reference option provided in the project type "Annotation Model for Referenced Service" helps you to reference a service registered in local BEP registry, so that the data model can be annotated.

 

  1. Right click of Data Model
  2. Select Import->Service Reference

importservice.png

  3.  In first screen of wizard,  enter technical name and version of  the service.

 

wizard.PNG

  4.  On click of 'Next' button, it will show th preview of OData elements this service is having

  5.  Click 'Finish' to import OData elements in Data Model.

 

Note: The OData artifacts imported in the project are non-editable because the project is only intended to create annotations.

 

Import a vocabulary file

  • In the edit mode, right click on the Data Model, choose Import->Vocabularyin the resulting menu.
  • The Vocabulary Repository window appears.
  • Select the required vocabulary(s) and click continue.

importvcabu.PNG

  • In the Tree view a new folder with the name Vocabularies will be created under the Data Model
    and the vocabularies imported into this folder.

Create Annotation

  1. Select OData element which you want to annotate
  2. Enter term value.

 

Annotation.PNG

     3.   Click on 'Save' button

Generate Runtime Artifact

  • Click Generate Generate.PNGbutton.

          It will open a dialog box with prefilled values for Annotation provider class(APC) and Annotation Model. These are editable fields and you can change the name.

AnnotationModel.PNG

  • On click of Ok button, APC classes and Annotation Model will get created that you can see in Runtime Artifacts Folder and finally the referenced service will be assigned to the created Annotation Model .
  • APC Code: You can check annotation related code in method DEFINE_VOCAB_ANNOTATIONS( ) of generated APC.APC_class.PNG
  • Maintain Annotation Model: You can see Assignment of the Referenced Service to Annotation Model using transaction /iwbep/reg_vocan.

Maintain_AnnotationModel.PNG

NOTE: You can reference only one service via Service Builder. However, using the transaction /IWBEP/REG_VOCAN multiple services can be assigned to the annotation model, but this causes an inconsistency as the services referenced via the transaction does not reflect in Service Builder.

 

Access Annotation File

  • Register the referenced service with Gateway Hub(If not registered). You can use Service maintenance feature of service builder for registration.
  • Load Metadata of the service. For this, click Maintainmaintain.PNGthat will take you to 'Active and Maintain Services' view of Gateway Hub where you can load metadata by clicking LoadMetadata.PNG.
  • Finally you can access annotation file through catalog service using below URL. Gateway  ClientGatewayclient.PNGbutton of service builder will take you to Gateway Client tool having request URI populated. Execute this URL to get annotation.


<</sap/opu/odata/IWFND/catalogservice;v=2/Annotations(TechnicalName='ZTEST_STANDALONE_ANNOTATION_ANNO',Version='0001')/$value>>

 

Note: Annotation file contains reference Uri of all the assigned services.

Metadata.PNG

 

1.      Similarly if you want to get the reference Uri of annotation file in metadata of the service, it will only be available if you create the reference in the MPC of the service, e.g.

  lo_reference = vocab_anno_model->create_annotation_reference(
                                iv_annofile_id
= 'ZTEST_STANDALONE_ANNOTATION_ANNO'
                                iv_annofile_version
= '0001').

k
c  Hope this helps you understand and create standalone annotation using service builder. I look forward to your feedback.

Simple Step-by-Step SAP-Gateway Service Guide

$
0
0

Hi All,

 

Finally thought of writing blog  after struggling to create simple o-data service to perform basic operations including media and deep entities.

So I don't want you all to struggle and waste your time...

 

This is for Beginners not for Experts ,

 

Create your simple gateway service, following provided steps in this link.

using table and structure list below with Project Details.


Service is all about Employee Information System.


Transaction  :  SEGW


http://www.bluefinsolutions.com/Blogs/Lindsay-Stanger/March-2014-(1)/Building-your-first-simple-Gateway-service/?feed=RSS-Feed

Or

Technical Details.

 

Tables Used.

  1. Employee Details table[Principle data]Or[Header Information]

EmployeeTable[Header].PNG

 

   2. Employee Contact details(Ph no on working days and on leave)[Line Item]

 

EmployeeContactDetails[Line]Sub.PNG

 

  3.  Employee Photo Details.

EmployeePhoto[Sub].PNG

 

 

Structures Used.

  1. Employee Details.

EmployeeDetailsStructure.PNG

 

2.  Employee Address Info[Include structure in Emp Details table].

EmployeeDetailsAddressInclude.PNG


3.  Employee Contact details(Info like Contact no during working days and on leave).

EmployeeContactDetailsStructure.PNG

  4. Employee Photo details.

EmployeePhotoStructure.PNG

 

 

Project Details.


ProjectStructure.PNG

 

ProjectStucture2.PNG


Once after creating Entity Types, Entity Sets, Associations, Navigation Properties. [Please find links at end of this blog ]

  1. 1. Click on Generate Runtime objects.
  2. 2. Expand Runtime artifacts.
  3. 3. Right click on Class which ends with DPC_EXT.
  4. 4. Redefine the methods which mentioned below.
  5. 5. Paste the code[Put break-point if u want to check behavior of methods called    based on URL].
  6. 6. Expand Service maintenance.
  7. 7. Right click on system in which you created these objects.
  8. 8. Click on  Register and select proper System in RFC System alias.
  9. 9. Right click again on Selected system and click maintain.
  10. 10. Pop up will appear asking for redirection Click Yes.

Redirected.PNG

 

Click on Gateway Client.

GatewayClient.PNG

Click Execute to test.


Status 200 shows service is created correctly.


Paste URL in Requested URI field and Click Execute.


Check respective methods by keeping breakpoints as given below.

 

 

READ.

             

URL :

To get single record.

------------------------------/sap/ZEMPLOYEE_INFO_SRV/EmpDetailsSet(EMP_ID='1')

METHOD empdetailsset_get_entity.
DATA: ls_key_tab TYPE /iwbep/s_mgw_name_value_pair,
ls_emp_tab
TYPE zxx_emp_det.

READ TABLE it_key_tab INTO ls_key_tab WITH KEY name = 'EMP_ID'.
SELECT SINGLE * FROM zxx_emp_det INTO ls_emp_tab WHERE emp_id = ls_key_tab-value.
IF sy-subrc = 0.
MOVE-CORRESPONDING ls_emp_tab TO er_entity.
MOVE-CORRESPONDING ls_emp_tab TO er_entity-details.
ENDIF.
ENDMETHOD.

SUCCESS CODE : 200

URL:

To get all records from table respect to EntitySet.

-------------------------------/sap/ZEMPLOYEE_INFO_SRV/EmpDetailsSet

To get records based on where condition.

------------------------------/sap/ZEMPLOYEE_INFO_SRV/EmpDetailsSet?$filter=EMP_ID eq '1'

We can add more conditions using & Operator in between fields.

METHOD empdetailsset_get_entityset.

DATA: lt_emp_tab    TYPE TABLE OF zxx_emp_det,
ls_emp_tab   
TYPE          zxx_emp_det,
es_entityset 
TYPE          zcl_zemployee_info_mpc=>ts_empdetails.

SELECT * FROM zxx_emp_det INTO TABLE lt_emp_tab WHERE (iv_filter_string).
IF sy-subrc = 0.
LOOP AT lt_emp_tab INTO ls_emp_tab.
MOVE-CORRESPONDING  ls_emp_tab    TO es_entityset.
MOVE-CORRESPONDING  ls_emp_tab    TO es_entityset-details.
APPEND              es_entityset  TO et_entityset.
CLEAR ls_emp_tab.
ENDLOOP.
ENDIF.
ENDMETHOD.

SUCCESS CODE : 200




CREATE


Steps :

  1. 1.Get any record from GET_ENTITY ..
  2. 2.After getting click on Use as request.
  3. 3.Change details what you want to create in left window.
  4. 4.Check POST method of HTTP.
  5. 5.Use URL..

---------------------------/sap/ZEMPLOYEE_INFO_SRV/EmpDetailsSet

method ZEMPDETSTRSET_CREATE_ENTITY.
DATA: ls_emp_details TYPE zxx_emp_det.
"Get the created entity here
io_data_provider
->read_entry_data( IMPORTING es_data = er_entity ).
MOVE-CORRESPONDING er_entity TO ls_emp_details.
MOVE-CORRESPONDING er_entity-details TO ls_emp_details.
INSERT zxx_emp_det FROM ls_emp_details
endmethod.

SUCCESS CODE : 201



 

UPDATE

 

To Update the Record.

Follow same steps as for CREATE_ENTITY.

Just Change URL and Check HTTP  PUT Method.

  1. URL.

---------------------------/sap/ZEMPLOYEE_INFO_SRV/EmpDetailsSet(EMP_ID='1')

But on response   body nothing will be displayed..

For that we need to call get entity internally.

method EMPDETAILSSET_UPDATE_ENTITY.
DATA: ls_emp_details TYPE zxx_emp_det.

"Get the created entity here
io_data_provider
->read_entry_data( IMPORTING es_data = er_entity ).
MOVE-CORRESPONDING er_entity TO ls_emp_details.
MOVE-CORRESPONDING er_entity-details TO ls_emp_details.
MODIFY zxx_emp_det FROM ls_emp_details.

endmethod.

SUCCESS CODE : 204



 

DELETE


To delete record Follow same steps for create.

Check http method DELETE.

URL .

--------------------/sap/ZEMPLOYEE_INFO_SRV/EmpDetailsSet(EMP_ID='1')

method EMPDETAILSSET_DELETE_ENTITY.
DATA: ls_key_tab TYPE /iwbep/s_mgw_name_value_pair,
ls_emp_details
TYPE zxx_emp_det.

READ TABLE it_key_tab INTO ls_key_tab WITH KEY name = 'EMP_ID'.
IF sy-subrc = 0.
ls_emp_details
-emp_id   = ls_key_tab-value.
DELETE zxx_emp_det FROM ls_emp_details.
ENDIF.
endmethod.

SUCCESS CODE : 204

 

 

DEEP READ


To get data of dependent with parent entity[Header with Line Items]

  1. URL.

-----------------------------ZEMPLOYEE_INFO_SRV/EmpDetailsSet(EMP_ID='1')/?$expand=EmpContDetailsNavig

METHOD /iwbep/if_mgw_appl_srv_runtime~get_expanded_entity.
DATA:   ls_key_tab        TYPE /iwbep/s_mgw_name_value_pair,
ls_emp_tab       
TYPE zxx_emp_det,
ls_empadd_tab    
TYPE zot_cont_det,
ls_empadd        
TYPE zot_cont_det.

DATA: ls_expand_tech_clauses LIKE LINE OF et_expanded_tech_clauses.

DATA: BEGIN OF ls_expand.
INCLUDE TYPE zcl_zemployee_info_mpc=>ts_empdetails.
DATA: empcontdetailsnavig TYPE STANDARD TABLE OF zcl_zemployee_info_mpc=>ts_empcontactdetails WITH DEFAULT KEY.
DATA: END OF ls_expand.

READ TABLE it_key_tab INTO ls_key_tab WITH KEY name = 'EMP_ID'.

SELECT SINGLE * FROM zxx_emp_det INTO ls_emp_tab WHERE emp_id = ls_key_tab-value.

SELECT SINGLE * FROM zot_cont_det INTO ls_empadd_tab WHERE emp_id = ls_key_tab-value.

MOVE-CORRESPONDING ls_emp_tab TO ls_expand.
MOVE-CORRESPONDING ls_empadd_tab TO ls_empadd.
APPEND ls_empadd TO ls_expand-empcontdetailsnavig.

"Assign the navigation properties
ls_expand_tech_clauses
= 'empcontdetailsnavig'.
APPEND ls_expand_tech_clauses TO et_expanded_tech_clauses.

copy_data_to_ref
(
EXPORTING
is_data
= ls_expand
CHANGING
cr_data
= er_entity ).

ENDMETHOD.

SUCCESS CODE : 200




DEEP INSERT


To create deep entity.[Parent data with child][Header with Line Items]

Steps :

  1. 1.Read data from GET_EXPANDED_ENTITY
  2. 2.Made HTTP method as POST.
  3. 3.Click User as Request and Edit values You want to Insert.
  4. 4.url

-----------------------ZEMPLOYEE_INFO_SRV/EmpDetailsSet

  1. 5.Execute.

method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_DEEP_ENTITY.

TYPES : ty_t_empadd TYPE STANDARD TABLE OF ZCL_ZEMPLOYEE_INFO_MPC=>TS_EMPCONTACTDETAILS WITH DEFAULT KEY.
TYPES: BEGIN OF ty_expand.
INCLUDE TYPE ZCL_ZEMPLOYEE_INFO_MPC=>TS_EMPDETAILS.
TYPES  :       EmpContDetailsNavig TYPE ty_t_empadd,
END OF ty_expand.
DATA :
*&-------> Local structures.
ls_deep_emp_details
TYPE  ty_expand,
ls_emp_cont_det    
TYPE  ZOT_CONT_DET,
ls_emp_details     
TYPE  zxx_emp_det,
*&-------> Local Itabs.
lt_emp_cont_det    
TYPE TABLE OF ZOT_CONT_DET.

io_data_provider
->read_entry_data( IMPORTING es_data = ls_deep_emp_details ).

copy_data_to_ref
( EXPORTING  is_data = ls_deep_emp_details
CHANGING   cr_data = er_deep_entity ).

MOVE-CORRESPONDING ls_deep_emp_details TO ls_emp_details.
MOVE-CORRESPONDING ls_deep_emp_details-details TO ls_emp_details.

INSERT INTO zxx_emp_det VALUES ls_emp_details.

LOOP AT ls_deep_emp_details-empcontdetailsnavig INTO ls_emp_cont_det.
APPEND ls_emp_cont_det TO lt_emp_cont_det.
ENDLOOP.
MODIFY zot_cont_det FROM TABLE lt_emp_cont_det.

IF sy-subrc EQ 4.
ENDIF.
endmethod.

SUCCESS CODE : 201




CREATE MEDIA


  1. 1.Redefine the DEFINE METHOD OF MPC_EXT CLASS
  2. 2.Paste code.
  3. 3.We need to get key values in SLUG Parameter Of http.
  4. URL.

-------------------------------ZEMP_PRO_SRV/EmpPhotoSet

  1. 4.Click on add file select image.
  2. 5.Check Post method of HTTP.
  3. 5.Execute.

method DEFINE.
super
->DEFINE( ).
DATA:
lo_entity  
type REF TO /IWBEP/IF_MGW_ODATA_ENTITY_TYP,
lo_property
type REF TO /IWBEP/IF_MGW_ODATA_PROPERTY.
lo_entity
= model->GET_ENTITY_TYPE( IV_ENTITY_NAME = 'EmpPhoto' ).

IF lo_entity is BOUND.
lo_property
= lo_entity->GET_PROPERTY( IV_PROPERTY_NAME = 'MIMETYPE' ).
lo_property
->SET_AS_CONTENT_TYPE( ).
ENDIF.
endmethod.

 

method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~CREATE_STREAM.

    DATA: ls_key_tab                   TYPE /iwbep/s_mgw_name_value_pair,
lt_key_tab                  
TYPE /iwbep/t_mgw_name_value_pair,
ls_photo                    
TYPE ZSEMP_PHOTO,
lv_email                    
TYPE char100.

CASE iv_entity_name.
WHEN 'EmpPhoto'.
READ TABLE it_key_tab WITH KEY name = 'EMP_ID' INTO ls_key_tab.

ls_photo
-emp_id = ls_key_tab-value.
ls_photo
-mimetype = is_media_resource-mime_type.
ls_photo
-filename = iv_slug.
ls_photo
-content = is_media_resource-value.
DELETE FROM ZEMP_PHOTOS WHERE EMP_ID = ls_photo-EMP_ID.
INSERT INTO ZEMP_PHOTOS VALUES ls_photo.
empphotoset_get_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
IMPORTING
er_entity         
= ls_photo ).

copy_data_to_ref
( EXPORTING is_data = ls_photo
CHANGING  cr_data = er_entity ).
ENDCASE.
ENDMETHOD.

 

 

READ MEDIA


Steps:

URL:

---------------------/ZEMPLOYEE_INFO_SRV/EmpPhotoSet('1')/$value

  1. 1.Redefine GET_STREAM Method Paste code.
  2. 2.Select GET Method of HTTP.
  3. 3.Execute.

method /IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM.

    DATA: ls_key      TYPE /iwbep/s_mgw_name_value_pair,
lv_email   
TYPE char100,
ls_photo   
TYPE ZEMP_PHOTOS,
ls_lheader 
TYPE ihttpnvp,
ls_stream  
TYPE ty_s_media_resource,
lv_filename
TYPE w3conttype.

CASE iv_entity_name.
WHEN 'EmpPhoto'.

READ TABLE it_key_tab WITH KEY name = 'EMP_ID' INTO ls_key.
lv_email
= ls_key-value.

SELECT SINGLE * FROM ZEMP_PHOTOS INTO CORRESPONDING FIELDS OF ls_photo WHERE EMP_ID = lv_email.
ls_stream
-value = ls_photo-content.
ls_stream
-mime_type = ls_photo-mimetype.

lv_filename
= ls_photo-filename.
*        lv_filename = escape( val = lv_filename
*                              format = cl_abap_format=>e_url ).
*        ls_lheader-name = 'Content-Disposition'.
*        ls_lheader-value = |inline; filename="{ lv_filename }"|.
*        set_header( is_header = ls_lheader ).


ls_stream
-value = ls_photo-content.
ls_stream
-mime_type = lv_filename.

copy_data_to_ref
( EXPORTING is_data = ls_stream
CHANGING  cr_data = er_stream ).

*        copy_data_to_ref( EXPORTING is_data = ls_stream
*                          CHANGING  cr_data = er_stream ).
ENDCASE.

 

 

***** SOME DUMMY REFERENCE CODE FOR SAME METHOD [CAN BE USEFUL]  ****


**TRY.
*CALL METHOD SUPER->/IWBEP/IF_MGW_APPL_SRV_RUNTIME~GET_STREAM
*  EXPORTING
*    IV_ENTITY_NAME          =
*    IV_ENTITY_SET_NAME      =
*    IV_SOURCE_NAME          =
*    IT_KEY_TAB              =
*    IT_NAVIGATION_PATH      =
**    io_tech_request_context =
**  IMPORTING
**    er_stream               =
*    .
** CATCH /iwbep/cx_mgw_busi_exception .
** CATCH /iwbep/cx_mgw_tech_exception .
**ENDTRY.


*DATA: ls_stream    TYPE         ty_s_media_resource
*      ,lo_api    TYPE REF TO  if_mr_api
*      ,lv_entity_name TYPE  /IWBEP/MGW_TECH_NAME
*      ,er_entity type REF TO DATA
*      ,lr_entity TYPE REF TO DATA
*      ,empphotoset_get_entity TYPE ZCL_ZEMP_PRO_MPC=>TS_EMPPHOTO
*      ,ls_content type table of TBL1024 initial size 0
*      ,ls_xstring type xstring
*      ,lt_messg type table of BAPIRET2 initial SIZE 0
*      ,lv_pernr(8) TYPE n
*      ,t_photo type table of TBL1024
*      ,l_photo type XSTRING
*      ,l_line type string
*      ,l_photo1 type string
*      ,ls_ret type BAPIRET2
*      ,ls_photo type ZEMP_PHOTOS
*      ,t_msg type table of BAPIRET2.
*
*lv_entity_name = io_tech_request_context->GET_ENTITY_TYPE_NAME( ).
*
*CASE lv_entity_name.
*
*      WHEN 'ZsempDet'.
*      WHEN 'EmpPhoto'.
*
*     empphotoset_get_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_tech_request_context = io_tech_request_context
*           IMPORTING er_entity          = empphotoset_get_entity
*                                 ).
*
*           IF empphotoset_get_entity IS NOT INITIAL.
**     Send specific entity data to the caller interface
*           copy_data_to_ref(
*                     EXPORTING
*                     is_data = empphotoset_get_entity
*                     CHANGING
*                     cr_data = er_entity
*                          ).
*           ELSE.
**         In case of initial values - unbind the entity reference
*           er_entity = lr_entity.
*           ENDIF.
*
*           lv_pernr = empphotoset_get_entity-emp_id.
*
*           CALL FUNCTION 'PAD_PHOTO_UPDATE_GET_DETAIL'
*           EXPORTING
*                IV_EMPLOYEE_NUMBER         = lv_pernr
*
*           TABLES
*                T_PHOTO_ARCHIVE_OUT        = t_photo
*                T_MESSAGES_OUT             = t_msg
*                .
*
**           LOOP AT t_photo into  ls_photo.
**                l_line = ls_photo-line.
**                concatenate l_photo1 l_line into l_photo1.
**           ENDLOOP.
*
*               ls_stream-value = l_photo = l_photo1.
*               ls_stream-mime_type = 'image/jpeg'.
*
*               copy_data_to_ref( EXPORTING is_data = ls_stream
*                                 CHANGING  cr_data = er_stream ).
*
*      WHEN OTHERS.

*ENDCASE.

endmethod.

 

 

 

Entity Types.

https://help.sap.com/saphelp_nw74/helpdata/en/bb/dc22512c312314e10000000a44176d/content.htm

Entity Sets.

https://help.sap.com/saphelp_nw74/helpdata/en/b6/dc22512c312314e10000000a44176d/content.htm

  1. Associations.

https://help.sap.com/saphelp_nw74/helpdata/en/07/dc22512c312314e10000000a44176d/content.htm

Navigation Properties.

http://help.sap.com/saphelp_nw74/helpdata/en/3f/dd22512c312314e10000000a44176d/content.htm






Thanks,


Arshad Shaikh.


Steps to access the gateway service from one system to another system.

$
0
0

Business Scenario

  • The odata service is created in one system (ex: development system), and this service has to be accessed in other system (EX: sap gateway system)  .
  • When the development system and the gateway service system are different this process is helpful.

 

Step-by-Step Procedure


Configuration on SAP NetWeaver Gateway System

This activity needs to be done in the system where software component IW_FND is installed

This Setting has to be done in the system where you have to access the odata service (in my case gateway system)


1. Manage RFC Destination

Create RFC Connection to the SAP Business Suite backend system.

  • In transactionSPROopen the SAP Reference IMG and navigate to:SAP NetWeaver->Gateway->OData Channel->Configuration ->Connection Settings->SAP NetWeaver Gateway to SAP System->Manage RFC Destinations->and click the Activity icon.

 

2. Manage SAP System Aliases

  • In transactionSPROopen the SAP Reference IMG and navigate to:SAP NetWeaver->Gateway->OData Channel->Configuration ->Connection Settings ->SAP NetWeaver Gateway to SAP System->Manage SAP System Aliases->and click the Activity icon.
  • ChooseNew Entries.
  • Enter the following details for the system alias:

Field

Description

SAP System Alias

Name of the system alias, for exampledev_001

Description

Descriptive text for the system alias.

Local GW

Leave unchecked if the Backend system is not on the same system as the SAP NetWeaver Gateway system.

For Local App

Check if IW_BEP add-on is deployed on the SAP NetWeaver Gateway hub system.

RFC Destination

Specify the RFC destination that you created in the step above.

WS Provider

Leave it blank.

Software Version

ChooseDefault.

  • Save your settings.

system alias.PNG


Creating the service

1. Go to transaction /iwfnd/maint_service

2. Click on add service

3. Enter the system alias, Technical service name and version of a service.

· System alias which was created in spro.

· Technical service name – Enter the gateway service name which is present in other system

( ZLEAVELOGIN_SRV).

· Specify the version (in my case it is 1).

                         

After this you can use the service

SAP Gateway and API Management Footprints at TechEd Berlin and Outlook for the Final Day

$
0
0

If you haven’t seen the TechEd Berlin keynote from Bernd Leukert, definitely check out the replay. 42 minutes into the keynote Bjoern Goerke – EVP of Technology and Innovation demonstrated an insurance claim app creation with exposing OData service from ERP (via Gateway) with our brand new SAP API Management solution on the fly. That was a really impressive app up and running on various mobile devices in just few minutes!

 

Our code review sessionCR704 “SAP Gateway - Tune your OData Services”took placetoday in this small white tent which was called "Code Review Arena". Youfelt a little bit like in a real arena. People really enjoy being inside of this mini arena . The session was conducted by SAP Gateway runtime architect Olaf Tennie and Product Manager Andre Fischer. They showed amongst others the latest improvements inSAP Gateway SP09. You can see how packed and cozy the arena was during this session.

 

codeReviewWP_20141112_018.jpg

CodeReviewWP_20141112_020.jpg

 

Our customer Cornelia Wanders fromAOK Systems presented today “Mobile B2E/B2C Apps Using SAP Mobile Platform and SAP NetWeaver Gateway” which was well received. Her presentation covered the implementation of mobile B2E and B2C applications. Both scenarios cover the OData service development in SAP NetWeaver Gateway as well as the development of mobile applications using the SAP Mobile Platform. She showed cool mobile app for young people to receive benefits from their health insurance based on SAP Gateway and SMP which will be available shortly.

AOKonStage.png

 

 

 

Our famous book“OData and SAP NetWeaver Gateway” is prominently featured and sold on the front row at TechEd Berlin as well.

 

GWBook_WP_20141112_009.jpg

 

Another jump packed session was our 4 hours Hands-on Session INT260 Develop an E2E Integration Scenario with SAP Gateway, SAP HANA, and SAPUI5. In this hands-on session, you could develop an SAP Fiori-style app in an end-to-end scenario. Thomas Meigen (Chief Product Owner), Olaf Tennie and Andre Fischer walked through the development and extension of an SAP Gateway OData service consisting of SAP HANA-based views and other data sources. Participates could generate and extend an SAP Fiori-styled app with SAPUI5 and the new SAP WEB IDE.
AndreHandsOnSession.png
INT260_handsOn_WP_20141112_003.jpg

We have another exciting day ahead of us. It will be the final opportunity to visit our Demo Pod in the Info Zone (P2.5 / IZ5) Integration Solutions and API Management.

 

Stay tuned for the Live Studio on Thu 11 AM German local time about “Digital Acceleration for 100+ Year Old Companies using API-centric architectures”. Our product manager Carsten Boennen will interview Joe Black - SAP Strategic Partner Lead at Apigee.Here is the replay link.

 

Abstract:
The digital economy is often viewed as the habitat of young, digital native companies. How can established companies compete? One hundred years ago, factory electrification and mass production advanced—and challenged—existing businesses. The survivors of that era now find new challenges and opportunities in today’s digital economy.
Join Apigee and SAP in this SAP Studio chat to learn how Fortune 1000 enterprises are recognizing their digital potential and overcoming challenges to increase business agility and innovation with API-centric architectures.

More about the program and detailed information for the final day is in this blogsneak peek. Additional TechEd Berlin pictures are here.

For further information please see our social media channels too:

 

SAP Gateway               SAP.com|SCN|LinkedIn|Youtube|Twitter|Facebook

SAP API ManagementSAP.com|SCN|LinkedIn|Youtube|Twitter|Facebook

Expand Parent Child Entities in a Single Expansion - GET_EXPANDED_ENTITYSET

$
0
0

Working on first gateway project and being asked to expand the parent child entities linked with Navigation Property with a single expansion or RFC call requires quite a bit of self learning. However, when explored the internet, I could not find blogs/links which explained in detail how to use Expansion Method of the Gateway to expand both Parent and Child Entity in a single RFC call, rather than making call first to parent entity and then to the child using $EXPAND parameter in the Odata Service Link.

 

This scenario is more appropriate for Gateway Hub scenario where in GW(GW_CORE, I_BEP and IW_FND) and ECC are separate systems. An RFC call is made from GW to ECC each time data is requested from UI. Therefore, if the user needs to fetch the Parent Child data using $EXPAND, the gateway framework will first call the entity set for the Parent(SOHeaderSet) and then the entity set for Children(SOItemSet). This results in 2 RFC call to fetch the required data.

 

In this blog, we will learn how we can reduce 2 RFC calls to a single RFC call and expand both the Parent and Child Entities in a single Odata Service Call.

 

In order to implement this, we will re define 'GET_EXPANDED_ENTITYSET' Method of the Data Provider Class.

 

In this example, we will use 2 entities Sales Order Header(SOHeader) and Sales Order Item(SOItem). Both are linked to each other with a navigation property SOHeaderToItem.

Entities.PNG

SOHeader.PNG

SOItem.PNG

Association.PNG

Navigation.PNG

 

Redefine GET_EXPANDED_ENTITYSET as explained in the attached snapshot.

GET_EXPANDED_ENTITYSET.PNG

 

The catch here is that, we have to tell the GW framework that we have expanded both the Header and Item entities in a single entity set call and no need to call the child entity set to fetch the the Sales Order Items. We can do this using parameter ET_EXPANDED_TECH_CLAUSES of GET_EXPANDED_ENTITYSET. Append the Navigation Property Name(SOHEADERTOITEM) in this exporting parameter, which will tell the gate way framework that the child entity has already been expanded and there is no need to call the child entity set.

 

An important point to not here is that the structure of the output entity set should have a field with Name same as Navigation Property Name(SOHEADERTOITEM). This field has to be a Table Type to support Header and Item relationship structure. Check structure below.

Structure.PNG

 

 

When you will call the Odata Service from the Client with $EXPAND, only the Header Entity Set will be called and no call is made to the Item Entity Set.

https://<Host Server:Port>/sap/opu/odata/sap/ZEXPAND_PARENT_CHILD_SRV/SOHeaderSet?$expand=SOHeaderToItem

 

 

In normal expansion scenario with $EXPAND, the gateway framework would first call SOHeaderSet and then the corresponding SOItemSet.

 

Thanks!!!!

Multi-Level Expansion with GET_EXPANDED_ENTITYSET

$
0
0

This blog is based on the idea of expanding Entities linked with Multi-Level Navigation Properties(A->B->C->D) in a single Gate Way  framework call.

 

To get an idea of expanding multiple entities linked with Navigation property in a single ENTITYSET call with $EXPAND, refer to my recent blog at Expand Parent Child Entities in a Single Expansion - GET_EXPANDED_ENTITYSET.

 

Consider below entity relation ship ENTITY A -> ENTITY B-> ENTITY C linked with Navigation properties Entity A to Entity B = AB and Entity B to Entity C = BC. With this blog I am trying to fetch data for all the entities A, B and C in a single call of the gateway framework using below URI call where A is linked to B and B is linked to C via a navigation property. This is like an INNERJOIN on the interrelated Entities linked via navigation properties:

/sap/opu/odata/sap/zmultilevel_exp_srv/EntitySetA?$expand=AB/BC,

this would return data for entity A, B and C in a single Gateway Framework Call which would otherwise be achieved with below 2 Odata Calls:


/sap/opu/odata/sap/zmultilevel_exp_srv/EntitySetA?$expand=AB

/sap/opu/odata/sap/zmultilevel_exp_srv/EntitySetB?$expand=BC


In above entity expansion, you could always use filters based on the entities A and B, However, the way you access the various properties of entities A and B is slightly different.


Say you want to filter data result on the basis of property X of entity A, the above link would be represented as /sap/opu/odata/sap/zmultilevel_exp_srv/EntitySetA?$expand=AB/BC&$filter=X eq <Filter Value>.


However, if you want to filter result set based on property Y of entity B, the link would be represented as

/sap/opu/odata/sap/zmultilevel_exp_srv/EntitySetA?$expand=AB/BC&$filter=AB/Y eq <Filter Value>.


We will consider above situations with the help of Sales Order Data linked with entity relations SalesOrder Header -> Sales Order Items ->Sales Order Schedule Lines


Consider below Entity Structures and Navigation Properties:

Entities.PNG

SOHeader.PNG

SOItem.PNG

SO Item Schedule Lines.PNG

 

   Associations.PNG

Navigation.PNG

Item to Schedule Lines.PNG

 

Redefine GET_EXPANDED_ENTITYSET as explained in the attached snapshot.

Code1.PNG

 

Code2.PNG

The catch here is that, we have to tell the GW framework that we have expanded the Header, Item and Schedule Line entities in a single entity set call and no need to call the child entity set to fetch the the Sales Order Items and Sales Order Schedule Lines. We can do this using parameter ET_EXPANDED_TECH_CLAUSES of GET_EXPANDED_ENTITYSET. Append both the Navigation Property Name(SOHEADERTOITEM/SOITEMTOSCHDLN) in this exporting parameter, which will tell the gate way framework that the child entity has already been expanded and there is no need to call the child entity sets.

 

An important point to not here is that the structure of the output entity set should have fields with Name same as Navigation Property Name(SOHEADERTOITEM and SOITEMTOSCHDLN).  Check structure below.

SOHeaderItemsScheduleLines.PNG

 

Access Scheduel lines data along with Header and Line Items:
https://vmw4462.wdf.sap.corp:44362/sap/opu/odata/sap/ZMULTILEVEL_EXPAND_SRV/SOHeaderSet?$expand=SOHeaderToItem/SOItemToS…

 

With filter on base entity(SOHeader)

https://vmw4462.wdf.sap.corp:44362/sap/opu/odata/sap/ZMULTILEVEL_EXPAND_SRV/SOHeaderSet?$expand=SOHeaderToItem/SOItemToSchdLn&$filter=Vbeln%20eq%20%271%27&$format=json

 

FilterOnHeader_Property_Vbeln.PNG

With filter on Items Entity (SOItem): The catch here is that, you have to fetch the filter from the filter string from IO_TECH_REQUEST_CONTEXT->MO_FILTER->MV_FILTER_STRING.


https://vmw4462.wdf.sap.corp:44362/sap/opu/odata/sap/ZMULTILEVEL_EXPAND_SRV/SOHeaderSet?$expand=SOHeaderToItem/SOItemToS…

SOHeaderToItem_Filter_Vbeln.PNG

 

Kindly share your inputs and thoughts on this.

Are the SAP Gateway Addons non modifiable?

$
0
0

Last week a customer that planned to start with SAP Fiori asked for an SAP official statement whether the SAP Gateway Addons are non modifiable.

 

Strangely enough ...

 

I wasn't able to find such an official statement.

 

 

We therefore changed our central SAP Note 1569624  - Installation/Delta Upgrade of SAP NW Gateway 2.0 accordingly which now finally states:

"All the Gateway 2.0 parts are non-modifying components ( GW_CORE 200,IW_CNT 200 IW_CBS 200 IW_FND 250 IW_BEP 200 and IW_SCS 200 )and can also be installed on a Netweaver 700 EHP3 systems or Netweaver 730 EHP1 system based on the import conditions."

 

 

Please note that with SAP NetWeaver 7.40 the SAP Gateway functionalities GW_CORE, IW_FND and IW_BEP are shipped with the software component SAP_GWFND which is part of SAP Basis of SAP NetWeaver 7.40. As a result no separate statement like the one mentioned above is needed anymore for 7.40 based systems.

 

So if your customer are also asking (this very valid) question you can refer them to the note that I have mentioned above.

 

Best Regards,
Andre

 

Viewing all 253 articles
Browse latest View live




Latest Images