Consuming Gateway OData service with OData adapter
Introduction
OData is everywhere these days in SAP’s plethora of products. In fact it is the key enabler for the Fiorification of SAP’s ecosystem backed by SAP NetWeaver Gateway.
From an integration perspective, inevitably OData-based integration will come be a common requirement. SAP released an OData Adapter few years back, however content around it is few and far in between compared to its more popular cousin, the REST adapter.
This blog post covers the use of the OData receiver adapter to consume a NetWeaver Gateway OData service. While one would have expected that such design to be straightforward, there are a few tweaks required (as usual, buried deep in some SAP Note) to get it working right.
This post assumes that the reader interested in reproducing such a scenario has solid fundamentals in PI development, and therefore some of the more basic steps/tasks are not included here. The focus will be on the additional effort required to make it work for a Gateway OData service.
Prerequisite
The Operations Modeler is required in order to generate the ESR definitions for the OData service. This will require an Eclipse installation with HCI plugins. Refer to the following for the installation details:-
SAP HANA Cloud Integration Tools
Design and Configuration Steps
Step 1 – Find a Gateway service
Before we begin, we will of course need an existing Gateway OData service. For the purpose of this example, I will use the existing UserService available in a Gateway system. Following is the screenshot of the corresponding ICF entry in the system.
This service can be tested in a REST client. In the following screenshot, this service is called from Postman, where it displays the 3 available collections of the service.
Step 2 – Generate the definition for ESR using HCI Operations Modeler
How to Model Successfactors SOAP and ODATA Entities using Eclipse Juno Tool provides more details on the usage of the Operations Modeler. In this post, I will zoom in directly on the relevant section.
After launching the Operations Modeler, provide connection details to the Gateway service.
Select the entity, in this case UserCollection.
For this example, the scenario will be configured to perform a dynamic query. As such, select the Query(GET) operation, and select all the available fields.
Proceed with the default options in the following screen until the end of the wizard. Then, the following window will be provided to indicate that the corresponding XSD for the GET operation has been generated. It can be found in the src.main.resources.wsdl folder as shown below.
Back in the channel configuration screen, the Operation Details will be populated. Of particular importance is the ResourcePath field which will be used in the later configuration step.
Step 3 – Develop the ESR content
We now proceed to develop the relevant design objects in ESR. In order to perform a dynamic query call, we need to use an SAP-provided XSD available in the CONNECTIVITY ADD ON SWCV. The details are further elaborated in the blog How to Use OData Adapter with Dynamic Query Calls as well as SAP Note 2052093.
First of all, import the XSD generated in the above step. This will act as the definition for the response message.
For the request, the provided XSD as mentioned above will be used.
Following is the definition for the Inbound Service Interface.
On the outbound side, we will expose the interface as a synchronous SOAP web service. Therefore on the outbound side, the following Data/Message Type are developed.
Definition for sender request – a single input field for the user ID.
Definition for sender response – all the similar fields as provided by the OData service.
For the mapping of the request message, the QueryStringOptions message will be mapped so that the filter field will dynamically filter the username based on the input ID. It uses the standard OData filter functionality (for more details, check OData URI conventions). The outcome of mapping for the field will be as follows:-
filter = username eq ‘<ID>’
The response mapping will be just a 1-1 mapping from the response of the OData service to the SOAP response definition.
Step 4 – Configure OData receiver channel
Lastly, we can configure the OData receiver channel referring to the following SAP Library link.
In the General tab, use the address to the UserService for the URL and provide basic authentication details.
For the Processing tab, we will select QUERY as the Operation. Now we will use the Resource Path that was generated in Step 2. However, the query parameters will be changed so that it uses the dynamic filter value populated during mapping. For the payload format, we can optionally switch to JSON in order to benefit from the smaller payload as compared to Atom-XML.
Now, for the final, and most important part of the configuration. We need to configure the following additional parameters in the Advanced settings tab.
Firstly, dynamicQuery = true is required to enable mapping based dynamic query as mentioned by SAP Note 2052093 above.
Secondly, ContentTypeEncoding = none is required when consuming Gateway OData service. This is mentioned in SAP Note 2317362. Without this setting, the OData generates additional charset details in the Accept HTTP Header (which by the way is incorrect IMHO when I read the HTTP 1.1 spec – Accept-Charset should be used instead). This additional charset details causes the Gateway service to fail when being called, resulting in an HTTP 406 error with the following error message:-
The resource identified by the request is only capable of generating response entities which have content characteristics not acceptable according to the accept headers sent in the request
Step 5 – Testing the interface
Ok, finally with all the design and configuration completed, we can proceed to test this out. After generating the WSDL for the scenario and importing it into SoapUI, we can test this out by sending a simple request message consisting of the user ID. The response from the OData service provides the details of the user ID.
Conclusion
As demonstrated above, with a few tweaks here and there (no thanks to cleverly hidden SAP Notes!), it is possible to configure PI’s OData adapter to consume a Gateway service. While it is also possible to Expose Gateway Services from SAP Process Orchestration, without the use of PI interfaces, there might be requirements they need to be configured/developed as PI interfaces.
Hi Eng Swee Yeoh,
Thanks for the blog. Is it also work for HCI?
Regards,
Chris Xu
Of course not. Development on HCI is totally different from PI.
Thank you, Eng Swee Yeoh.
I am new to HCI. And I am doing some hands on now. Simple scenario SOAP=>HCI=>OData. I couldn't find how to build dynamic query string for OData receiver adapter. Any reference or suggestion?
Thank you very much!
Regards,
Chris Xu
Thanks Eng Swee,
as always very comprehensive Blog. Great to see you "back" also on the new community.
Just by chance (I was off on other topics than PI / PO / HCI for a couple of months): They did plan to introduce a OData Sender adapter to PI/PO, right? Did that already happen or do roughly know when this is planned? I skimmed through the "What's new" section of NW 7.4 help and couldn't find any reference of a sender OData adapter. Unfortunatelly help.sap.com for NW 7.5 seems to have troubles right now, so could not have a look at that.
Anyways, keep it up and cheers.
Jens
Hi Jens
Haven't seen anything on an OData sender as far as I know. Anyway, development in the PI space is pretty much dead these days other than the once a year Customer Connection project.
The OData adapter is categorised under the Connectivity Add On section in Help SAP. But Help SAP (like the rest of SAP) is also in a mess these days, so can't really find the link to the main page for that. The Add on has remained at SP02 for a few years.
Eng Swee
Thanks Eng Swee,
Is it possible to access Function Import with dynamic query? I am trying to access but I can not do it. Any recommendation?
Thanks
Fede
Hi Fede
I have never worked with a service using Function Import, so can't comment on that. It could be possible that this is not supported.
Regards
Eng Swee
Thank you very much anyway !!
Thank you for this introduction to the OData Adapter!
Personally I have only used the REST Adapter so far to integrate some odata based services.
Do you see any situations where you would use the REST adapter over the OData adpater or vise versa in case you have to call an OData CRUD Service?
Hi Peter
No hard and fast rule about it, really. The standard OData adapter is relatively basic, so if you can achieve it with the REST adapter, that is fine. Furthermore, it only supports OData v2 at the moment, and limited to Basic or Client-cert authentication.
The only thing is that is has the hidden $skiptoken functionality as described in my subsequent blog on the OData adapter:-
https://blogs.sap.com/2017/03/13/diving-deeper-into-the-odata-adapter/
Regards
Eng Swee
Hi Eng Swee,
After launching the Operations Modeler, I'm facing the below error.Please find the below screenshot.
Thanks & Regards,
Govardhan.
Hi Eng Swee, I have been always studying from your blogs. When I use odata adapter, there is a error called http/1.1 403 forbidden, could you tell me how to set x-csrf-token http header in odata adapter. Thank you!
As far as I am aware, the OData adapter provides only very basic options for authentication (Basic, Cert, None). If the OData service requires setting of X-CSRF tokens, you might not be able to use this adapter for your scenario.
Hi Eng Swee
Great blog. I have been trying OData to consume an OData service. But for some reason only query option 'top' works in resource path. e.g.
Resource Path : Entity?$top=top
If I want to try to skip some records then query should be :
Entity?$skip=skip&$top=top
ideally it should work. For some reason it doesn't.
I haven not seen a single article using skip in the query, despite it being part of QueryStringOptions definition in ESR.
I am not sure if I am missing something. Do you haven any idea?
Hi Saurabh
Were you able to resolve this issue? Can you please provide some pointers on what is causing the issue.
Hi Eng Swee Yeoh,
Thanks for sharing the valuable informations, always a pleasure to read your blogs.
I have a issue implementing a SFSF Odata RCV, it is all working through soap ui like it schould, i think may be a url encoding challange!
My RCV Channel Setup in the IFlow
xpi_inspector + Error is => please check the attachment below.
For the Filter value i tried also => userId%20eq%20%27000500014533936%27 or userId%20eq%20’000500014533936′ but no success. (the SF API think i am filtering after this Property => userId%20eq%20% )
PS: if i request without dynamic Query Param just like => User?$select=userId,firstName => it work’s
But if i enable the filter option (dynamic or static) i have the Error.
Do you have any idea?
Thank u.
Youssef
Unfortunately, I won't be able to assist with your issue.
The focus of this blog is on using the OData adapter with a Gateway-based service. I have not used this (or the SFSF adapter) with SF-based service.
Hi Eng Swee,
How the concept of polling and token based authentication work with Odata adapter or we have to rely on rest adapter ?
Thanks.
CG
Hi,
Is it possible to dynamically set the Entity name in the Resource Path on the SAP PI? I was able to set the filter dynamically with this option, but I would need a same possibility what the CPI SFSF OData adapter has, where you can set the Entity dynamically as well.
Thanks for your answer.
Hi Eng Swee
Hope you’re doing fine!
I found this post while looking for guidelines about using the Odata adapter on PI. I now spent some time trying to find the mentioned Operation Modeler in Eclipse. Apparently, as you also learned here: https://blogs.sap.com/2018/02/15/sap-cloud-platform-integration-finalizes-web-application-for-integration-developers/comment-page-1/#comment-412363 this feature got discontinued by SAP in 2018. It’s by the way still mentioned in the recently updated document named “Developer's Guide: Managing Integration Content” - that’s very weird. Do you suggest installing Eclipse Neo to get the Int.Designer, as mentioned in the post linked above, or is there a better way?
Thank you
Phililppe
Hi Philippe
If you have your hands on a CPI tenant, then you can use the OData Query Wizard that is available when using an OData receiver channel. The XSD generated is the same. This saves you from having to install Eclipse Neon.
Regards
Eng Swee
Thanks for the quick answer Eng Swee. OK, I thought that could be today's solution. But it means I also need a cloud connector connection to the on-prem S/4 which hosts the Odata service. Luckily, in my case this should be possible. Otherwise it would still be tricky. I wish SAP would add this query wizard to the PI/PO adapter as well to make it complete.
Regards,
Philippe
You can also use the query wizard with a local EDMX file, therefore not requiring the Cloud Connector connection. You can query your S/4 OData service manually, extract the EDMX and then upload it to CPI to run the query wizard.
And of course you can also install Eclipse Neon to run the modeller there and connect to your on-prem S/4.
These are just the different options available for you - so choose one that is suitable.
As you know, Integration Suite is the future, so IMHO it's unlikely that you will see SAP investing into making the query wizard with the PI/PO adapter.
Do you have any blog posts showing how to consume a JSON datetime field with the OData receiver?
We are getting invalid XML errors in the sending system because the OData receiver is appending "GMT" to the date time value in the XML message it constructs.
The OData service we are calling returns a datetime field as
"dt_field":"/Date(1548979200000)/"
and the XML message inside PI has the field looking like this
Which SOAPUI and the sending system flag as invalid XML. According to XML standards, an xsd:datetime field is assumed to be GMT and should not have "GMT" on the end of the string. So we are currently having to deploy a custom Java UDF for every datetime field in our payloads to strip the "GMT" from the value.
This seems wrong. I hope there is a flag/configuration setting in the receiver channel we can set to correct this.
Hi Eng Swee,
Is it possible to set 'select' dynamic query? If so could you provide please how can I set it?
Now I only have top, skip, filter and custom/@name fields in QueryStringOptions external definition. I use now Connectivity Add-on 1.0.
Thank you
Olesya
Hi Eng Swee,
Thank you for this useful blog! I am using ODATA Receiver Adapter (ADD ON 2.0) in PO system for accessing SAP back-end ODATA service for the CREATE operation.
As per your blog, I am trying to access Operation modeler in my Eclipse Oxygen version, I am NOT finding it anywhere, it Operation modeler is Eclipse version specific, if yes then which version I should install.
please help me.
Thank you in advance
Regards,
Jagesh Lakdawala