Skip to content

Defining an Application Configuration File

Creating and Importing Application Configuration File

When non-default behaviors are expected, you need to define offline application settings in an application configuration file, and configure the mobile services based on those settings.

  1. Create an application configuration (.ini) file (Application Configuration File) that includes the defining queries and other application-specific information.

  2. Send the application configuration file to an administrator of the mobile services.

    The administrator imports the .ini file and configures various offline settings that support the offline application. See Defining Applications and Defining Offline Application Settings in the cockpit online help.

Defining Queries

A defining query is a read query that targets the OData service associated with the offline store and retrieves a subset of the endpoint data. You can define multiple defining queries for each endpoint.

Defining queries retrieve data from the OData service that is sent to the client, either during initialization of the offline store or during a download.

Defining queries are set up in both the application source code and in the application configuration files. In the source code, use the addDefiningQuery method from the OfflineODataProvider class with a name and a query. The example below demonstrates how the defining queries retrieve all information for one event.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
// Expand is needed to create a many-to-many relationship between Event and Feature
// since there is no referential constraint defined on the relationship.
// Data sharing should be enabled as all users see the same information
offlineODataProvider.addDefiningQuery(
    new OfflineODataDefiningQuery("Events_10000", 
                                  "/Events?$filter=EventID eq 10000L&$expand=Features", 
                                  false));
// One-to-many relationship between Event and Session is built via
// referential constraint. Data sharing should be enabled
offlineODataProvider.addDefiningQuery(
    new OfflineODataDefiningQuery("Sessions_10000", 
                                  "/Sessions?$filter=EventID eq 10000L", 
                                  false));
// Data sharing should be enabled
offlineODataProvider.addDefiningQuery(
    new OfflineODataDefiningQuery("Tracks_10000", 
                                  "/Tracks?$filter=EventID eq 10000L", 
                                  false));
// User Specific data; data sharing should be off
offlineODataProvider.addDefiningQuery(
    new OfflineODataDefiningQuery("UserSessionAgendas", 
                                  "/UserSessionAgendas?$filter=EventID eq 10000L", 
                                  false));
// Data sharing should be enabled.
offlineODataProvider.addDefiningQuery(
    new OfflineODataDefiningQuery("Features", 
                                  "/Features", 
                                  false));

In the application configuration file, reference each query using the same name as the one written in the source code (the first parameter to the OfflineODataDefiningQuery constructor), as shown in the following example:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
[defining_query]
name=Events_10000
is_shared_data=Y
download_interval=10
track_deltas=AUTO
delta_token_lifetime=36000

[defining_query]
name=UserSessionsAgendas
is_shared_data=N
...

In the example, the defining query Events_10000 is declared as sharable, which means that the event and related features can be accessed by all users.

Usually, you'll specify defining queries before the opening offline store for the first time, but they can also be added afterwards if appropriate.

Keep the following in mind when writing defining queries:

  • Currently, only defining queries where the resource path identifies an entity set or entity type instance (a single entity) are supported.

  • Shared defining query names must be unique, and must be identical on both the client and server. Otherwise, expected settings will not be applied to the correct defining query and the query will be using the default settings instead.

  • If you are using a mix of delta enabled and non-delta enabled defining queries, and you are using referential constraints to build relationships, the dependent entity in a relationship cannot be in a delta enabled defining query if the principal entity is in a non-delta enabled relationship. For example, say you have two defining queries, Events and Sessions (based on the sample metadata). Since there is a referential constraint between them and no expands are specified, the mobile services automatically use the referential constraints to build relationships. The events are the principal entities and the sessions are the dependent entities. If the Events defining query is not delta enabled, then the Sessions defining query must not be delta enabled. However, if the Events defining query is delta enabled, the Sessions defining query may or may not be delta enabled.

  • If you are not using deltas, you can use the same entity sets in more than one defining query, but you cannot perform a selective download of one of those defining queries without the others.

  • If you are using a mix of delta enabled and non-delta enabled defining queries, you cannot use the same entity set in both a delta enabled and a non-delta enabled defining query, either directly referenced in the resource path or through an $expand.

Using Defining Queries to Build Entity Relationships

To build relationships in your application, you can use $expand in queries, referential constraints, or a combination of the two.

  • $expand in queries

    Use $expand in queries to build relationships between entity sets only if you are not tracking deltas, or if you are tracking deltas using the mobile services. You cannot use $expand in queries if you are tracking deltas using the OData service.

  • Referential constraints

    If you are tracking deltas using the OData service and require entity relationships in the offline store, you cannot use $expand in queries but instead must have associations with referential constraints. Ensure that each defining query references a single entity set. The mobile services detect the associations with referential constraints and use the constraints to build the relationships between the entity sets selected in your defining queries.

    For example, the sample metadata document has an association between Event and Session, called Event_Session_One_Many0, which defines a referential constraint. If you specify two defining queries, /Events and /Sessions, the server uses the referential constraint defined in the association Event_Session_One_Many0 to build the relationship between the Events and Sessions entity sets in the offline store.

  • Combining referential constraints and $expand in queries

    When you use an $expand to build relationships between two top-level entity sets, an association set is implicitly referenced. For example, /Events?$expand=Sessions implicitly references the Event_Session_One_Many0Set association set. The mobile services allow you to mix referential constraints and $expand to build relationships.

    Consider the following example, which uses entity sets from the sample metadata:

1
2
 ~/Events?$expand=Sessions
 ~/Tracks

Relationships between events and sessions are computed using $expand and relationships between events and track are computed using referential constraints.

However, you cannot mix referential constraints and $expand for the same implicitly referenced association set. In the example below, relationships between events in Canada and their sessions are built using $expand, where the Event_Session_One_Many0Set association set is implicitly referenced. Although there is an association Event_Session_One_Many0 with referential constraint between the Event and Session entity type, the referential constraint will not be used by the second and the third defining query to build other relationships since the referential constraint also implicitly references the same association set. As a result, relationships between events in the US and their sessions are not built. Hence, only for events in Canada one can use the Sessions navigation property to get associated sessions. For events in the US, one must use the EventID property in a filter to get the associated sessions.

1
2
3
4
    ~/Events?$expand=Sessions&$filter=Country eq 'CAN'
    ~/Events?$filter=Country eq 'US'
    ~/Sessions
    ~/Tracks

Note

This is not an exhaustive list of ways to build relationships. The choice of defining queries is highly dependent on the needs of the offline application.

The table below lists parameters that can be used to configure defining queries in an application configuration file.

Parameter Value Notes
name Valid String (Required) Name of the defining query.endpoint data.
is_shared_data N or Y Whether the data is shared among different clients or users.
  • N Some data is not shared among multiple client databases.
  • Y Data is shared among multiple client databases.

The default value is N.

refresh_interval NNN The interval time, in minutes, between downloads of the shared data.

The default is 15 minutes.

track_deltas AUTO or ALWAYS or NEVER How to track OData deltas.
  • AUTO If the OData service supports delta change tracking on the defining query, the delta links returned are used when downloading the data. If the OData service does not support delta change tracking on the defining query, the mobile service tracks the changes so that only changed data is exchanged between the client and the mobile services.
  • NEVER Sets the mobile services to never track delta changes. If the OData service supports delta change tracking, the delta links returned by the OData service are used when downloading data, even if this option is specified.
  • ALWAYS Sets the mobile services to always track delta changes. This option is equivalent to AUTO if the OData service does not support delta change tracking on the defining query.

The default value is AUTO.

delta_token_lifetime NNN The time, in minutes, until the OData delta token expires. While a token is valid, only changed data is downloaded to the offline store. When the delta token expires, the entire data set is replaced.

The default is 72000 minutes (50 days).

Performance Improvement with Delta Tracking and Caching

You can use delta change tracking (short as delta tracking) and data caching to significantly improve the performance of the mobile services.

Delta Tracking

OData delta tracking is a method by which a client obtains changes from an OData service without downloading the entire data set. Set up the track_deltas parameter in your application configuration file to track deltas when you configure your defining queries. If your OData service supports the delta query protocol to track changes, the provided delta links automatically track changes and you don't need to configure delta tracking. When possible, use an OData service that supports delta query protocol.

Delta tracking sends only changed data to the client, rather than the entire data set. This significantly decreases the load on the back end and is especially useful when performance is critical.

  • If your OData service does not support delta tracking, the default delta tracking setting in the application configuration file tracks deltas using the mobile services. This improves performance on the client, while tracking deltas using the OData service improves performance over the entire network.

  • If your OData service has limited support for delta tracking, for example, deltas expire after a set period of time, using the ALWAYS setting for delta tracking in the application configuration file helps fill the missing delta tracking functionality.

If all or most of your data is continuously changing so that you expect to be downloading the full data set during every download, enabling delta change tracking does not improve performance. For example, if you download the temperature value for sensors in 1000 offices, using delta tracking does not decrease the amount of data downloaded during a download and turning off delta tracking may increase performance.

Caching

To minimize the load on the OData service and possibly improve performance, cache data that is shared by numerous users on the mobile services. For example, cache data from a query that returns the same results to multiple users. Do not cache data from a query that returns different results to each user. Set up the is_shared_data parameter to cache data when you configure your defining queries in your application configuration file.

Application Configuration File

Use the application configuration file to configure OData endpoints and defining queries that determine the data that populates the client database (the offline store) when it is created. Use the cockpit to import the application configuration file.

An application configuration file consists of one or more OData endpoints, each of which can be optionally followed by one or more defining queries.

Each application configuration file represents a single application. All settings have default values, so an application configuration file is required only for non-default behaviors.

An endpoint is defined as follows:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
[endpoint]
name=YourConnectionName
prepopulate_offline_db=Y|N|SHARED-ONLY
prepopulate_offline_db_interval=NNN
indexed_type=<namespace>.<entity type name1>: Property1A [ASC|DESC][, Property1B [ASC|DESC], ]
indexed_type=<namespace>.<entity type name2>: Property2A [ASC|DESC][, Property2B [ASC|DESC], ]
defining_query_format=application/json;q=1,application/atom+xml;q=0.5
delta_query_format=application/atom+xml
offline_db_collation=UTF8BIN
case_sensitive_offline_db=Y|N
json_datetimeoffset_in_utc=Y|N
local_change_expiry=NNN
allow_omitting_max_length_facet=Y|N
content_id_header_location=mime|operation
max_delta_resends=NNN

The table below lists parameters that can be used to configure endpoints in an application configuration file.

Parameter Value Notes
name Valid String (Required) The name of the endpoint, which is the same as Connection Name in the cockpit.
prepopulate_offline_db Y or N or SHARED-ONLY The type of data that is included in the initial database.
  • Y Shared and unshared data is included in the initial database when it is created on the server. The fully populated database, as defined by the defining queries, is deployed to the client.
  • N Creates an empty database with only a schema. The database obtains data when it's automatically refreshed after it is deployed to the client.
  • SHARED-ONLY The database includes only shared data and no user-specific data. User-specific data is obtained when the database is refreshed automatically after it is deployed to the client

The default value is Y.

prepopulate_offline_db_interval NNN If a download requires a new database, the shared data is refreshed based on the interval specified, in minutes. This option applies only when prepopulate_offline_db is set to Y or SHARED-ONLY and there is at least one defining query with is_shared_data=Y.

The default is 1440 minutes (one day).

indexed_type .: PropertyName [ASC or DESC][, AnotherPropertyName [ASC or DESC], …] The left-side value is the entity type name and the right-side value is a comma-delimited list of properties, each of which can optionally be suffixed with ASC or DESC. Each indexed_type creates an index on the client database. Defining indexes can improve client query performance. However, defining too many indexes can slow the performance of downloads and updates. Specify multiple indexed_type entries by listing one entry per line.

Specify either the primitive property name, or a complex type path expression that ends with a primitive property.

    For example:
    indexed_type=SAPODataExample.CustomerType:Surname,GivenName
    indexed_type=SAPODataExample.CustomerType:Address/Province,Address/City

Tip:

  • indexed_type entries are for new registrations; changing the setting does not create or re-create indexes. However, deleting the application from the client has the same effect as deleting the registration.
  • in the mobile services debug logs, lines that start with “Ignoring index creation” indicate that something is misconfigured.
defining_query_format atom or json or any valid value The format to use when communicating with the OData service. This property applies only when the offline store is making initial requests or non-delta requests to the OData service.
  • atom application/atom+xml.
  • json application/json.
  • any valid value Any valid value for an Accept Header.

The default is application/json;q=1,application/atom+xml;q=0.5.

delta_query_format atom or json or any valid value The format to use when communicating with the OData service. This property applies only when the offline store is making delta requests to the OData service.
  • atom application/atom+xml.
  • json application/json.
  • any valid value Any valid value for an Accept Header.

The default is application/atom+xml.

offline_db_collation Any collation supported by UltraLite The collation for the database.

The default is UTF8BIN.

case_sensitive_offline_db Y or N Whether the database is case sensitive.

The default value is Y.

json_datetimeoffset_in_utc Y or N Whether the OData service specifies or accepts the ticks portion of a JSON-formatted Edm.DateTimeOffset in UTC or in the timezone specified by the offset portion.
  • Y The OData service accepts the ticks portion of a JSON formatted Edm.DateTimeOffset in UTC.
  • N The OData service accepts the ticks portion of a JSON formatted Edm.DateTimeOffset in the time zone that is specified in the offset portion.

The default value is Y.

local_change_expiry NNN In some cases, local changes may remain in the offline store after it has been uploaded to the back end. To prevent this, specify a life span, in hours, for local data. When this option is omitted from the configuration file, local changes never expire.
  • Negative value Local changes never expire.
  • Zero Local changes expire during the next download.
  • Positive value Local changes expire during the first download after the specified number of hours have passed.
allow_omitting_max_length_facet Y or N When enabled, allows default MaxLength values for Edm.String and Edm.Binary key properties to be assigned by the system when none are provided. Any indexable properties (key or referential constraint) that are missing the MaxLength facet are treated as though they have a MaxLength of 1536 bytes.
  • Y The system assigns default MaxLength values when they are not provided in the OData metadata.
  • N The system does not assign default MaxLength values so they must be provided in the OData metadata.

The default value is N.

Note: This feature is intended only for development purposes as it does not provide fine-tuned control over the values chosen. In a production environment, ensure MaxLength facets for Edm.String and Edm.Binary key properties are included in the OData metadata.

content_id_header_location mime or operation In a batch request, the header section of the OData change set to put the ContentID header.
  • mime The ContentID header is included in the mime header section of the OData change set.
  • operation The ContentID header is included in the operation header section of the OData change set. Use this option when the back end does not allow the ContentID header to be in the mime header section.

The default value is mime.

max_delta_resends NNN When multiple defining queries are delta enabled, the delta requests are automatically sent to the back end repeatedly until all delta responses are empty, to ensure data consistency. Use this option to configure the number of times a delta link is sent during a download.

The default value is 5.

batch_all_defining_queries Y or N If Y, all defining queries under the endpoint are sent in one batch operation.

The default is N.

refresh_in_order Y or N Whether to download data in the order in which the defining queries appear in the configuration file. If Y, the defining queries are executed in the order in which they are defined in the configuration file.

The default value is N.

check_repeatable_requests Y or N To enable repeatable requests, set:

[endpoint]
name=myEndpoint
check_repeatable_requests=Y

If using an OData service that supports repeatable requests (such as Netweaver gateway), you do not need to enable check_repeatable_requests. When implemented in the OData service, protection is provided from all comunication errors. Whereas if you enable check_repeatable_requests, you are only protected against communication errors between the client and the mobile services. Communication errors between the mobile services to the OData service can still lead to issues. However if you are using an OData service without repeatable requests enabled you must enable check_repeatable_requests. See Repeatable Requests for additional details.

The default value is N.

repeatable_requests_lifetime NNN Repeatable requests require space in your database tenant to track which requests have received responses. Set repeatable_requests_lifetime to control how long, in minutes, responses are saved.

The default value is 72000 (50 days). This setting needs to be large enough to handle devices that sit idle for some time.

For example, if a communication error occurs at the end of a Friday, you'd want to keep the saved responses until at least the following Monday (3 days). For example:

[endpoint]
name=myEndpoint
check_repeatable_requests=Y
repeatable_requests_lifetime=4320

When batch_all_defining_requests=N, multiple defining queries can be grouped into one batch request as instructed in a [defining_query_group] section. For example:

1
2
3
4
[defining_query_group]
defining_queries=req1,req2,req3
[defining_query_group]
defining_queries=req4,req5,req6
Parameter Value Notes
defining_queries Comma-separated list of definined queries names Defining queries that are specified in the same defining_query_group are sent in one batch request.
  • When defining_query_group is defined, you cannot set batch_all_defining_requests to Y.
  • If batch_all_defining_queries is set to Y, then all the defining queries are executed in a batch.
  • Defining queries not belonging to any group are executed individually if batch_all_defining_requests is set to N.