Troubleshooting with ILOData¶
Interactive Local OData (ILOData) is a command line utility that lets you execute OData requests, upload, and download against a local offline store.
The ILOData command line utility is shipped as part of the SAP SDK. In the SAP BTP SDK for Android, it is located in the tools\ilodata
folder of the installer.
The SAP BTP SDK for iOS also provides an optional way to install the tools using the iOS Assistant.
ILOData functions in the same way as an offline OData client, without the need for an application or device, enabling you to test data from the back-end service.
If an offline store exists, ILOData uses it. If not, ILOData performs a download to create the offline store. To perform a download, you must set defining_query
and service_root
. If no defining queries are specified on the command line and no offline store exists, you are prompted to enter defining queries before ILOData opens the offline store.
To use ILOData against an existing offline store, you must first retrieve the underlying offline store files from the device they were created on. Offline store files include two database files, prefixed with the store name (or the default name if no store name was specified when the offline store was created). One has a .rq
.udb
suffix and the other has a .udb
suffix. These files are located in the directory provided in the store_path
option, or in the application data directory by default if no store_path
has been provided.
Syntax¶
To view detailed help for the command line utility, use the -?
or --help
option.
ILOData.exe -?
ILOData.exe --help
The command line utility accepts parameters in the form of option=value
. The valid options are listed below.
ILOData.exe [option=<value> [option=<value> ...]]
Options¶
-
host
The host name of the mobile services server. -
port
The port of the mobile services server. -
appcid
The application client ID.Note
This is required by SAP Mobile Platform server and you DO NOT need to specify it for SAP Business Technology Platform server.
-
custom_cookie
A custom cookie to add to all HTTP communications. Use this option multiple times if you have more than one custom cookie to add. Custom cookies are added to HTTP requests between the offline store and mobile services and to HTTP requests between mobile services and the back-end OData service. For example,custom_cookie=name1:value1;
. -
custom_header
A custom header to add to all HTTP communications. Use this option multiple times if you have more than one custom header to add. Custom headers are added to HTTP requests between the offline store and SAP Mobile Services and to HTTP requests between mobile services and the back-end OData service. For example,custom_header=name1:value1;
. -
defining_query
An OData read request that targets the OData endpoint that is associated with the offline store and retrieves a subset of the data, either during initialization of the offline store or during a download. Multiple defining queries can be defined for each OData endpoint by specifying multipledefining_query
options on the command line. Defining queries become fixed for an offline store after the first time the store is opened.If no defining queries are provided on the command line, and no database files exist, ILOData prompts you to specify them. You can specify a name for the defining query (the name that would be used for a selective download and/or in an application configuration
.ini
file on the mobile services), as well as specify whether to download media streams. When the defining queries are specified using command line options, media streams are not downloaded by default, and the defining queries's names are the index at which they are specified. For example, in the following ILOData command, the first defining query would be named “1” and the second defining request would be named “2”.ILOData defining_query=Events defining_query=Sessions
-
enable_https
Whether to use HTTP or HTTPS to communicate with mobile services. The default isno
. -
enable_repeatable_reqs
Whether the back-end OData service supports repeatable requests. Repeatable requests (or idempotent requests) are a feature of some OData services that ensure OData requests are applied only once, even if they are received multiple times. This is useful in cases where OData responses may be lost due to intermittent network connectivity and is required by the offline store to guarantee that requests are applied exactly once to the back-end OData service. -
extra_stream_parms
Additional advanced stream parameters. -
identity_file
A file containing a client authentication certificate. -
identity_password
The password to use with the client authentication certificate. -
log_file
A file in which to log output. -
prompt
Override the default ILOData prompt. -
retry_download
The number of times to retry a download or store open when a failure occurs. The default is 0 (no retry). -
retry_wait
The amount of time, in milliseconds, to wait before retrying a download. The default is 100. -
service_root
The service root of the OData service. When the server is an instance of mobile services, this value depends on theRewrite Mode
configuration in the server-side application. IfRewrite Mode
is set toRewrite URL
, then this is the name of the application back-end connector. IfRewrite Mode
is set toRewrite URL on Back End
, then this is the path of the back-end OData endpoint. For example, if the application is configured with a connector namedmyconn
to an OData endpoint ofhttp://myhost:80/odata/endpoint
, then theservice_root
should bemyconn
forRewrite URL
andodata/endpoint
forRewrite URL on Back End
.Note
The mobile service does not provide the functionality to use
No Rewriting
mode to support external back ends for offline usage. -
store_key
The key that encrypts the local database. By default the database is not encrypted. -
store_name
An arbitrary name that identifies the offline store. If omitted, the default namelodata
is used. -
store_path
The file system path to store the offline store files. The default is the current directory. -
trusted_certificate
A file containing a trusted root certificate. -
url_suffix
The URL suffix path to the server. Specify the suffix to add to the URL of each HTTP request sent to the server. -
username
The user name to authenticate with the OData service. -
password
The password to authenticate with the OData service. -
enable_undo_local_creation
Specifies whether or not deleting an entity that was created locally but not yet uploaded undoes the creation. The default value isno
. -
enable_transaction_builder
Specifies whether or not to enable the transaction builder. The default value isno
. -
add defining query
Adds a new defining query.
Formats of Data Used with ILOData¶
-
null
|NULL
(case sensitive) -
binary
:0xhhhhhh
(hh
is a pair of hexadecimal digits) -
boolean
:true
|false
-
byte
,sbyte
,int16
,int32
,int64
:[0-9]*
-
datetime
:yyyy-mm-dd[T]hh:mm:ss.ssssss
(time portion is optional) -
datetime_offset
: likedatetime
plus timezone -
decimal
,double
,single
: normal numeric representation for type -
guid
:hhhhhhhh-hhhh-hhhh-hhhh-hhhhhhhhhhhh
(h
is hex digit) -
time
:PnYnMnWnDTnHnMn[.m]S
each component is optional
Commands¶
You can run commands in ILOData, or you can specify them on the command line, to run immediately on startup.
For example, command=get ~/T1
causes ILOData to exit immediately after executing the command.
Command | Option | Description |
---|---|---|
delete |
id_url |
Execute the given DELETE request. |
exit |
Quit ILOData. | |
upload |
Upload queued requests. | |
get |
[request] |
Execute the given GET request. |
help |
Print usage information. | |
patch |
id_url [prop=value] |
Execute the given PATCH request. id_url is a URL identifying an entity.1 |
patch |
link_url [id_url] |
Execute the given request to modify a link. link_url is a URL identifying a navigation property.1 id_url is n URL identifying an entity.1 |
post |
set_url [prop=value] |
Execute the given POST request.set_url is a URL identifying an entity set.1 POST requests support:
|
put |
id_url [prop=value] |
Execute the given PUT request.id_url is a URL identifying an entity.1 |
put |
link_url [id_url] |
Execute the given request to modify a link. link_url is a URL identifying a navigation property.1 id_url is a URL identifying an entity.1 |
download |
Perform a delta download. | |
register |
name id_url |
Register a media stream request. id_url is a URL identifying an entity.1 |
requestQueueIsEmpty |
Returns whether or not the request queue is empty. | |
set |
name=value |
Set an ILOData variable.pagesize variable The page size for server-driven paging. pagesize must be a 32-bit integer greater than 0. A special value for this variable is NO_PAGING, which means do not use server-driven paging. NO_PAGING is the default. |
unregister |
name |
Unregister a media stream request. |
Batch operations The important commands for executing batch operations are:
|
Each request within a change set is given an request number. The request number can be used as a Content-ID reference in later requests in the same change set. | |
send store |
[EncryptionKey ] |
Send the offline store to SAP Mobile Services server for diagnostic purpose. If the EncryptionKey option is not specified, then this command will send a decrypted store to the server. If Encryptionkey is specified, then the send store command will send an encrypted store to the server with EncryptionKey . For example send store 123 will send the offline store with encryption key "123" to the server. |
printDefiningQueries |
Print defining queries that have been added to the offline store. | |
printRequestQueue |
Print requests that are currently in the request queue. | |
undo |
id_url |
Undo pending changes made to an entity identified by id_url. For an existing entity downloaded from the back end, the entity will be restored to its original status. For a new entity created locally, the entity will be removed. |
1 All URLs must be properly encoded, particularly spaces and slashes. All values that contain spaces or tabs must be quoted with double quotes ("
). All other values can be, but aren't required to be, quoted with double quotes. Quoted values may contain \
, \xhh
and ""
escape sequences. Except when noted, values are case insensitive.
Getting Option Values for SAP Mobile Services Server¶
You need to provide a set of mandatory option values in order to access the server, including host
, port
, .ini
, service_root
, custom_header
and custom_cookie
(for the tenant node cookie). You also need to know the ID of the application to access.
host
: Consult your system administrator to get the host name. For example, a string likexxx-xxx.hanatrial.ondemand.com
.port
: Usually 443.enable_https
: Alwaysyes
for SAP Business Technology Platform.service_root
: Knowing the ID of the application to use, it is a string, such ashttps://host/application_id
.custom_header
: You must includeX-SMP-APPID
as a custom header in the form ofcustom_header=X-SMP-APPID:application_id
.custom_cookie
: Follow the steps below to get the tenant node cookie.- Log in to the SAP mobile service cockpit.
- Navigate to your application's details page, then switch to the "APIs" tab. Make a record of the URL for the "Server" API.
- Send a
GET
request using a REST client (such as Postman) to the URL you get in step #1 with a headerX-SMP-APPID
which value is the ID of the application. - If the request is successful, the response will contain a cookie. Make a record of the cookie name and value. The cookie name and value will be used in the
custom_cookie
option in the form of cookie_name:cookie_value.
Examples¶
Create a New Offline Store Using the SAP Business Technology Platform Server¶
Assuming your application requires no authentication (the application's Security Configuration
is None
) and the back-end OData service requires no authentication either (the application connectivity's SSO Mechanism
is No Authentication
), use the command below to access the server and open the offline store (replacing the xxx
parts with your own values):
ILOData host=xxx-xxx.hanatrial.ondemand.com port=443 enable_https=yes service_root=https://xxx-xxx.hanatrial.ondemand.com/xxx defining_query=xxx custom_header=X-SMP-APPID:xxx "custom_cookie=xxx:xxx"
Another common use case is that your application requires basic authentication (the application's Security Configuration
is Basic
). In this case you need to specify the user name and password for accessing SAP Business Technology Platform:
ILOData ... username=xxx password=xxx
In the command above, …
represents other options as shown in the previous example and you also need to replace the xxx
parts with your own values.
If your back-end OData service requires Basic Authentication
, you need to configure the user name and password in the application's destination to let SAP Business Technology Platform know how to authenticate with the back end.
Create a New Entity¶
ILOData> post MySampleCollection strProp="myvalue1" dateProp="2015-01-01 T12:00:00"
Query the Error Archive¶
ILOData> get ErrorArchive
Batch Operations¶
-
Batch operation #1:
ILOData > start batch ------------------------------------------------------------------------------------------------------- Batch Operation #1 > start change set ------------------------------------------------------------------------------------------------------- Change Set #1 Operation #1 > post Customers ID=3 GivenName="John" Surname="Doe" The operation was successfully added to the change set. ------------------------------------------------------------------------------------------------------ Change Set #1 Operation #2 > post $1/Orders ID=3 FinancialCode="r1" Region="Eastern" SalesRepresentative=299 OrderDate="2017-07-04T00:00:00.000" The operation was successfully added to the change set. ------------------------------------------------------------------------------------------------------- Change Set #1 Operation #3 > add change set The change set was successfully added to the batch.
-
Batch operation #2:
Batch Operation #2 > get Customers?$expand=Orders&$orderby=ID The query was successfully added to the batch.
-
Batch operation #3:
Batch Operation #3 > start change set ------------------------------------------------------------------------------------------------------- Change Set #2 Operation #1 > post Customers ID=4 GivenName="John" Surname="Doe" The operation was successfully added to the change set. ------------------------------------------------------------------------------------------------------- Change Set #2 Operation #2 > post $1/Orders ID=4 FinancialCode="r1" Region="Canada" SalesRepresentative=299 OrderDate="2017-07-04T12:00:00.000" The operation was successfully added to the change set. ------------------------------------------------------------------------------------------------------- Change Set #2 Operation #3 > post $2/OrderItems LineID=1 ProductID=1 Quantity=1 ShipDate="2017-07-04T13:00:00.000" The operation was successfully added to the change set. ------------------------------------------------------------------------------------------------------- Change Set #2 Operation #4 > add change set The change set was successfully added to the batch.
-
Batch operation #4:
Batch Operation #4 > get Customers?$expand=Orders/OrderItems&$orderby=ID The query was successfully added to the batch.
-
Batch operation #5:
Batch Operation #5 > execute batch
Deep Insert and Complex Type¶
-
This example performs a deep insert of a customer within a new order, then retrieves the new customer:
ILOData > post Orders Customer={ID=2 GivenName="John" Surname="Doe"} ID=2 FinancialCode="r1" Region="Eastern" SalesRepresentative=299 OrderDate="2017-07-04T00:00:00.000" HTTP 201: Created ------------------------------------------------------------------------------------------------------------------- ILOData > get Customers?$expand=Orders&$orderby=ID,Orders/ID HTTP 200: OK
-
This example illustrates how to work with complex types:
ILOData > post Customers ID=3 GivenName="John" Surname="Doe" Address={Street="445 Wes Graham Way" City="Waterloo" Country="Canada"} HTTP 201: Created ------------------------------------------------------------------------------------------------------------------ ILOData > upload Upload complete ------------------------------------------------------------------------------------------------------------------ ILOData > download Download complete
Bind Operations¶
The following example creates a new customer and binds it to two existing orders:
ILOData > post Customers ID=3 GivenName="John" Surname="Doe" Orders="Orders(3)" Orders="Orders(4)"
HTTP 201: Created
------------------------------------------------------------------------------------------------------------------
ILOData > upload
Upload complete
------------------------------------------------------------------------------------------------------------------
ILOData > download
Download complete
------------------------------------------------------------------------------------------------------------------
ILOData > get Customers?$expand=Orders&$orderby=ID,Orders/ID
HTTP 200: OK
Tip
- If you set the value of a navigation property to an object (for example,
Orders= {….}
) it is treated as a deep insert. - If you set the value of a navigation property to a URL (for example,
Orders=Customers(101)
), it is treated as a bind.
Event Log with Data Changed Flag¶
-
From the ILOData command line open a store with the parameter:
extra_stream_parms=_data_changed_by_download_flag;
-
Retrieve the
EventLog
with theget EventLog
command. -
If there have been any changes, or for the initial download, the log shows
"DataChanged": true
:{ "_metadata": { "uri": "EventLog(1L)", "type": "offlineOData.Event" }, "ID": "1", "Type": "download", "Time": "\/Date (1500988667440-240) \/", "Details": null, "DataChanged": true }
Note
Performing a download operation when no data has changed in the back end results in "DataChanged": false
in the EventLog
. DataChanged
is null
for other types of events, such as upload.