Using ILOData for Client Inspection

Objective

After completing this lesson, you will be able to explain Interactive Local Offline OData

Interactive Local Offline OData (ILOData)

Interactive Local Offline OData (ILOData) is a command-line tool that enables developers to inspect and modify the contents of offline OData databases. ILOData functions like an offline OData client, without the need for an application or device, enabling you to test data from the back-end system.

The Offline OData database consists of two files: one that ends with .rq.udb and another that ends with .udb. Both must be in the same location to open the database. These files always end in 'UDB' and are referred to as UDBs or UDB files.

The MDK creates UDBs during an Offline OData synchronization. They are stored in an application directory. They are accessed using iTunes on Windows and Finder on macOS; and Windows Explorer and Android File Transfer for iOS and Android platforms, respectively.

Note

Refer to SAP Note https://launchpad.support.sap.com/#/notes/0003041428

Getting Started with ILOData

ILOData binaries can be found in the SAP Business Technology Platform SDK for Android. When the SDK is downloaded, unzip it and navigate to tools/ILOData/bin, then use the appropriate binary executable. These are standalone executables. You can place them in any directory.

For the MAC OS, it is recommended that ILOData be copied to /usr/local/bin and be granted (chmod) 755 permission. This allows the user to simply type the binary into the terminal without knowing its actual location. For Windows, this can be done by copying the binary into the user’s AppData folder (Optionally it can be copied to other location, however, you need to update the PATH environment variable).

Using ILOData

The Offline OData database consists of two files: one that ends with .rq.udb and another that ends with .udb. To open the database, both must be in the same location.

The following are the prerequisites to use the ILOData:

  1. For Windows, the folder location of ILOData must be configured in User’s PATH environment variable (or alternatively it is stored in /usr/local/bin). For MAC OS the folder authorization must be modified via chmod settings.

  2. The two UDBs must be in the same folder and named DEST_SAM2005_PPROP_##.udb and DEST_SAM2005_PPROP_##.rq.udb.

On Windows, execute the following command:

Code Snippet
1
ILOData store_name=DEST_SAM2005_PPROP_##

On MAC OS, if the binary is located in the same directory as the UDBs, use the following:

Code Snippet
1
./ILOData store_name=DEST_SAM2005_PPROP_##

Note

The extension is omitted from the store_name parameter.

Once the command prompt is launch, at prompt ILOData >, you can issue standard HTTP commands to the database such as GET, POST, PATCH, and DELETE as if it were an HTTP OData service. The following are some examples of ILOData CRUD (Create, Read, Update, and Delete).

Fetching (GET) Data

Arguably, one of the most important functions of ILOData is getting data from a UDB. It enables developers to verify that transactions on a client happen as designed.

Here are some examples of the OData Queries you can execute through the ILOData prompt:

OData Queries Executed through the ILOData Prompt

GET MyWorkOrderHeaders

This command returns a list of work order records in JSON format. The list returns data as an array of objects.

GET MyWorkOrderHeaders(‘400003’)

This command returns data of a single work order 40003 as a JSON object.

GET MyWorkOrderHeaders(‘400003’)/Equipment

Using the Navigation link, you can fetch the Equipment data of a work order header.

Either a single record of type MyEquipments is returned or code 204 no data displays.

Note

Other OData queries are also possible using GET. However, it is beyond the scope of this discussion. For more information on OData syntax and usage, visit: https://www.odata.org/documentation/odata-version-2-0/uri-conventions/.

Creating Data

Sometimes, it is helpful to inject new data into a UDB, either for the purposes of testing. You can do this through a POST. Standard HTTP POST requests often contain a payload in addition to a URI. ILOData handles this by treating any key-value pairs after the initial URI request as part of that payload.

New Data Injected by a Post request

POST MyNotificationHeaders

Use the command to create a new notification record with no data in ILOData.

ILOData returns the new record in JSON format. Notice that all the fields are initially set to null.

POST MyNotificationHeaders Priority=2 MainWorkCenterPlant=1000 NotificationDescription="Test Notification"

Use POST with parameters to create a new notification record with some populated fields.

In both cases, the key field, NotificationNumber, is left empty. ILOData can accept empty key fields. Sometimes, because of back-end business logic, it must accept empty fields. Locally created records can be accessed through GET, PATCH, or DELETE using the returned record read link.

MyNotificationHeaders(lodata_sys_eid=X'FF3DF2D0F3A146F3A15DB11D3B27873000000000')

The read link can have something.

MyNotificationHeaders(‘10000025’)

However, Normally, the read link uses specific Notification Number.

Updating Data

Altering records is similar to creating new records. The HTTP verb for altering records is PATCH. Similar to POST, PATCH has an associated payload. In this instance, the payload contains key-value pairs of the properties to be changed on a given entity.

Using Patch for update

PATCH MyNotificationHeaders(‘10000035’) Priority=3 NotificationType=M1

Use PATCH to change properties for an existing entity.

MyNotificationHeaders(lodata_sys_eid=%3DX'FF3DF2D0F3A146F3A15DB11D3B27873000000000') Priority=3 NotificationType=M1

The process is similar for unsynchronized entity.

Notice that the ‘=’ sign is replaced with ‘%3D’ ILOData only accepts URL-encoded special characters for POST, PATCH, and DELETE. This does not apply to GET.

Deleting Data

HTTP DELETE does not carry a payload and is similar to GET.

Usage of HTTP DELETE

DELETE MyNotificationHeaders(‘10000035’)

Use DELETE for deleting entity in ILOData.

Ilodata can only delete one entity at a time. DELETE requests cannot be used with filter queries.

SAP Offline OData-Specific Extensions

Offline OData, by definition, is not always in sync with the back end. Several annotations and queries exist to deal with locally created and locally modified entities. There are also several built-in query options that enable more efficient queries when dealing with unknown links.

Using Exercise 4 above as an example, create a new Notification. Then run the following query: GET MyNotificationHeaders?$filter=sap.islocal()

The result of this is at least one entity that is created in the database but has not yet synced with a back end. There are also two new properties:

  • @com.sap.vocabularies.Offline.v1.isLocal

  • @com.sap.vocabularies.Offline.v1.hasPendingChanges

These properties do not persist. They only indicate that the entity has changed and has not yet been synced.

Offline OData also has a property-checking filter. You can use this to determine if a navigation link exists and has data, or if a property is non-null. For example, GET MyNotificationHeaders?$filter=sap.entityexists(Priority).

In a standard use case, all notifications must have a priority. However, if a notification has no priority, the preceding query omits it from the returned results. Similarly, GET MyWorkOrderHeaders?$filter=sap.entityexists(Operations) returns all work orders with at least one operation.

SAP Offline OData also supports lambda expressions any and all. These are filter queries that enable a user to "drill into" a one-to-many relationship. Effectively, the queries work similar to for() loops in most modern languages. For example: GET MyNotificationHeaders?$filter=Items/any(it : sap.entityexists(it/ItemTasks)). This finds all notifications with at least one item with an item task. In this example, it is analogous to the iterator in a traditional for() loop. The portion after the colon is the condition that is checked given the variable it.

The all operator is the logical set-inverse of any. It checks to see if all items under a notification have item tasks. However, this is the inverse set, and so this operator also returns notifications with no Items. This can be countered by adding an additional parameter: GET MyNotificationHeaders?$filter=Items/any(it : sap.entityexists(it/ItemTasks)) and sap.entityexists(Items)

Another common use of any is to check for entities in a collection containing a specific property. For example, GET MyEquipments?$filter=Partners/any(p : p/PersonnelNum eq '00000022'). This returns any equipment that has a partner with a personnel number of 22. In this case p is similar to an iterator checking the partners on given equipment.

Log in to track your progress & complete quizzes