Technology Blogs by SAP
Learn how to extend and personalize SAP applications. Follow the SAP technology blog for insights into SAP BTP, ABAP, SAP Analytics Cloud, SAP HANA, and more.
cancel
Showing results for 
Search instead for 
Did you mean: 
bernhard_grusie
Product and Topic Expert
Product and Topic Expert

Updates



  • 16/11/2023: ADT wizard robustness, see section "What comes next?".

  • 13/12/2023: Hint for error log integration in section "Tips for developers".



Introduction


This blog post will describe the Service Consumption Model 2 for OData. I will describe its benefits, provide a description of the model, take a look at the OData Client Proxy at runtime and also dive into the ABAP cross trace integration as well.

If you want to receive or send data to an OData V2 or V4 service within SAP BTP, ABAP Environment or SAP S/4HANA ABAP Environment, you can use the "Service Consumption Model 2" for OData. As of release 2311, it is possible to consume Complex Types, Complex Collection, Action (bound) and Functions (bound). Of course, the consumption of Entity Types and Entity Sets is also possible.

In addition you get fewer generated artifacts. The persistence of the underlying model has changed completely. In the first version you get an abstract CDS View for each Entity Type. For large services with multiple Entity Types, you could end up with a lot of artifacts. Now only one class with type definitions is created.


Many artifacts in the first version of the Service Consumption Model for OData




Use case


If you have an SAP BTP, ABAP Environment or SAP S/4HANA Cloud, ABAP Environment system you can use the Service Consumption Model for OData. From here you can connect to a Cloud or an on-premise system.

 


Scenario


 

In my scenario I am consuming the /dmo/travel service from another Cloud system. A call to the Entity Set Travel returns the following data:
GET /sap/opu/odata4/dmo/api_travel_u_v4/srvd_a2x/dmo/travel_u/0001/Travel

{
"@odata.context": "$metadata#Travel",
"@odata.metadataEtag": "W/\"20230919122803\"",
"@odata.nextLink": "/sap/opu/odata4/dmo/api_travel_u_v4/srvd_a2x/dmo/travel_u/0001/Travel?$skiptoken=100",
"value": [
{
"@odata.etag": "W/\"SADL-202305191948080000000C~20230519194808.0000000\"",
"AgencyID": "70041",
"AgencyName": "Maxitrip",
"BeginDate": "2023-06-03",
"BookingFee": 40.0,
"CurrencyCode": "USD",
"CustomerID": "594",
"CustomerName": "Ryan",
"EndDate": "2024-03-31",
"LastChangedAt": "2023-05-19T19:48:08Z",
"Memo": "Vacation",
"SAP__Messages": [
],
"Status": "P",
"StatusText": "Planned",
"TotalPrice": 1889.0,
"TravelID": "1"
},
...


Service Consumption Model 2 for OData


As of release 1808, you can use the Service Consumption Model for OData. From release 2311 on, the wizard in the ABAP Development Tools (ADT) will automatically use the new version.

Wizard


Select File -->  New --> Service Consumption Model and choose OData as Consumption mode in ADT.

The consumption system requires a representation of the remote service. This knowledge is used to create the URL, write and read the JSON form the HTTP requests and responses. Therefore, the wizard needs the EDMX file (a service metadata document that describes the data model exposed by the service as an HTTP endpoint). OData uses EDMX as the format for this description of the remote service. You can get this by adding $metadata to the end of the service document, in my case it is the following URL:
GET /sap/opu/odata4/dmo/api_travel_u_v4/srvd_a2x/dmo/travel_u/0001/$metadata

I saved this file on my computer to use this in the wizard. In addition I chose ZBG_TRAVEL_SCM as the class name. This class is the model representation and will contain all the types for my client.


EDMX import and class name


 

The EDMX file is analyzed beforehand to identify potential problems. It could be that certain artifacts are ignored, for example, parts of them violate the OData metadata rules. In my case, the EDMX file describes several Entity Types, Entity Sets, a Complex Type and a Bound Action.


Analysis of EDMX file


 

The next step looks for the OptimisticConcurrency annotation of the Org.OData.Core.V1 vocabulary. If an Entity Set has this annotation, modifying requests must use an ETag. If an Entity Set does not have this annotation, you can select the ETag support here.


ETag support


Finally, I get the Service Consumption Model 2 for OData:


Service Consumption Model 2 for OData


In the upper left section, you can see the model class that describes the /dmo/travel service. I use the code snippets from Travel EntitySet and Read list as operation, as a starting point for my OData client.

 

Model class


The model class has the following parts:

  1. Type definitions that can be used in my client code. I use a table of zbg_travel_scm=>tys_travel_type to retrieve the travel data.

  2. To find the corresponding types, constants are created for Entity Sets, Entity Types, Complex Types, Actions and Functions. Here is the ABAP doc for the Entity Type constant, including the link to the type:




  3. The model definition is done in several method implementations. The types are used to define all the artifacts of the remote service. In addition a mapping between the ABAP and the EDMX name is done here. ABAP artifacts are limited to 30 characters. In EDMX they can be up to 128 characters long in camel case.


If you need to customize the result of the wizard, for example because you need to adapt to certain naming conventions, you can modify the source code of the generated class and adapt it to your needs.

 

Support for Action and Functions


To call an action or a function, structures and tables for the parameter are generated. With release 2311 the ADT integration is still missing. So I can't select a bound action, an action import, a bound function or a function import and use the code snippet from the ADT. However, the parameter structure is there and I can use it at runtime to call the operation. You can find examples in SAP Help portal.

 

Connecting to a Remote Service


In a cloud system I need an outbound communication scenario, an outbound service and a communication arrangement for the http connection. Tutorial: Prepare Consuming System and Service Consumption Model describes the steps to achieve this.

 

OData Client Proxy at Runtime


For my client, I have used the code snippet from ADT (right hand side in the Service Consumption Model) to read the Entity Set Travel. The client code uses the type from the model. changed three things after that:

  1. Established the HTTP connection using the communication scenario and the outbound service.

  2. Changed the IV_RELATIVE_SERVICE_ROOT parameter of the factory (line 56 in the screenshot below) to point to the OData service. This path depends on the communication system.

  3. Added the out->write() statement at the end (line 81).


And voila, the GET request and transformation of the JSON response to ABAP was done for me.


OData Client Proxy at Runtime



Conclusion


The Service Consumption Model 2 for OData supports more OData features and generates fewer artifacts. The model class can be adapted to my needs, if the result of the wizard does not meet my expectations. It would be great to get feedback from you, so that we can further improve the wizard if this is indeed the case.

What comes next?



  • Make the ADT wizard more robust when importing EDMX files. Skipped elements will be part of the generated model to identify them later. 

    • As of release 2405, the ADT wizard skips elements that violate the OData specification (for example trying to create a key property inside a complex type). You find skipped elements in the gcs* constants.



  • Full support for actions and functions in the ADT, including code snippets.

  • On-premise shipping of the Service Consumption Model for OData.

  • Multiple namespace support for SuccessFactors services.

  • OpenAPI importer to support REST services.


Links


For more details on the OData Client Proxy, Service Consumption Model and communication scenario, see Developing External Service Consumption: OData Services




Feel free to ask me questions, provide feedback or to share this blog with others. Thank you.

 

 




 

Tips for developers


Error log integration


You can see errors in the SAP Gateway error log of ADT. To configure the feed, you can follow Andre's blog:: how-to-use-the-sap-gateway-error-log-in-adt

 

Cross trace integration


Sometimes it is good to know what the OData Client Proxy does under the hood. Especially connecting to another system can be tricky. Therefore the OData Client Proxy is part of the ABAP Cross trace (ADT Windows --> Show View --> ABAP Cross trace):


Activate OData Client Proxy in cross trace


 

In the trace result you can see for example the response payload and the CSRF token fetch:


HTTP payload in cross trace


 

 


 
35 Comments
Frank1
Participant
0 Kudos
Thank you for great sharing. You mentioned that want to receive or send data to an OData V2 or V4 service within SAP BTP, ABAP Environment,  can use the “Service Consumption Model 2” for OData. What do you mean receive or send data to an OData V2 or V4? In this case why not use Remote API? Is this for there is no corresponding Remote API then turn to this approach? Thank you.
bernhard_grusie
Product and Topic Expert
Product and Topic Expert
0 Kudos
HI Frank,

 

you have two systems (see use case section), the Service Consumption Model is for the client side. The OData Client Proxy is an ABAP client for OData. It allows you to make GET, POST, PUT, etc. requests to a remote OData service.

Best regards
Bernhard
nsathya_infy
Explorer
0 Kudos
Hi Bernard,

Thanks for Sharing. It is now available for ABAP on BTP and S/4 HANA Cloud as per the article, is there a plan to enable the OData client of On-premises too? Technically ABAP on Cloud is now available as a part of Development Extensibility(Embedded Steampunk).

Regards,
Sathya
bernhard_grusie
Product and Topic Expert
Product and Topic Expert
Hi Sathya,

On-premises delivery is planned, as you can see in the "What's next?" section. The reason for not shipping was that our first design approach in SCM1 was not perfect. After changing of the persistence, we can ship OData client on premise.

Best regards
Bernhard
nsathya_infy
Explorer
0 Kudos
Thanks for the response. I missed the "What's next?" section.
0 Kudos
Hi Bernhard,

Thank you for sharing the new features.  I look forward to use consumption model 2.

I have been using consumption model to push and pull data from S/4 On-prem from SAP BTP.

I am facing a strange problem. Everytime whenever there is a change in metadata, I had to create a new consumption model and delete the old one. I had to adjust the code accordingly.

I could not regenerate or refresh the existing consumption model.

Does Consumption model 2 overcome this issue?

Best Regards

Vijay
bernhard_grusie
Product and Topic Expert
Product and Topic Expert
0 Kudos
I mention in the blog that we have to guess an ABAP name (30 characters) from the Edm world of 128 characters. This guessing algorithm is stable up to a certain point.
For example, if a new entity type has been introduced and multiple entries reach the 30 character limit, we add a number to the end of the type name to be unique.

 

Finally, we create a large class with types and the definition. It is also possible to just add the new type and method implementation to your used model class manual when you come to such situations.
0 Kudos
 

hello Bernhard

 

For the metadata: https://sapes5.sapdevcenter.com/sap/opu/odata/sap/SEPMRA_PROD_MAN/$metadata/

I've tried to generate the SCM in the trial ABAP Runtime in BTP and I'm getting "Activation failed with code '2'" ?!

Moreover, an inactive SCM is generated and if I try to delete it, I'm getting HTTP/1.1 500 Internal Server Error ?!

 

Could you kindly help, please?

 

thanks & best regards

 

M.
maryia_saskevich
Newcomer
0 Kudos
Hi!

Did you solve this problem?
0 Kudos
 

hi,

no, i did not.

I think this is (yet another) limitation of the Trial abap account in BTP. The strange thing is that the previous version of the SCM used to work in the Trial. With this new version, it cannot seem to be activated in Trial nor I can delete the generated malfunctioning SCM object 😞

best

m.

 
Andre_Fischer
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hi Sathya,

as described in my blog post

How to use the OData Client Proxy in SAP S/4 HANA | SAP Blogs

it would be possible to generate the Service Consumption Model as a workaround in a Steampunk System (e.g. a trial system).

Then you would be able to copy the code to your on premise system and perform the steps described in my blog post to create an OData V4 model provider class from the generated Service Consumption Model class.

This can then be registered as an OData Proxy Client.

Kind regards,

Andre
christian_d
Explorer
0 Kudos

Hi,

one question...is there a tutorial how to use the Business Data (lt_business_data) within a new Fiori.

In Version 1 of the Service Consumption Model we had an generated CDS that we could use for generating a Fiori-App.

Now there is only a model class....

Thx in advance

Christian Dülsen

bernhard_grusie
Product and Topic Expert
Product and Topic Expert
0 Kudos
Hi Christian,

 

I am not sure how you reused the abstract CDS view for a Fiori UI, but with the new version it is not possible to use the type definition directly.

Best regards
Bernhard
bernhard_grusie
Product and Topic Expert
Product and Topic Expert
0 Kudos
The limitation of the Trial ABAP account will be removed with Hot Fix collection 6.
sebastian_wilhelm1
Participant
0 Kudos
Hi Bernhard, is there a tutorial on how to use the Business Data? Generally the business data should be stored/used in CDS View which can be used in a Fiori-App (e.g. as a value help, etc.). The old wizard generated a CDS. Do I have to create this CDS now manually?

Thanks, Sebastian
Andre_Fischer
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Christian,

in version 1 of the Service Consumption Model so called abstract entities were generated for each entity of the to be consumed OData service whose $metadata document had been imported.

Based on this abstract entity the developer was able to build a called custom entity.

How to create a custom entity with the new Service Consumption model 2.0 is described here in step 5:

abap-platform-rap-workshops/rap6xx/rap620/exercises/ex3/README.md at main · SAP-samples/abap-platfor...

Kind regards, 

Andre

 

Andre_Fischer
Product and Topic Expert
Product and Topic Expert

Hi Sebastian,

You would have to create a custom entity manually and use the type definition within this class to define the type of the fields and the define method `def_...` to get the nice external field names.

I have updated the following hands-on script 

abap-platform-rap-workshops/rap6xx/rap620/exercises/ex3/README.md at main · SAP-samples/abap-platfor...

so that it describes the steps needed to retrieve the business data.

Kind regards,

Andre

 

christian_d
Explorer
0 Kudos
Hello Andre,
Thank you very much for your answer. I finally figured out how to use a custom entity.
I was following a tutorial to learn how to consume an O-Data service from our S/4 on Premise backend when the Service Consumption Model version changed and all the tutorials I found only showed the "old" way.
I was now able to successfully retrieve and process the service.
Kind regards
FaizSabu
Newcomer
0 Kudos

Hi Bernhard,

In the above Blog, you have mentioned that "As of release 2311, it is possible to consume Complex Types, Complex Collection, Action (bound) and Functions (bound)."

I have tried to consume the metadata : /sap/opu/odata4/sap/api_warehouse_order_task_2/srvd_a2x/sap/warehouseorder/0001/$metadata, but i am getting the below error. Is there anything i am missing.

FaizSabu_0-1707667678814.png

Best Regards,

Faiz

 

bernhard_grusie
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi Faiz,

From the screen shot I can see that you use version one of the service consumption model. I'm not sure where (trial/productive) you use this one but this is definitely wrong. Could you create an incident on opu-gw-cp?

best regards

Bernhard

vsubbakrishna
Participant
0 Kudos

hello @bernhard_grusie ,

When I created the "service consumption model" on SAP BTP platform for The SOAP API "Journal Entry - Post (Synchronous)" "JournalEntryCreateRequestConfirmation_In" it created hundreds of data elements and structures. 

if there is any change in API definition, do we need to regenerate entire structure? will the existing code be impacted if any filed is removed/renamed?

Thanks

kris

bernhard_grusie
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hello Kris,

the OData service consumption model only has type definitions in the class, rather than structures and data elements.

In the event that new fields are added to the API, the Structure type must be extended to include these new fields. Similarly, any changes to existing property types should be reflected in the corresponding field definition. It is important to note that removing something from the API could result in an error when attempting to use the element.

To ensure everything is up to date, it is recommended to regenerate the service consumption model to get all changes to the model

Best regards,
Bernhard

vsubbakrishna
Participant
0 Kudos

Thank you @bernhard_grusie for your clarification!! Appreciate your reply!!

nishantbansal91
Active Contributor
0 Kudos

Hello  bernhard_grusie

My client is on ECC system and Gateway component 2.0 and we are planning to develop the oData for exposing the data from the custom table. 

We are developing one application on ABAP Environment on BTP.  Is it possible to consume the odata from ECC to ABAP Environment on BTP via Destination? 

Below is the sample code which we have used for mulesoft integration. Can we use the same class for oData intergration as well? 

DATA(destination) = cl_http_destination_provider=>create_by_cloud_destination(

i_name = 'mulesoft_crm'

i_authn_mode = if_a4c_cp_service=>service_specific

).

bernhard_grusie
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi @nishantbansal91 

you can call the OData service in ECC from the ABAP Environment on BTP. There are multiple ways to establish the connection. The recommended way is described under "Connecting to a Remote Service" in this blog. However, cl_http_destination_provider=>create_by_cloud_destination is also possible. The different options are explained in the SAP help documentation:

https://help.sap.com/docs/btp/sap-business-technology-platform/enable-http-communication-in-your-aba... 

Best regards 
Bernhard

nishantbansal91
Active Contributor
0 Kudos

@bernhard_grusie I have created the Service consumption but while creating the communication scenario on BTP ABAP I am not able to select the Service in the outbound tab. 

I don't understand how to create the custom communication scenario for the newly created service consumption

nishantbansal91_0-1708692474398.png

 

bernhard_grusie
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi @nishantbansal91 

you need to create an outbound service. 
See step 2 in: https://developers.sap.com/tutorials/abap-environment-create-service-consumption-model.html 
This one can be added to your CS. 

Best regards
Bernhard

hendrikp
Explorer
0 Kudos

Hello,

in the Service Entity Set Details we find code snippets for all basic operations. Would it be possible to also extend the examples with deep insert, deep update and read with expand. I found blog entries which describe it(deep insert, read with expand ) but it would be handy to have it also with the other snippets.

BR
Hendrik

bernhard_grusie
Product and Topic Expert
Product and Topic Expert

 

Hi @hendrikp 

 

that is a good point. I will create a backlog item for this. You will find examples in the SAP help:
https://help.sap.com/docs/btp/sap-business-technology-platform/expand-option?locale=en-US&version=Cl... 
https://help.sap.com/docs/btp/sap-business-technology-platform/odata-request-deep-create?locale=en-U... 

It would also be nice to have a link to the help portal from the SCM editor in ADT.



Best regards
Bernhard

hendrikp
Explorer
0 Kudos

Hello,

we want to create multiple sub childs of an sub child in a deep insert. Is that possible and how ?
Like as an example we try to add the childs Phone Number, Fax Number and Email Number to Business Partner address, which is a child of business Partner. The methods add_child and set_properties are the only possible methods to use. There is no methode like get_child.
I'm searching for something like this:

DATA(lo_data_description_node) = lo_request->create_data_descripton_node( ).
lo_data_description_node->set_properties( it_bp_property ).
lo_data_description_node->add_child( 'TO_BUSINESS_PARTNER_ADDRES' )->set_properties( it_adress_property )->add_child( 'TO_PHONE_NUMBER' )->set_properties( it_phone_property ).


lo_data_description_node->get_child( 'TO_BUSINESS_PARTNER_ADDRES' )->add_child( 'TO_FAX_NUMBER' )->set_properties( it_fax_property ).


lo_data_description_node->get_child( 'TO_BUSINESS_PARTNER_ADDRES' )->add_child( 'TO_EMAIL_ADDRESS' )->set_properties( it_mail_property ).

BR

bernhard_grusie
Product and Topic Expert
Product and Topic Expert

Hi @hendrikp 

there is no get_child at the moment. You have to store the variable like:

DATA(lo_data_description_node) = lo_request->create_data_descripton_node( ).
lo_data_description_node->set_properties( it_bp_property ).
data(lo_dd_partner_address) = lo_data_description_node->add_child( 'TO_BUSINESS_PARTNER_ADDRES' ).
lo_dd_partner_address->set_properties( it_adress_property )->add_child( 'TO_PHONE_NUMBER' )->set_properties( it_phone_property ).


lo_dd_partner_address->add_child( 'TO_FAX_NUMBER' )->set_properties( it_fax_property ).
nishantbansal91
Active Contributor
0 Kudos

Hello @bernhard_grusie  

 

I can see the response in coming via ABAP cross track call but I am getting exception as well.

Below is the response 

nishantbansal91_0-1713532090277.png

 

Below exception is coming while calling lo_response = lo_request->execute( ) method.

 

  Exception : Error returned by virus scanner (Profile /IWBEP/CP/ODATA_DOWNLOAD) 

 

nishantbansal91_1-1713532205596.png

 

We have activated/deactivated the virus scan profile from backend but still system is raising this exception.. 

Below is the full code 

lo_client_proxy = /iwbep/cl_cp_factory_remote=>create_v2_remote_proxy(

EXPORTING

is_proxy_model_key = VALUE #( repository_id = 'DEFAULT'

proxy_model_id = 'ZSCM_ZSEMERGENCY'

proxy_model_version = '0001' )

io_http_client = lo_http_client

iv_relative_service_root = '/sap/opu/odata/sap/ZCSOS_test_CDS/' ).

 

lo_request = lo_client_proxy->create_resource_for_entity_set( 'ZCSOS_test' )->create_request_for_read( ).

lo_request->set_top( 50 )->set_skip( 0 ).

 

" Execute the request and retrieve the business data

lo_response = lo_request->execute( ).

lo_response->get_business_data( IMPORTING et_business_data = lt_business_data ).

 

shahbhat
Product and Topic Expert
Product and Topic Expert
0 Kudos

Hi @bernhard_grusie ,

 
I downloaded edmx from Business Accelerator hub for SFSF ODATA V2 API (https://api.sap.com/api/ECEmploymentInformation/overview). I am getting this error when trying to create Service Consumption model in BTP ABAP using SVC 2.0. Is this a possible bug?

31124f15-7a65-4c8b-8309-4b653d768754.png

shahbhat
Product and Topic Expert
Product and Topic Expert
0 Kudos

I was able to fix the error mentioned in my previous comment by editing the EDMX file (removing one schema).

vsubbakrishna
Participant
0 Kudos

hi @bernhard_grusie ,

in the below tutorial to Call an external API SAP BTP ABAP Environment and parse the response using JSON or XML there is no usage of service consumption model..could you please let us know in what scenarios SVC is optional.

https://developers.sap.com/tutorials/abap-environment-external-api.html

Thanks

Kris