You are on page 1of 7

https://blogs.sap.

com/2014/03/11/how-to-consume-an-odata-service-of-sap-netweaver-gateway-with-apache-olingo/

How to consume an OData Service of SAP


NetWeaver Gateway with Apache Olingo

This article show s how to consume (Read) an OData Service w ith support of the Apache Olingolibrary.

As OData Service a gatew ay demo service is used w hich defines a data model
containingBusinessPartners and their related Products they sell. For this sample w e assume an use case
that a client (e.g. UI) is interested in all offered Products and in addition the related BusinessPartner w hich
supplies the Product.

To implement and demonstrate the described use case follow ing steps have to be proceeded:

Fulfil prerequisites to access the gatew ay OData demo service


Read a single Product and Read all available Products
Navigation from a Product to the related BusinessPartner
Inclusion of information of related Entries to reduce requests
Selection of w anted information from Entries to reduce transfered data

Prerequisites
The gateway demo service is named ZGWSAMPLE_SRV and the functionality the service provides is described
here. To get access to the gateway demo service it is necessary to sign up as described.

Read
Apache Olingo provides client functionality in form of create Requests (serialization) and interpret Responses
(deserialization) based on the OData format. It does not provide functionality for sending and receiving requests
so an application is free to decide whatever HTTP client library it wants to use. The methods to access provided
serialization and deserialization functionality are all declared at the EntityProvider class. For basic
consumption (Read) of an OData Service following methods are necessary:

1 of 7 5/18/17, 9:15 PM
https://blogs.sap.com/2014/03/11/how-to-consume-an-odata-service-of-sap-netweaver-gateway-with-apache-olingo/

EntityProvider.readMetadata(...) to read the metadata of the service.


EntityProvider.readEntry(...) to read an single entry.
EntityProvider.readFeed(...) to read a collection of entities.

Read Prerequisites: EDM/$metadata

Because Apache Olingo requires the metadata for serialization and deserialization of an entity the first step
is to read the w hole Entity Data Model (EDM) of an OData Service.

public Edm readEdm(String serviceUrl) throws IOException, ODataException {


InputStream content = execute(serviceUrl + "/" + METADATA, APPLICATION_XML, HTTP_METHOD_GET);
return EntityProvider.readMetadata(content, false);
}

To read the Entity Data Model (EDM) a HTTP GET on the corresponding $metadata URI of the OData
Service via the execute(...) method. The resulting content is passed into
the EntityProvider.readMetadata(InputStream content, boolean validate) method w hich de-serialize the
EDMX into an EDM object. This EDM object than can be used for necessary deserialization in combination of
read operations.

Read Entity: Product

To read a single Product of the service a single request to the ProductsCollection URI w ith set ID is done.

2 of 7 5/18/17, 9:15 PM
https://blogs.sap.com/2014/03/11/how-to-consume-an-odata-service-of-sap-netweaver-gateway-with-apache-olingo/

public ODataEntry readEntry(Edm edm, String serviceUri, String contentType, String entitySetName, String keyVa
throws IOException, ODataException {
// working with the default entity container
EdmEntityContainer entityContainer = edm.getDefaultEntityContainer();
// create absolute uri based on service uri, entity set name and key property value
String absolutUri = createUri(serviceUri, entitySetName, keyValue);
InputStream content = execute(absolutUri, contentType, HTTP_METHOD_GET);
return EntityProvider.readEntry(contentType,
entityContainer.getEntitySet(entitySetName),
content,
EntityProviderReadProperties.init().build());
}

The execute(...) method executes the request against the absolute URI and returns the response content as
InputStream which then is deserialized by the EntityProvider.readEntry(...) into an ODataEntry object. This

contains all properties (data) of the entry in form of a Map, additional entry metadata as EntryMetadata object
(which contains e tag, id, association uris and uri information), the ExpandSelectTreeNode , information whether
the entry contains inline e ntrie s and if the entry is a me dia re source additional the MediaMetadata .

Read Entities: ProductCollection

To read all Products of the service a single request to the ProductsCollection URI is done.

public ODataFeed readFeed(Edm edm, String serviceUri, String contentType, String entitySetName)
throws IOException, ODataException {
EdmEntityContainer entityContainer = edm.getDefaultEntityContainer();
String absolutUri = createUri(serviceUri, entitySetName, null);
InputStream content = (InputStream) connect(absolutUri, contentType, HTTP_METHOD_GET).getContent();
return EntityProvider.readFeed(contentType,
entityContainer.getEntitySet(entitySetName),
content,
EntityProviderReadProperties.init().build());
}

3 of 7 5/18/17, 9:15 PM
https://blogs.sap.com/2014/03/11/how-to-consume-an-odata-service-of-sap-netweaver-gateway-with-apache-olingo/

The execute(...) method executes the request against the absolute URI and returns the response content as
InputStream which then is deserialized by the EntitProvider.readFeed(...) into an ODataFeed object. This

contains all entities provided by the OData Service as ODataEntry in a list as well as FeedMetadata like inline
count and ne xt link.

All used URIs

Read metadata of service


Read single Product w ith id “HT-1000” of service
Read all Products of service

Navigate
The demo service defines an association betw een Products and their releated BusinessPartners as
navigation property at a Product w ith the name Supplier. By follow ing that association theBusinessPartner
can be retrieved. This can be done by calling the absolute URI to a Supplier of a single Product w hich can be
get by using the getAssociationUris(...) method of the EntryMetadata object. In this example the metadata
object method is called w ith parameter Supplier w hich then returns w ith a list w hich contains the absolute
URI (e.g. https://sapes1.sapdevcenter.com/sap/opu/odata/sap/ZGWSAMPLE_SRV/ProductCollection(‘HT-
1000’)/Supplier) w hich can be called to get the Supplier for the Product.

For this example w e prefer to already include the Supplier information for a Product into the response of our
request. Therefore a read with expand system query option is the w ay to go (in next section).

All used URIs

Navigation to Supplier
Navigation Supplier to its Contacts

Read more with Expand


To read an Entry or Feed w hich already includes properties of a related Entry (or Entries) the $expand system
query option can be used. The $expand clause is a list off all associations to be retrieved w ithin this request.
For the example the $expand parameter is set to the navigation property Supplier to be retrieved. This results

4 of 7 5/18/17, 9:15 PM
https://blogs.sap.com/2014/03/11/how-to-consume-an-odata-service-of-sap-netweaver-gateway-with-apache-olingo/

in the follow ing relative URI:“./ProductCollection(‘HT-1000’)/?$expand=Supplier”.

The client has only to append the $expand for this case and can then again parse the result
via EntityProvider.readEntry(...) . The difference now is that containsInlineEntry() is true and the
Supplier properties are available as ODataEntry w ithin the properties (i.e. Map ) of the Product. To visualize
the Map looks like:

Product (as ODataEntry)


\- *additional information like EntryMetadata*
\- *all simple properties*
\- Supplier (as ODataEntry)
\- *additional information like EntryMetadata*
\- *all simple properties*

The above shown readEntry(...) method could be used with minor adaption of URI creation, which now has
to include the name of the expanded navigation property.

String absolutUri = createUri(serviceUri, entitySetName, keyValue, expand);

All used URIs

Include Supplier for Product

Read more with Expand on a Feed

5 of 7 5/18/17, 9:15 PM
https://blogs.sap.com/2014/03/11/how-to-consume-an-odata-service-of-sap-netweaver-gateway-with-apache-olingo/

As mentioned in the section above the $expand can also be used to read a Feed so that then as example
each Product already includes the related Supplier. Also EntityProvider.readFeed(...) can be used for
deserialization and the only adaption in compare to normal read Feed use case is to append the $expand
system query option. For the sample use case the relative URI is“../ProductCollection/?$expand=Supplier”.

All used URIs

Include Supplier for each Product

Read less with Select


Each response usually contains all properties for an entry but this is not necessary for each client use case.
Hence, for a use case in that a client is only interested in some properties it is possible to define the system
query option $select to specify w hich properties of an Entry should be sent in the response payload. As
example w e only w ant the Name of each Product and the CompanyName of the related Supplier. Then w e
can use the $expand to include the Supplier in the response and define the $select system query option
w ith Name,Supplier/CompanyName w hich results in the relative URI “../ProductCollection
/?$select=Name,Supplier/CompanyName&$expand=Supplier”.

Again the EntityProvider.readFeed(...) method is used for deserialization and the only adaption in
comparison to the read Feed with expand use case is appending the $select system query option in
creation of the URI.

String absolutUri = createUri(serviceUri, entitySetName, keyValue, expand, select);

All used URIs

Include Supplier Name for each Product Name

6 of 7 5/18/17, 9:15 PM
https://blogs.sap.com/2014/03/11/how-to-consume-an-odata-service-of-sap-netweaver-gateway-with-apache-olingo/

Conclusion
In the sections above it was shown that with the support of Apache Olingo it is relatively easy for a client to
consume an OData Service. While the library takes care of serialization and deserialization of the OData
formatted entities the client can focus on processing the data.

Runnable sample client

A sample client exists for a quick Hands-On covering the here show n read use cases and in addition
containing the boiler plate code w hich is necessary for the URL connection handling (e.g.
Proxy/Authentication support).

To run this sample follow these steps:

Prerequisite: An installed JVM (Version 1.6 or above) and Maven (Version 3 or above).
Dow nload it here.
Extract it into some folder
Configure proxy and/or authentication in client.properties in folder src/main/resources (w ith
credentials provided via signing up)
Execute mvn compile exec:java to run Maven w hich compiles and executes the sample project.

Alert Moderator

7 of 7 5/18/17, 9:15 PM

You might also like