4.5 Technical solution description
4.5.3 Oine design and architecture
This subsection outlines the main architectural and design choices that makes up the application oine strategy.
4WebDAV allows clients to perform remote web content authoring operations.
5This example has been elaborated with the contribution of Nicola Fankhauser.
6The version of the SAP system used is SAP NetWeaver 2004s, Basis.release 7.00.
METHOD / r e s t / u s e r I n f o ~do_read .
2
DATA :
4 l_username TYPE bapibname−bapibname , " username
l s _ a d d r e s s TYPE bapiaddr3 , " s t r u c t u r e w i t h address data
6 l t _ b a p i r e t TYPE TABLE OF b a p i r e t 2 , " r e t u r n t a b l e o f BAPI f u n c t i o n module l s _ b a p i r e t LIKE LINE OF l t _ b a p i r e t .
8
∗ Get username from c l a s s a t t r i b u t e
10 l_username = username .
12 I F l_username IS I N I T I A L . RAISE EXCEPTION . . .
14 . . . ENDIF .
16
∗ R e t r i e v e user d e t a i l s
18 CALL FUNCTION ’ BAPI_USER_GET_DETAIL ’
EXPORTING
20 username = l_username
IMPORTING
22 address = l s _ a d d r e s s
TABLES
24 r e t u r n = l t _ b a p i r e t .
26 ∗ Handling p o s s i b l e e x c e p t i o n s r a i s e d w h i l e r e t r i e v i n g user d e t a i l s . . .
28
e_response = l s _ a d d r e s s .
30
ENDMETHOD.
Listing 4.2: ABAPimplementation of the do_read()method of the userInfo REST service
{ . . . , " f i r s t n a m e " : " Fabien " , " lastname " : " Ropraz " , " birth_name " : " " , . . . , " f u n c t i o n " : " I n f o r m a t i k e r "
, . . . , " c i t y " : " Sorens " , " d i s t r i c t " : " " . . . }
Listing 4.3: Excerpt of the userinfo REST service response
4.5. Technical solution description 86
Figure 4.7: Activity diagram for HTTP request processing on the server
Connection strategy
Only parts of the numerous features provided by the backend system are made available in the oine client, as this application represents a particular use case of the system, where only a reduced set of functionality is required. It has been clearly specied with
Figure 4.8: Example of a URI used to get the details of a particular user
Figure 4.9: Customizing table entry for the userinfo service
the customer which features should be implemented in the client application. In this project, since a separate oine-enabled web application is created specially for oine use, all features available when using the oine client online are also available when using it oine. Thus, no function is deactivated when going oine, since the application only implements features that are intended to be used oine.
Application modality
The oine client is designed in a modal style, i.e. the user is aware of the application connection state and manually toggles between the connection modes via a button on the user interface (see Subsection 3.6.2). However, the oine client presents some par-ticularities rather atypical for a modal application. The application always uses the local store even while online and in addition to syncing when switching between the connection modes, the application also attempts to sync data between the local store and the server
4.5. Technical solution description 88 at regular intervals in the background while online. This allows the local store to be kept up to date while working online.
Gears modules used
The LocalServer, Database and Desktop Gears modules are used in the client application in a way that is described in more details in the following paragraphs.
• LocalServer
The oine client uses a ManagedResourceStore to capture application resources declared in a manifest le, which allows the application to be run oine. During application initialization, thecheckForUpdate()method is called to capture the initial version of the application. Gears takes then over the responsibility of automatically initiating updates to the store. Subsection 3.3.1 provides more information on the topic.
• Database
The Gears local database required to persist data locally is lled with two kinds of tables:
1. Business data tables
Business data tables represent business objects fetched from the server, such as customers. These tables store business data, which are relevant for data syn-chronisation, as they are also persisted on the server. To generate these tables locally, the client application needs to retrieve the description of the REST services interfacing with the business objects on the server. This is done by sending a request to the corresponding resource using theHTTP PROPFIND method. The tables can then be created during the rst application initializa-tion according to the business object data structure returned by these calls.
2. Support data tables
Support data tables do not have a server counterpart because they are des-tined to store data used to support the application oine operation and the synchronization process. Thus, this data is not getting synchronized with the server. Following support data tables (represented in Figure 4.10) are needed by the oine client:
the ActionLog table, used to store all local operations on data, so that they can be replayed on the server during synchronization;
the SyncHistorytable, which keeps a history of all executed synchronization steps in order to know when the last sync for a particular business object took place, or whether a sync has already been kicked o for that object;
the IdMappingtable, which establishes a mapping between local unique IDs and server unique IDs for sync purposes, as locally created data are not attached to a GUID until the next sync;
the StateProvider table, used to store initialization, state or other kinds of parameter necessary to properly use the application oine and retrieve its state in case of oine startup;
the PropfindCache table, which stores the REST service description and metadata, needed to generate the local business object tables;
theSchemaInfotable (automatically generated), which contains the current local database schema.
Figure 4.10: Support data tables schema
Despite its benets, the SQL-based local data store raises the issue of managing the database versions. If developers update the oine-enabled web application according to a newly updated database schema, it will cause inconsistencies and errors when running the application on the client-side, as already existing local database tables are usually not re-created during application initialization. In order to avoid keeping track of what version of the database is on the client, the oine client makes use of a migration mechanism for Gears called Gearshift [25]. This JavaScript script allows the denition of rules representing the version history and to which the application can migrate, up or down. Once the rules have been dened, developers can call the Gearshift init() method, which takes two arguments: the Gears database and a boolean that dictates the auto migrate functionality. If set to true, the application will automatically be taken up to the latest rule, thus ensuring that all intermediate modications of the database structure are taken into account to keep the local database consistent with new versions of the web application.
Gearshift also provides the whatIsMyVersion(), latestVersion() and migrateTo() functions to manually control the migration. As an example, Listing4.4gives the content of a JavaScript le dening two rules, one for creating the table and one for updating its structure. Listing 4.5 shows then how to use the Gearshiftinit() method to execute these rules up to the latest.
• Desktop
The oine client makes use of the Desktop module to create a shortcut of the ap-plication when it is rst initialized. This makes it easy for the user to quickly access the oine client even when the network is not available. The desktop icon is created by calling the Gears DesktopcreateShortcut()method, like shown in Listing 4.6. The inconvenience with this method is that each time it is called, it causes the Gears permission prompt to appear (see Figure 4.11), even if the icon already exists. In other words, each time the application gets started, users get bothered over and over by this permission prompt. To avoid this and since Gears does not provide a way to query whether a desktop shortcut has been created before, i.e whether the permission was granted or not, the client application uses the StateProvider ta-ble to store that the user was given the option to create a desktop icon. Thus, if
4.5. Technical solution description 90
G e a r s h i f t . r u l e s [ 1 ] = {
2 / / c r e a t e t h e demo t a b l e up : f u n c t i o n ( ) {
4 r e t u r n t h i s. e ( "CREATE TABLE demo_table ( i d INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR ( 3 0 ) , movie VARCHAR( 3 0 ) ) " ) . success ;
Listing 4.5: Gearshift initialization with auto migration
the stored value indicates that the permission prompt has already been displayed, the application will not prompt the user again at the next startups. In case users deleted the icon and want to create it again or changed their mind and want to grant permission, the application provides a setting button that calls the createShortcut()
method when pressed, which displays again the permission prompt.
Overall strategy and logic
The oine-enabled application operates as follows:
• Application initialization
At startup, the application enters the initialization phase, which aims at making all server data available to the client application for oine use. To achieve this goal, the initialization process goes through several steps, as depicted in Figure 4.12. First, the application instantiates the Gears objects, including the ManagedResourceStore
c r e a t e S h o r t c u t : f u n c t i o n ( appURL , i c o n P a t h s ) {
Listing 4.6: Calling the Gears Desktop createShortcut()method
Figure 4.11: Gears permission prompt for creating application shortcuts
and the local Database. The Gearshift init() method is called to create all support data tables. Then, the support data classes such as the ActionLog, the SyncHistory
and the IdMapping classes as well as all the business object classes are initialized.
For each business object, it is checked whether its metadata is already stored in the PropfindCachetable. If it cannot be found there, the metadata is requested from the server using the HTTP PROPFIND method and persisted in the table. Once the metadata can be retrieved from the table, the object properties of the service class corresponding to the business object are lled with this metadata. In case the business object table has not been created yet, the metadata is converted into an SQL CREATE instruction to generate the local table. Next, the application issues a request to fetch the dierent events, each of which groups together a set of data of the various business objects. Upon receiving this event data, the application generatesLUIDs to map theGUIDs, stores them in the IdMappingtable and lls the business objectEventstable with the event data. At this stage, a window displaying all the events is prompted to the users, so that they can select an event, based on which data the application will be loaded. Once the users have selected one, the application sets and persists theGUIDof this event and requests all corresponding business object data from the server. When the data is returned,LUIDs are assigned to them and theIdMappingtable is completed. The properties of the business object classes are lled with this data, according to which the GUI is nally initialized.
From this point on, all business objects data belonging to the selected event are stored in the local database and are thus available oine.
It should be noted that the initialization process gets completely modied and largely shortened when the application is launched after being closed in oine mode.
By querying the persisted connection state, the application knows if it should be started in online or oine mode. In the latter case, the oine client does not retrieve any data from the server nor displays the event window, but simply instantiates the classes and the GUI.
4.5. Technical solution description 92
Figure 4.12: Oine client initialization process
• Online use
Even when the application is in online mode and the network is available, operations on data are still recorded locally using the local data store. A synchronization process is started at regular intervals in the background to fetch the server changes and upload the local changes to keep both databases updated. The synchronization and the conict resolution strategies are thoroughly described in the next paragraph.
• Going oine
When the user switches to the oine mode, a complete synchronization process is kicked o, whereby server data changes are fetched and any local data changed or created since the last sync is uploaded on the server. If the synchronization fails because the network has already been lost or for other reasons, the client application will still work oine, as application data and resources have been fetched during application initialization. The application or the local store may be simply not completely up to date. The synchronization and the conict resolution strategies are described in more details in the next paragraph. Obviously, data manipulations aect the local data store while oine and no synchronization process takes place.
• Going back online
When the user switches back to the online mode, the synchronization process is kicked o again.
Syncing strategy
As data can be edited while oine and shared amongst mutliple users, the syncing sce-nario implemented in the oine client considers the local store as a read/write cache for multiple users but without automatic merging (see Subsection 3.6.4). Thus, in case of conicts during synchronization, the application does not attempt to do automatic conict resolution and merging. Instead, it resolves conicts with a specic strategy that consists by default in keeping and storing both versions of the conicted item. As it has already been mentioned, the application maintains an action log, which keeps track of the local actions performed on data by the user and which gets replayed on the server during synchronization.
The oine client makes use of both general types of sync strategies, i.e. manual sync and background sync (see Subsection 3.6.4). Indeed, while online, the application uses background sync to regularly attempt to synchronize data between the local store and the server database, whereas the sync process is manually triggered when the user moves into the oine or online mode.
The synchronization process implemented in the oine client implies iterating over each business object and calling the syncObjectType() sync method on each one. This method encapsulates the sync logic, which is broken down into several steps as depicted in Fig-ure 4.13 (elaborated by Nicola Fankhauser).
The method starts by writing PRESYNC_START in the SyncHistory table for the cor-responding business object. Next, it retrieves all entries in the ActionLog table related to the business object and groups them by LUID, i.e. by data record. After getting the timestamp of the last business object sync from theSyncHistorytable, the method issues a request to the server to retrieve all modied and new entries related to the business object that have been recorded since the last sync. Once returned, the server changes are pro-cessed and analyzed to detect and resolve possible conicts and adapt the local store and the action log accordingly. Logically, a conict arises each time a record among the server changes is also referenced in the action log, as this means that the same record has been modied both on the server and on the client. In such case, CONFLICT_DETECT is written in the SyncHistory table and the following is performed:
• if both changes correspond to a delete action, then the local action is removed from the action log, so that the record does not get deleted twice when replaying the action log on the server;
• if the record has been deleted locally but updated on the server, it gets created again on the client-side without the action being recorded in the action log obviously;
• if both changes correspond to updates, both of them should be maintained, which is done by storing the updated server record locally and adding it to the action log so that it will be kept as such on the server. This case may be rened in future versions of the oine client.
If there is no trace of the record in the action log, it means that no change has been performed on this record locally. Therefore, no conict is generated and the change that took place on the server is applied on the local store without aecting the action log.
Once each server change has been processed, the updated action log is retrieved again and PRESYNC_END is written in theSyncHistorytable. Before uploading the changes, the action log is rst purged by removing all create and update actions on an entry that ends up being deleted, and SYNC_START is written in the SyncHistory table. For each action, an HTTP request is issued with the HTTP method corresponding to the type of action that needs to be performed on the server. The data from the records created or updated on the server is returned to the client, as it may contain additionnal information added by the server that should also be persisted on the client. The local store as well as theLUID-GUIDmapping are updated accordingly. If no error occurs, the synchronization process comes to end by writing SYNC_END in the SyncHistory table for each business object and clearing the ActionLog table.
4.5. Technical solution description 94
Figure 4.13: Oine client sync process