Pervasync in the Cloud – Setting up Pervasync with Amazon EC2 & RDS

Following is a tutorial for setting up Pervasync server in the Amazon cloud so that you can sync your mobile devices with Oracle, MySQL or SQL Server databases hosted in Amazon cloud.

 Preparing the AWS Env

1. Create an AWS account at http://aws.amazon.com/ec2/

2. Create a Beanstalk env to have a running Tomcat instance and a RDS database instance: http://aws.amazon.com/elasticbeanstalk/.

Setup the DB security group so that the DB instance can be accessed from the EC2 instance where Tomcat is hosted.

3. Create your app database, schema and tables. For MS SQL Server, connect to the DB server and create a database for your application’s DB schemas and tables. The DB name will be used as value of pervasync.server.db.database.name during Pervasync setup. For Oracle you supply the DB name during DB instance creation. The DB name will be the Oracle SID to be used in DB JDBC URL. For MySQL the RDS DB name is really the schema name.

4. For MySQL, create a DB Parameter Group and set the value of parameterlog_bin_trust_function_creators to 1. Modify the MySQL instance and set its parameter group to the one with log_bin_trust_function_creators set to 1. Reboot the DB instance.

Alternately to Beanstalk, you could also directly create an EC2 instance and RDS instance. To install Java & Tomcat on your EC2 instance, see
http://www.excelsior-usa.com/articles/tomcat-amazon-ec2-basic.html

Installing Pervasync in the AWS Env

Note: You need to substitute the host name, password etc. with yours in the following.

1. Download pervasync_server-5.0.3.zip from
https://www.dropbox.com/s/4uwhvo99j7ra2xc/pervasync_server-5.0.3.zip

2. Copy the zip file to your Amazon EC2 instance home folder:
scp -i keypair1.pem pervasync_server-5.0.3.zip ec2-user@ec2-54-214-22-102.us-west-2.compute.amazonaws.com:/home/ec2-user

3. Log on to your Amazon EC2 instance
ssh -i keypair1.pem ec2-user@ec2-54-214-22-102.us-west-2.compute.amazonaws.com

4. From now on act as root user. Un-package the zip in /usr/share/:
sudo su root
cd /usr/share/
unzip /home/ec2-user/pervasync_server-5.0.3.zip

5. Go to non-GUI install folder for your DB type, for example for SQL Server:
cd pervasync_server-5.0.3/util/mssql/

Edit pervasync_server_mssql.ini to supply your DB connection info:

 #=========================================================================
 #== Pervasync server for MS SQL Server ==
 #== ini file for setup/uninstall ==
 #== ==
 #== Property values are needed and only needed when you run ==
 #== the setup/uninstall scripts. After you are done with ==
 #== setup/uninstall, you can erase sensitive info from this file. ==
 #=========================================================================
# The JDBC URL to the Pervasync server repository database.
 # Replace "localhost" with the DB host name or IP if DB is not on the same host
 # For AWS RDS, replace "localhost" with the DB Endpoint
pervasync.server.db.url=jdbc:sqlserver://db1.cinuuz0ecpzz.us-west-2.rds.amazonaws.com:1433
# The database name. Replace "master" with the database name you created for your app
pervasync.server.db.database.name=myappdb
# Name and password of a DB user with root privileges.
 # This user/account should be pre-existent.
 # For AWS RDS, use the master user
pervasync.server.db.system.user=master
 pervasync.server.db.system.password=welcome1234!
# PervaSync server admin user name and password. You would need to use this
 # user/password pair to login to the web-based Pervasync admin console.
 # If not already exist, a database user/schema with this name will be created
 # in Pervasync server DB repository at setup time. At un-install time, the user/schema
 # will be dropped.
pervasync.server.admin.user=pvsadmin
pervasync.server.admin.password=welcome1234!

6. Run the setup
./pervasync_server_mssql_setup.sh

7. Install Pervasync server web app to Tomcat
chown -R tomcat:tomcat /usr/share/pervasync_server-5.0.3
cp /usr/share/pervasync_server-5.0.3/config/Catalina/localhost/pervasync.xml /usr/share/tomcat7/conf/Catalina/localhost/
vi /usr/share/tomcat7/conf/Catalina/localhost/pervasync.xml

8. Log on to Pervasync web admin console
http://default-environment-ddffdffd.elasticbeanstalk.com/pervasync

If not working, check Tomcat log:
vi /usr/share/tomcat7/logs/catalina.out

Check Pervasync log: vi /usr/share/pervasync_server-5.0.3/log/pervasync_server_mssql.log

Advertisements

Avoiding Sync Errors and Conflicts

Bad things happen. Synchronization systems are no exception. However, Pervasync has measures to help you keep things under control.

As you know a sync session has two phases, Check-in and Refresh. Refresh should rarely go wrong, as it is a forced applying of central DB changes to local DB. If it does go wrong, you have to manually fix the error and try Refresh again. As a last resort, the local DB has to be re-loaded by either re-installing the client or re-subscribe the client from server side.

Most of the errors happen in the Check-in phase where client tries to apply local DB transactions to central DB. In the following we will talk about errors due to DB constraint violations and conflicts due to con-current updates of same records from different clients. The emphasis here is prevention.

Errors Due to DB Constraint Violations

The sync client check-in is just like other central DB client transactions. It has to meet all the DB constraints to be committed in central DB.

Create Local DB Constraints via Sync SQL

First thing to do to avoid the constraint violations during Check-in is to ensure the local transactions meet the constraints on client side. Pervasync does not sync central DB constraints to local DB except for NOT NULL and primary key constraints. However, Pervasync has a “Sync SQL” feature that allows you publish SQL statements to be applied to client DB during synchronization. On web admin console, locate the sync schema and click on “Add Sync Sql” to define the desired UNIQUE constraints, CHECK constraints or referential constraints, for example,

ALTER TABLE pvcdemo.tasks ADD CONSTRAINT tasks_unique UNIQUE (NAME)

Instead of local DB constraints, we recommend you ensure the constraints in the client application layer where you can give end users direct, meaningful feedback when a constraint is violated.

Sync Table Ranks: Check-in Order

Even through your local changes meet the referential constraints, during Check-in, you still may encounter referential constraint violations like “Parent Key Not Found” and “Child Record Found”. This has to do with the order of the DML (Data Manipulation Language) operations in the Check-in transaction.

Pervasync uses the sync table ranks to determine the check-in order. When you publish a sync table, you need to assign a rank number that indicates the referential relationship among the sync tables. Parent tables should have a smaller rank number than child tables. For Insert operations, tables with a lower rank number are done first so that parent table is inserted first to avoid the “Parent Key Not Found” error when child table is inserted. Deletes are done in the reverse order to avoid the “Child Record Found” error.

Conflict Detection and Resolution

In an online system, a client could lock a DB row (record) when making changes to it so that the client is sure that it is modifying an up-to-date version of the row. In a sync system, sync client keeps a local copy of the row and makes offline changes to it without locking the central DB row. While the client makes these offline changes, other sync clients or central DB users may be making changes to the same row in central DB. During check-in time, if we do not do anything to handle conflicts, the newly checked-in row will overwrite changes from other sources. This may break your business logic since essentially the client was modifying an out-of-date copy of the row and changes from other clients were not taken into consideration.

Pervasync provides conflict detection and resolution to help you handle the conflicts so that your business requirements are satisfied.

There are three types of conflicts:

  • Insert conflict – Insert causes primary key violation. Likely others have inserted a row with a same primary key value. To avoid insert conflicts, refer to section 5.6 Generating Unique Key Values in Distributed Databases.
  • Update Conflict – Record to be updated has a higher version number indicating it was updated or has been deleted.
  • Delete conflict – Record to be deleted has a higher version number indicating it was updated or has been deleted.

For each type of conflict, we provide three resolution methods:

  • FORCE_CHECK_IN – Apply client transaction ignoring the conflict. For delete operations, records are deleted regardless of their versions. If records to be inserted already exist, update the records. If records to be updated have been deleted, insert the records.
  • DISCARD: Discard the conflicting changes from the client and check in non-conflicting changes.
  • REPORT_ERROR: Treat conflicts as errors and notify the client. This will cause the sync session to fail. In this case client could do a REFRESH_ONLY sync to let the server side changes overwrite the conflicting client side changes. This effectively modified the client transaction so that it won’t cause conflicts in next check-in assuming others won’t make new changes on server again. Before check-in, the client application could give end users a chance to inspect and update the new version of the records. End users should be clear that until the check-in succeeds, all changes are temporary although they are committed locally.

To configure the resolution methods, edit the following parameters in <PERVASYNC SERVER HOME>/config/pervasync_server_<db>.conf.

pervasync.conflict.resolution.InsertExisting=REPORT_ERROR

pervasync.conflict.resolution.UpdateChanged=FORCE_CHECK_IN

pervasync.conflict.resolution.DeleteChanged=DISCARD

 

REFRESH-ONLY to the Rescue

Pervasync supports three sync directions, TWO_WAY, REFRESH_ONLY and CHECK_IN_ONLY. You can pass in sync direction to the sync() method of client SyncAgent object, or you can use the corresponding pvc.bat/pvc.sh sub commands sync, refresh and checkin.

In a two-way sync session, Check-in is always done before Refresh. The reason is that conflict detection is done on the server side during Check-in. Refresh force-applies changes on local DB without any conflict detection. If Refresh is done before a successful Check-in, some local changes may be silently overwritten.

However, when Check-in encounters some errors or conflicts and cannot proceed, it is often useful to do a REFESH-ONLY sync to intentionally overwrite client changes with server changes so that a sub-sequent Check-in can go through. Examples are server has added or dropped a column, or server sets the conflict resolution method to be REPORT_ERROR and a conflict is found. The algorithm is as follows.

  1. Do two-way sync.
  2. Catch sync error, present the error to end-user and ask for permission to do a REFESH-ONLY sync.
  3. Do a REFESH-ONLY sync and give user a chance to edit the refreshed data.
  4. Do two-way sync.

By the way, even a lot of online applications do not lock the records while end users are editing the data. Instead, when the user is done with the editing and submits the data, they do the conflict check and if a conflict is found, a new version of the data is returned for user to edit and re-submit. The algorithm is essentially the same as above.

 

Generating Unique Key Values in Distributed Databases

A synchronization system contains distributed databases. How do you ensure that new records created on these databases have unique key values? In a single DB system, people usually use AUTO_INCREMENT columns (e.g. in MySQL) or sequence objects (e.g. in Oracle) that produce unique sequence numbers. In a multi-DB environment, special treatments have to be done to AUTO_INCREMENT columns and sequences otherwise different DBs might generate same primary key values that would conflict with each other when new records are synced from one DB to another.

Non-Conflicting AUTO_INCREMENT for MySQL Databases

NOTE: AUTO_INCREMENT does not apply to Oracle, which uses sequences. See next section for using sequences in a sync system.

AUTO_INCREMENT is the standard way for MySQL applications to generate unique key values. MySQL 5 introduces a couple of server variables, auto_increment_increment and auto_increment_offset, which make it possible to keep using AUTO_INCREMENT columns in a multi-DB system.

By default, auto_increment_increment and auto_increment_offset both have a value of 1. The inserted value is the least in the series [1, 2, 3…] that is greater than the maximum existing value of the column. When auto_increment_increment and auto_increment_offset take on non-default values, the series is no longer [1, 2, 3…], but calculated using the following formula:

auto_increment_offset + N × auto_increment_increment

where N is a non-negative integer value in the series [0, 1, 2, 3, …].

 

For example, with auto_increment_increment = 10 and auto_increment_offset = 5, the values are drawn from series [5, 15, 25…].

 

Following are the steps to take for using AUTO_INCREMENT in Pervasync.

 

  1. Choose an auto_increment_increment value. The value should be at least one greater than the number of local DBs you plan to deploy. For example, you may choose 1000 if your system is expected to have hundreds of local DBs.
  2. On central DB and all local DBs, edit your MySQL Server configuration file (usually called my.cnf or my.ini) to set auto_increment_increment and auto_increment_offset values. All MySQL servers should use a same auto_increment_increment value and a different auto_increment_offset value. For example, on central DB you may put

    auto_increment_increment=1000

    auto_increment_offset = 1

    while on the first local DB you may put

    auto_increment_increment=1000

    auto_increment_offset = 2

On central Db, keep the AUTO_INCREMENT column definitions intact. The AUTO_INCREMENT flag of the columns will be synced to local DB.

 

That’s it! From now on, do inserts as you normally do on a single DB without worrying about unique key violations. Nevertheless, if for some reason you prefer not to use the AUTO_INCREMENT feature, you can use the Pervasync “Sync Sequence” feature described in next section.

 

Sync Sequence

The idea of the Pervasync “sync sequence” feature is to divide a sequence into contiguous partitions/windows and distribute the partitions to central DB and local DBs. Database applications can draw globally unique values for unique keys from the sequence partitions. When a local DB is about to run out of the numbers, a new range is synced to the local DB.

Following are the steps to use Sync Sequences.

  1. Determine central DB sequence partition range. Normally you create a sequence for each unique key column. The central DB sequence has to be modified or re-created so that it will only occupy a partition. The START WITH value should be 1 greater than the maximum existing value of the column. The MAXVALUE of the sequence should be big enough so that central DB app would not easily run out of numbers, while at the same time it shouldn’t be too big so that local DBs have more room for their partitions. Manually create (or modify) the central DB sequence, for example, on Oracle server:

    CREATE SEQUENCE pvsdemo.task_id_seq START WITH 1000 MAXVALUE 1000000000;

     

    and on MySQL server

    CALL pvsadmin.create_sequence(‘pvsdemo’, ‘task_id_seq’, 1000, 1000000000);

  2. Publish the sync sequence on web admin console. Here you need to supply a sequence name, task_id_seq in our example and add it to a schema, pvsdemo in our example. In addition, you need to supply a “Start Value” and a “Window Size”. The start value should be one greater than the central DB sequence partition MAXVALUE. In our case, it should be 1000000001. The window size determines the number of values available in one local DB sequence partition. We use 1000000 for our example.
  3. After the first sync, the sequence partitions will be automatically created on local DBs. This is in contract to central DB, where you create the sequences manually. To use the sequences, call their NEXTVAL methods. For example, to insert into a table with column col1 as primary key, for Oracle database you do the following in your client application.

    INSERT INTO pvcdemo.table1(c1, c2) VALUES

    (pvcadmin.task_id_seq.nextval, ‘hello world’);

     

For MySQL database you do the following in your client application.

INSERT INTO pvcdemo.table1(c1, c2) VALUES

(pvcadmin.sequence_nextval(‘schema1’, ‘task_id_seq’), ‘hello world’);

For SQLite databases on Android or Blackberry, use the SyncClient method to retrieve the sequence next value and use it as key value for a new record. Note that the first argument is the logical sync schema name, not the client schema/database name. See API Javadoc for more details.

long idValue = pevasync.client.SyncClient.sequenceNextval(“schema1”, “task_id_seq”);

Other Options

We believe that AUTO_INCREMENT and sync sequence are the best choices for most situations. Still, there are other options that may fit your specific needs. We list them below.

  1. Only allow transactions to happen on central DB. Device local DBs are made read-only, i.e. for queries only. Believe it or not, there are systems that adopt this model.
  2. Use randomly generated numbers for key values. The length of the random numbers has to be long to reduce the possibility of collisions.
  3. Use a composite key. The sync client API has a method that returns the sync client ID. Apparently this is a globally unique number. You can use the client ID as the first column of a primary key. You then use a second column that takes locally unique values. Let’s call it LUID column. You define the client ID column and the LUID column together as your composite primary key. The values of the composite key are globally unique.
  4. Compute a GUID using client ID and LUID. For example, you could use this formula:

    GUID = <client ID> * 1000000000 + LUID

  5. Map local UID with GUID. This is the technique used by OMA DS (aka SyncML), and Activesync. Locally created records are assigned an LUID. During Activesync synchronization, a GUID for the same record is generated on server by mapping the LUID and synced back to client. For OMA DS, client sends an LUID back to server for every server sent record. A map table of LUID and GUID is maintained on server.

The mapping methods may be OK for simple PIM (Personal Information Management) sync. However, for enterprise applications that have large amount of data, a lot of tables and complex referential relationships between tables, the mapping would cause performance and maintenance problems. Hence, Pervasync does not support mapping method.

Schema Evolution and Sync Table Reload

Sometimes it is inevitable that new business requirements come up after the system has gone production and you have to change table structure or even drop/add table from/to schemas. Pervasync supports schema evolution so that you don’t have to re-build the whole system from scratch.

Schema Evolution Steps

  1. Shutdown sync server

Before you make any changes to the system, it is recommended to first shut down sync engine and sync servlet using the web admin console. It is also recommended to sync all the clients before the server shutdown so that all client side changes are uploaded to server.

  1. Alter DB table

Then, you make physical changes to the central database schemas/tables, such as create/drop tables, alter tables to add/remove columns or change column data types.

  1. Update sync table

Go to the web admin console and locate the table you just changed. Delete the sync table if you dropped the corresponding DB table. Update the sync table if you altered the corresponding DB table.

  1. Start sync server

Re-start sync engine and re-open sync servlet using the web admin console.

Propagation of Table Definition to Clients and Table Reload

The first sync after the server schema change will propagate the new schema definition to client. If a sync table was removed, the corresponding client DB table will be dropped. Also in general, if a sync table was updated, the corresponding client DB table will be altered.

Some updates to the sync table would cause the client DB table be dropped, re-created and re-populated with data from server. This is called a re-load.

If you change the subsetting query, clients may be assigned a different sub-set of data. Therefore, Pervasync will do a table re-load for all the clients. Altering a table’s primary key will cause the same.

If you change the values of subsetting parameters for a particular client, that client would get a reload for the affected tables. Other tables and clients won’t get a reload.

Data Subsetting Using a SQL Query with Parameters

A Step by Step Example of Data Subsetting

Let’s use the following table EMP of schema SCOTT as an example. Suppose you have your entire employee data stored in the EMP table of your central DB. The EMP table has the following definition. Each employee has an employ ID (column EMPNO) and belongs to a department (column DEPTNO):

CREATE TABLE “SCOTT”.”EMP”

(    “EMPNO” NUMBER(4,0),

    “ENAME” VARCHAR2(10),

    “JOB” VARCHAR2(9),

    “MGR” NUMBER(4,0),

    “HIREDATE” DATE,

    “SAL” NUMBER(7,2),

    “COMM” NUMBER(7,2),

    “DEPTNO” NUMBER(2,0),

     CONSTRAINT “PK_EMP” PRIMARY KEY (“EMPNO”) ENABLE,

     CONSTRAINT “FK_DEPTNO” FOREIGN KEY (“DEPTNO”)

     REFERENCES “SCOTT”.”DEPT” (“DEPTNO”) ENABLE

);

 

Your company has grown very big and become geographically distributed. Employees started to have problems accessing the EMP table because the central DB is under heavy load and the network is not always fast and stable. So you decide to create a local DB for each department. The EMP table in a local DB only contains data for employees belonging to that department. Here we are subsetting by DEPTNO. In real world applications, people may do subsetting by country, region, branch office name/ID, and clinic name/ID etc.

Following are the steps to take to use Pervasync to synchronize the EMP table in a local DB with the EMP table in the central DB.

  1. Prepare the central DB schema.

You may need to make some adjustments to the structure of your existing table to make it ready to be published as a sync table.

Pervasync requires that all sync tables have a primary key. The EMP table already has a primary key: column EMPNO. So, we are fine.

Assume we want to do the subsetting by DEPTNO. Then, we should have a table that defines the association between DEPTNO and EMPNO. One way to do this is to add a DEPTNO column to EMP table. EMP table already has a DEPTNO column, so we don’t need to do anything. Another way is to create a separate table that has two columns EMPNO and DEPTNO with EMPNO being the primary key column. You know what I mean if you learned about table normalization.

Now we have a decision to make: do we want to keep EMPNO as the sole primary key column or do we want to make DEPTNO and EMPNO together a composite primary key? Both have pros and cons. You make the decision based on your business requirements. If we keep EMPNO as the sole primary key column, we have to make sure that local DB do not assign conflicting EMPNO values when adding new employees locally. In Pervasync, you can create a sync sequence for the EMPNO column and draw globally unique values from the sync sequence locally (For more information and explanation of sync sequence, see section 5.5.2 Sync Sequence). If you make DEPTNO and EMPNO together a composite primary key, you only need to make sure EMPNO is locally unique when you add a new employee. If your company does not require every employee to have a company wide unique ID (value of EMPNO), you can choose the latter way.

In summary, to make a table ready to be published as a sync table, it has to have a primary key defined and an association between the primary key and the subsetting column defined.

  1. Publish the sync table and add it to the sync schema

When you define the sync table via the Pervasync web admin console at Sync Schemas-> Sync Tables-> Add new Sync Table, or via the admin Java API using method addSyncTable of class SyncServerAdmin, you have a chance to supply a data subsetting query. If you already have a sync table that you want to use for subsetting, you can click “Update”, and then edit “Subsetting Query”. Data subsetting query determines which rows go to which local database. There is no restriction on the query as long as it returns the Ids of the rows to be synced to a local DB. If we keep EMPNO as the sole primary key column we would use the following query:

SELECT EMPNO FROM SCOTT.EMP WHERE DEPTNO=${DEPTNO_PARAM}

 

If we make DEPTNO and EMPNO together a composite primary key we would use the following query:

SELECT DEPTNO, EMPNO FROM SCOTT.EMP WHERE DEPTNO=${DEPTNO_PARAM}

 

In the above queries, we have a placeholder, ${DEPTNO_PARAM}. The variables enclosed in ${} are subscription parameters. Queries for other tables could share the same parameter names. The collection of unique table level parameters becomes parameters for the published sync schema.

The queries in our example are among the simplest as they have only one parameter and reference only one table. One could have multiple parameters and use table joins in the query. Pervasync employs different algorithms for simple and complex queries to achieve maximum efficiency for both cases. You need to specify a subsetting mode when doing the subsetting: SIMPLE or COMPLEX. Subsetting mode SIMPLE is different from COMPLEX in that a SIMPLE query can select from only one table, which could be the sync table itself or a different table. For more information and explanation of SIMPLE or COMPLEX subsetting modes, see section 5.4.2: “Subsetting Modes: SIMPLE and COMPLEX”.

  1. Subscribe a sync user to a sync schema

For each local DB, you create a sync client – a combination of user and device. When you subscribe a sync client to a sync schema via the Pervasync web admin console at Sync Schemas-> Schema Subscriptions-> Add new Schema Subscription, or via the admin Java API method addSchemaSubscription of class SyncServerAdmin, you have a chance to supply a value for each of the subscription parameters. If you already have a Schema Subscription that you want to use for subsetting, you can click “Update Subscription”, and then enter the value of the parameter, which you specify as a placeholder in subsetting query at step 2. In our case, we will see DEPTNO_PARAM listed as a parameter name and we can assign a value. For example, if we want a sync client to sync data for DEPTNO=1, we put 1 as the value for DEPTNO_PARAM.

  1. Sync

During synchronization for the sync client we just subscribed, effectively the following query is executed:

SELECT EMPNO FROM SCOTT.EMP WHERE DEPTNO=1

 

So that only the rows with DEPTNO=1 are synced to this client.

 

Subsetting Modes: SIMPLE and COMPLEX

The parameterized SQL query is at the heart of data subsetting. There is virtually no restriction to the query as long as it returns the primary key values of the desired data sub-sets. This gives users great flexibilities but at the same time, it poses great challenges to the sync engine, which has to figure out physical and logical changes to the data sub-sets. Algorithms that apply to generic queries may not be scalable. On the other hand, algorithms that perform well for simple queries may not apply for complex queries.

Pervasync asks users to indicate the complexities of their queries via subsetting modes so that different algorithms can be applied to achieve best possible performance and scalability.

Criteria for SIMPLE query

There are two subsetting modes, SIMPLE and COMPLEX. Criteria for SIMPLE query are as follows.

  1. The query can reference only one table. This table can be the table you are subsetting or a different table.

    The query predicates that involve the table columns can use not only “=”, but also other conditional operators like “>”, “<“, and “like” etc. For example, the following queries qualify as SIMPLE queries,

    SELECT EMPNO FROM SCOTT.EMP WHERE DEPTNO=${DEPTNO_PARAM} AND MGR = ${MGR_PARAM}

 

SELECT EMPNO FROM SCOTT.EMP WHERE DEPTNO=${DEPTNO_PARAM} AND SAL < ${SAL_PARAM}

 

SELECT EMPNO FROM SCOTT.EMP WHERE SAL > ${SAL_MIN} AND SAL < ${SAL_MAX}

 

SELECT EMPNO FROM SCOTT.EMP WHERE JOB like ‘%Engineer’

 

  1. The query cannot use functions, expressions, joins, set operations like “union”, “intersect” etc.
  2. Query referenced columns (e.g. DEPTNO, MGR, SAL and JOB in the above examples) cannot have NULL values and the column data type cannot be too long. The reason is that these columns will become part of a primary key for a Pervasync internal table so they have to satisfy primary key column criteria of the database. If you cannot make these columns “NOT NULL” and have shorter length, mark the subsetting query COMPLEX.

Scalability implications

In general, SIMPLE queries are much more scalable than COMPLEX queries in terms of database space and sync engine processing time. For SIMPLE queries, sync engine performance is virtually independent of the number of sync clients you have.

COMPLEX queries can be scalable if a large number of clients share a same set of parameter values. For example, suppose you have 1000 clients and there are only 10 unique values for the subscription parameter DEPTNO_PARAM, the resources needed by sync engine are about the same as 10 clients each having a unique value for the parameter. Still, if at all possible, we recommend you use SIMPLE queries as opposed to COMPLEX queries.

Converting a COMPLEX Query to a SIMPLE Query

If you mark a SIMPLE query as COMPLEX, sync will still work but just not as efficiently. However, if you simply mark a COMPLEX query as SIMPLE, the sync may not work – you may find that client is not getting the changes you expect.

Fortunately, there are ways to convert a COMPLEX query to a SIMPLE query. For example, let’s say you want to sync users’ emails to their mobile devices and you use email recipient as subsetting parameter. The query qualifies as a SIMPLE query:

SELECT EMAIL_ID FROM USER_EMAILS WHERE RECEIPIENT = ${EMAIL_ADDRESS_1} OR RECEIPIENT = ${EMAIL_ADDRESS_2}

 

Now, let’s say you only want to sync last 30 days’ emails to save space on device. The query becomes COMPLEX:

SELECT EMAIL_ID FROM USER_EMAILS WHERE (RECEIPIENT = ${EMAIL_ADDRESS_1} OR RECEIPIENT = ${EMAIL_ADDRESS_2}) AND RECEIVE_DATE > (SYSDATE – INTERVAL ’30’ DAY(5))

 

To convert this query to a SIMPLE query, you can add a column INCLUDE_IN_SYNC, which takes values of “Y” for yes and “N” for no and defaults to “N”. You create a DB job to update the INCLUDE_IN_SYNC values every night:

UPDATE USER_EMAILS SET INCLUDE_IN_SYNC=”Y” WHERE INCLUDE_IN_SYNC=”N” AND RECEIVE_DATE > (SYSDATE – INTERVAL ’30’ DAY(5))

 

With this in place, you would be able to use the following SIMPLE query to achieve the same result as the original COMPLEX query.

SELECT EMAIL_ID FROM USER_EMAILS WHERE (RECEIPIENT = ${EMAIL_ADDRESS_1} OR RECEIPIENT = ${EMAIL_ADDRESS_2}) AND INCLUDE_IN_SYNC=”Y”

Doing Synchronization Using Pervasync Client for Android and Blackberry

We will first show the Pervasync client working in standalone mode and then describe how to embed the client in to your Android or Blackberry app.

Starting Sync Sessions and Viewing Sync History

Once the sync client is installed and setup, you can click on the “Start Sync” button on the Sync screen of the Pervasync client.

During synchronization, the Sync screen will show you the progress. Once completed, the sync history is available on the History screen. For Android, you switch between screens by clicking on the tabs while for Blackberry, you click on the menu items.

NOTE: If you see non-empty “Sent(bytes)” but empty “Received” and sync seems to get stuck, most likely you have a typo in sync URL or the sync server is not up. Use the “Setup” tab to correct the URL. Make sure you have the right IP and port number.

Below are Sync and History screen shots for Android and Blackberry respectively.

Updating Setup Info and Configuring Auto Sync

NOTE: In the following we will only show screen shots for Android. Blackberry screens are similar. The main difference is that instead of tabs, you usually use menu items to navigate to different screens on Blackberry.

The Setup screen allows you to update the setup info. It also allows you to reset the client to pre-setup state.

The Scheduler screen allows you to schedule sync jobs so that you don’t have to manually initiate each sync session. Normally you would turn on the “Repeat” flag to make the sync happen periodically with a preset sync interval. Note that you need to have both the Job Scheduler running and the job enabled for the auto sync to be on.

Database and File Browser

The Browser screen allows you to inspect the databases and files that are synced to the device. You may want to hide this functionality from end users after you compose your own user interface to the synced data. However, it’s a great tool to use during development of your application that uses Pervasync for data synchronization.

The Browser screen lists all the schemas/databases and folders. Clicking on a schema will bring up a dialogue with options to show tables or sequences that belong to the schema.

Following are the table list and sequence list.

Click on table to show table definition and table data. The table data screen will by default show 10 rows. You can change the Fetch Limit to show more or less than that. You can also put a predicate in the Where Clause box to show the desired rows, for example:

NAME like ‘%Jonh%’

Click on a row to bring up the row editor screen where you can delete or update the row data. You could also insert a new row using this screen.

Back to the main Browser screen, you can click on a sync folder to show the sub folders and files.

Syncing Data and Files to External Storage

If you run the sync client in standalone mode (as opposed to embedding it into your device app), your app usually won’t be able to access the synced data unless the data is on external storage. To sync data and files to external storage, prefix the client schema name and client folder name with “EXTERNAL;”. Note the trailing semi colon.

Embedding Pervasync Client into Your Android Application on Device

If you run the sync client in standalone mode, your app usually won’t be able to access the synced data unless the data is on external storage. Instead, if you embed the sync client into your own application, both the sync client code and your app code share the same permissions to the data and you would be able to store the data on internal and external storages.

The “android/lib” folder of your Pervasync server home has a Pervasync client library jar that you can easily include into your app.

Let’s assume you created an Android project “my_android_app” in your Eclipse workspace. Your package name is “com.mycorp.myapp” and your main Activity is “MyMainActivity”. The AndroidManifest.xml of your project would look like the following:

<?xml
version=“1.0”
encoding=“utf-8”?>

<manifest package=“com.mycorp.myapp” android:versionCode=“1”

    android:versionName=“1.0” xmlns:android=http://schemas.android.com/apk/res/android&#8221;>

    <application
android:icon=“@drawable/icon”

        android:label=“My Android App”>

        <activity
android:name=“.MyMainActivity”
android:label=“@string/app_name”>

            <intent-filter>

                <action
android:name=“android.intent.action.MAIN” />

                <category
android:name=“android.intent.category.LAUNCHER” />

            </intent-filter>

</application>

    <uses-sdk
android:minSdkVersion=“7”
android:targetSdkVersion=“7” />


</manifest>

Following are the steps to embed Pervasync client.

Add Pervasync Android client library to Java Build Path

Right click on your Eclipse project for your Android app and open the “Properties” window. Click on “Java Build Path” on the left panel and then click the “Libraries” tab on the right panel. Click on “Add External JARs…” button to add Pervasync Android client library “pervasync_android_lib-4.0.0.jar” which is located in the “android/lib” folder of Pervasync server home.

NOTE: If your Pervasync server and your Eclipse IDE are on different hosts, just copy the jar to your Eclipse host.

After adding the jar, click the “Order and Export” tab. Select the check box in front of “pervasync_android_lib-4.0.0.jar”.

Add Pervasync Activities and Permissions to AndroidManifest.xml

Copy-paste the “activity” and “uses-permission” elements from the following sample AndroidManifest.xml (see also android/AndroidManifest_sample.xml) to your AndroidManifest.xml.

NOTE: Don’t copy the grayed-out parts. Your AndroidManifest.xml should already have them.

<?xml version=“1.0” encoding=“utf-8”?>

<manifest package=“com.mycorp.myapp” android:versionCode=“1”

    android:versionName=”1.0″ xmlns:android=”http://schemas.android.com/apk/res/android”&gt;

    <application android:icon=“@drawable/icon”

        android:label=“My Android App”>

        <activity android:name=“.MyMainActivity” android:label=“@string/app_name”>

            <intent-filter>

                <action android:name=“android.intent.action.MAIN” />

                <category android:name=”android.intent.category.LAUNCHER” />

            </intent-filter>

        </activity>

        <activity android:name=“pervasync.ui.android.PervasyncClientActivity”

            android:label=“Pervasync”>

        </activity>


        <service
android:name=“pervasync.ui.android.PervasyncService”>

            <intent-filter>

                <action
android:name=“pervasync.ui.android.PervasyncService” />

            </intent-filter>

        </service>

        <activity android:name=“pervasync.ui.android.PervasyncSyncActivity”

            android:label=“Pervasync Sync”>

        </activity>

        <activity android:name=“pervasync.ui.android.AutoSyncSchedulerActivity”

            android:label=“Pervasync Scheduler”>

        </activity>

        <activity android:name=“pervasync.ui.android.PervasyncHistoryActivity”

            android:label=“Pervasync Sync History”>

        </activity>

        <activity android:name=“pervasync.ui.android.PervasyncSetupActivity”

            android:label=“Pervasync Setup”>

        </activity>

        <activity android:name=“pervasync.ui.android.PervasyncBrowserActivity”

            android:label=“Pervasync Browser”>

        </activity>

        <activity android:name=“pervasync.ui.android.SchemaTablesActivity”

            android:label=“Schema Tables”>

        </activity>


        <activity android:name=“pervasync.ui.android.FolderFilesActivity”

            android:label=“File Browser”>

        </activity>

        <activity android:name=“pervasync.ui.android.SchemaSequencesActivity”

            android:label=“Schema Sequences”>

        </activity>

        <activity android:name=“pervasync.ui.android.TableRowsActivity”

            android:label=“Table Data”>

        </activity>

        <activity android:name=“pervasync.ui.android.TableColumnsActivity”

            android:label=“Table Column Types”>

        </activity>

        <activity android:name=“pervasync.ui.android.RowEditActivity”

            android:label=“Row Edit”>

        </activity>

        <activity android:name=“pervasync.ui.android.ImageFileActivity”

            android:label=“Image File”>

        </activity>

        <activity android:name=“pervasync.ui.android.TextFileActivity”

            android:label=“TextFile”>

        </activity>

        <receiver
android:enabled=“true”
android:name=“pervasync.ui.android.BootUpReceiver”

            android:permission=“android.permission.RECEIVE_BOOT_COMPLETED”>

            <intent-filter>

                <action
android:name=“android.intent.action.BOOT_COMPLETED” />

                <category
android:name=“android.intent.category.DEFAULT” />

            </intent-filter>

        </receiver>

    </application>

    <uses-sdk android:minSdkVersion=“7” android:targetSdkVersion=“7” />

<uses-permission
android:name=“android.permission.RECEIVE_BOOT_COMPLETED” />

    <uses-permission
android:name=“android.permission.ACCESS_NETWORK_STATE”></uses-permission>

    <uses-permission
android:name=“android.permission.ACCESS_WIFI_STATE”></uses-permission>

    <uses-permission
android:name=“android.permission.INTERNET”></uses-permission>

    <uses-permission
android:name=“android.permission.WRITE_EXTERNAL_STORAGE”></uses-permission>

</manifest>

Invoke Pervasync Client from Your App Code

With the inclusion of the library and the additions to the manifest file, Pervasync is now part of your application. You can now invoke Perasync. In the main activity of your app, you should start the Pervasync service so that it can perform auto-sync in the background:

if (!PervasyncService.isStarted()) {

    startService(new Intent(this, PervasyncService.class));

}

To show the Pervasync UI, start the Pervasync client activity:

Intent intent = new Intent(myMainActivity,

PervasyncClientActivity.class);

startActivity(intent);

Following is a sample main activity:

package com.mycorp.myapp;

import pervasync.ui.android.PervasyncService;

import pervasync.ui.android.PervasyncClientActivity;

import android.app.Activity;

import android.content.Intent;

import android.os.Bundle;

import android.view.Gravity;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.LinearLayout;

import android.widget.TextView;

import android.widget.LinearLayout.LayoutParams;

/*

* This is the main screen of your app

*/

public
class MyMainActivity extends Activity {

    private
static
final
int
SYNC_CLIENT_ID = 0;

    private
final MyMainActivity myMainActivity = this;

    /** Called when the activity is first created. */

    @Override

    public
void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);

        // start Pervasync service if not already started.

        if (!PervasyncService.isStarted()) {

            startService(new Intent(this, PervasyncService.class));

        }

        // set title

        setTitle(“Pervasync Sample App”);

        // contentView is a LinearLayout

        LinearLayout contentView = new LinearLayout(this);

        contentView.setOrientation(LinearLayout.VERTICAL);

        this.setContentView(contentView);

        // empty line

        contentView.addView(new TextView(myMainActivity));

        // description

        String description = “This is a place holder main screen for your application. “

                + “You can replace the title, add UI components to the screen and add “

                + “child screens that can be linked from this main screen.\n\n”

                + “We added a button below that invokes the Pervasync Client main screen where users can setup “

                + “Pervasync and perform synchronization.\n\n”

                + “The Pervasync Client also includes a database browser for you to explore the “

                + “synced databases during developemnt time. You could hide the browser in the production “

                + “version of your app.”;

        TextView textView = new TextView(this);

        textView.setText(description);

        contentView.addView(textView);

        // empty line

        contentView.addView(new TextView(myMainActivity));

        // buttonBar

        LinearLayout buttonBar = new LinearLayout(myMainActivity);

        buttonBar.setGravity(Gravity.CENTER); // How button bar aligns its

                                                // children

        buttonBar.setOrientation(LinearLayout.HORIZONTAL);

        contentView.addView(buttonBar, new LinearLayout.LayoutParams(

                LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));

        // Launch Pervasync Client button

        Button pervasyncButton = new Button(this);

        LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(

                LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);

        pervasyncButton.setLayoutParams(params);

        pervasyncButton.setText(“Launch Pervasync Client”);

        pervasyncButton.setTag(“Pervasync”);

        pervasyncButton.setOnClickListener(new OnClickListener() {

            public
void onClick(View view) {

                Button button = (Button) view;

                if (“Pervasync”.equalsIgnoreCase((String) button.getTag())) {

                    Intent intent = new Intent(myMainActivity,

                            PervasyncClientActivity.class);

                    startActivity(intent);

                }

            }

        });

        buttonBar.addView(pervasyncButton);

    }

    @Override

    public
boolean onCreateOptionsMenu(Menu menu) {

        menu.add(Menu.NONE, SYNC_CLIENT_ID, Menu.CATEGORY_CONTAINER,

                “Launch Pervasync Client”);

        return (super.onCreateOptionsMenu(menu));

    }

    @Override

    public
boolean onOptionsItemSelected(MenuItem item) {

        switch (item.getItemId()) {

        case
SYNC_CLIENT_ID:

            startActivity(new Intent(myMainActivity,

                    PervasyncClientActivity.class));

            return (true);

        default:

            ;

        }

        return
super.onOptionsItemSelected(item);

    }

}

You can now build and run your Android app.

Advanced Topics

OTA Deployment

Once you package and sign your app with Android signature tool, you will have an apk file generated. Copy the apk file, e.g. my_android_app.apk, to <Pervasync Server Home>/web/pervasync/download and your users can install the app over-the-air (OTA) by entering the following URL in their mobile browser:

http://<Pervasync_Host&gt;:<port>/pervasync/download/my_android_app.apk

Javadoc

You can find Javadoc of the Pervasync client interface in <Pervasync Server Home>/android/doc. Open the index.html in a browser.

Embedding Pervasync Client into Your Blackberry Application on Device

If you embed the sync client into your own application, both the sync client code and your app code share the same permissions to the data. This allows you to secure the data so that only your app (including sync code) can access the data.

The “blackberry/lib” folder of your Pervasync server home has a Pervasync client library jar that you can easily include into your app.

Let’s assume you created a Blackberry project “my_blackberry_app” in your Eclipse workspace. Your package name is “com.mycorp.myapp” and your UIApplication is “MyBlackberryApp”. You also have a MainScreen called “MyMainScreen”.

Following are the steps to embed Pervasync client.

Add Pervasync Blackberry client library to Java Build Path

Right click on your Eclipse project for your Blackberry app and open the “Properties” window. Click on “Java Build Path” on the left panel and then click the “Libraries” tab on the right panel. Click on “Add External JARs…” button to add Pervasync Blackberry client library “pervasync_blackberry_lib-4.0.0.jar” which is located in the “blackberry/lib” folder of Pervasync server home.

NOTE: If your Pervasync server and your Eclipse IDE are on different hosts, just copy the jar to your Eclipse host.

After adding the jar, click the “Order and Export” tab. Select the check box in front of “pervasync_blackberry_lib-4.0.0.jar”.

Enable Auto-Run

Open Blackberry_App_Descriptor.xml under your app project and select the checkbox “Auto-run on start”. This is to auto start your app after a device re-boot so that your app can do auto-sync in the background.

Invoke Pervasync Client from Your App Code

With the inclusion of the library, Pervasync is now part of your application. In the UIApplication “MyBlackberryApp” of your app, you should start the Pervasync JobScheduler so that it can perform auto-sync in the background:

if(!SyncClient.needSetup()){

SyncClient.restartJobScheduler();

}

To show the Pervasync UI, push PervasyncSyncScreen in your MyMainScreen class:

UiApplication.getUiApplication().pushScreen(

                    new PervasyncSyncScreen());

Following is a sample UIApplication “MyBlackberryApp”:

package com.mycorp.myapp;

import pervasync.client.SyncClient;

import net.rim.device.api.ui.UiApplication;

public
class MyBlackberryApp extends UiApplication {

    /**

     * This is a place holder for your Blackberry application.

     * You could replace the package name and class name.

     * @param args

     * @throws Exception

     */

    public
static
void main(String[] args) throws Exception {

        MyBlackberryApp myBlackberryApp = new MyBlackberryApp();

        myBlackberryApp.enterEventDispatcher();

    }

    /**

     * Constructor. Displays the main screen of your application

     * @throws Exception

     */

    public MyBlackberryApp() throws Exception {

        // start Pervasync job scheduler if you want to have auto sync

        if(!SyncClient.needSetup()){

            SyncClient.restartJobScheduler();

        }


        // show the app main screen

        pushScreen(new MyMainScreen());

    }

}

Following is a sample MainScreen “MyMainScreen”:

package com.mycorp.myapp;

import net.rim.device.api.ui.Font;

import net.rim.device.api.ui.MenuItem;

import net.rim.device.api.ui.UiApplication;

import net.rim.device.api.ui.component.Dialog;

import net.rim.device.api.ui.component.LabelField;

import net.rim.device.api.ui.component.RichTextField;

import net.rim.device.api.ui.component.SeparatorField;

import net.rim.device.api.ui.container.MainScreen;

import pervasync.client.SyncClient;

import pervasync.ui.blackberry.PervasyncSyncScreen;

public
class MyMainScreen extends MainScreen {

    /**

     * Constructor

     */

    public MyMainScreen() {

        // set page title

        LabelField title = new LabelField(“My Blackberry App”,

                LabelField.ELLIPSIS | LabelField.USE_ALL_WIDTH);

        setTitle(title);

        // set header

        addHeader(“My Blackberry App Main Screen”);

        // set description

        String description = “This is a place holder main screen for your application. “

            + “You can replace the title, add UI components to the screen and add “

            + “child screens that can be linked from this main screen.\n\n” +

            “We added a menu item that invokes the Pervasync Client main screen where users can setup “+

            “Pervasync and perform synchronization.\n\n” +

            “The Pervasync Client also includes a database browser for you to explore the “+

            “synced databases during developemnt time. You could hide the browser in the production “ +

            “version of your app”;

        RichTextField richTextField = new RichTextField(description,

                RichTextField.READONLY);

        add(richTextField);

    }

    /**

     * Helper to add a bold typed header

     * @param labelStr

     */

    private
void addHeader(String labelStr) {

        LabelField labelField = new LabelField(labelStr,

                LabelField.FIELD_HCENTER);

        labelField.setFont(labelField.getFont().derive(Font.BOLD));

        this.add(labelField);

        this.add(new SeparatorField());

    }

    /**

     * Put the app in the background when closing.

     */

    public
boolean onClose() {

        UiApplication.getUiApplication().requestBackground();

        return
true;

    }

    /**

     * Kill the app on exit

     */

    private
void exit() {

        if (SyncClient.isSynchronizing()) {

            int retVal = Dialog

                    .ask(Dialog.D_YES_NO,

                            “Exiting will kill the on-going sync session. Are you sure you want to exit?”);

            if (retVal == Dialog.YES) {

                System.exit(0);

            }

        } else {

            System.exit(0);

        }

    }

    /**

     * Pervasync Client Menu Item

     */

    private
final
class PervasyncMenuItem extends MenuItem {

        private PervasyncMenuItem() {

            super(“Pervasync Client”, 1, 1);

        }

        public
void run() {

            UiApplication.getUiApplication().pushScreen(

                    new PervasyncSyncScreen());

        }

    }

    /**

     * Exit Menu Item

     */

    private
final
class ExitMenuItem extends MenuItem {

        private ExitMenuItem() {

            super(“Exit”, Integer.MAX_VALUE, 1);

        }

        public
void run() {

            exit();

        }

    }

    /**

     * This is called when user invokes menu

     */

    public
boolean onMenu(int instance) {

        removeAllMenuItems();

        addMenuItems();

        return
super.onMenu(instance);

    }

    private
void addMenuItems() {

            PervasyncMenuItem pervasyncMenuItem = new PervasyncMenuItem();

            this.addMenuItem(pervasyncMenuItem);

        ExitMenuItem exitMenuItem = new ExitMenuItem();

        this.addMenuItem(exitMenuItem);

    }

}

You can now build and run your Blackberry app.

Advanced Topics

Encryption

To encrypt the database, prefix the client schema name with “ENCRYPT;” when you publish the sync schema. If you want it be both encrypted and stored on external storage, use prefix “EXTERNAL; ENCRYPT;”.

Note that other apps on the device can still access the databases when it’s encrypted. To further secure your DB so that only your app can access it, use prefix “PROTECT;”.

OTA Deployment

Once you package and sign your app with Blackberry signature tool, you will have a jad file and some cod files generated (e.g. in <your project root>/deliverables/Web/6.0.0). Copy these files to <Pervasync Server Home>/web/pervasync/download and your users can install the app over-the-air (OTA) by entering the following URL in their mobile browser:

http://<Pervasync_Host&gt;:<port>/pervasync/download/my_blackberry_app.jad

Javadoc

You can find Javadoc of the Pervasync client interface in <Pervasync Server Home>/android/doc. Open the index.html in a browser.

Doing Synchronization Using Pervasync Client for Oracle and MySQL

Locate pvc.bat (for Windows) or pvc.sh (for Linux) in the “bin” folder of Pervasync client home. Invoke it with the “-h” option to show its usage:

C:\pervasync\bin>pvc -h

 

Usage

—–

pvc.bat [{sync|refresh|checkin|auto_sync|sys_tray} [<password>]]

 

Use this command to launch the Pervasync Client Configuration and Sync Utility.

If no arguments are specified, i.e.

 

pvc.bat

 

the sync client GUI will be launched.

 

If “sys_tray” is specified as an argument, i.e.

 

pvc.bat sys_tray

 

the sync client GUI will be launched in system tray (minimized).

 

Otherwise, it will run in non-GUI mode.

Use the “sync” sub-command to do two-way sync, e.g.

 

pvc.bat sync

 

Use “refresh” and “checkin” to do one-way sync.

 

You use “auto_sync” option to start the job scheduler for running sync jobs

at pre-arragned times. Use the “Schedule” tab of the GUI to update job schedules.

 

You can optionally supply the sync user password as a second argument.

Stored password will be used if it is absent.

 

Note that the JDBC jar file (for Oracle) or Java connector jar file

(for MySQL) has to be available in folder ../lib to run this script.

If invoked without any arguments, the client will run in GUI mode. In GUI mode, users can start or schedule sync sessions by pointing and clicking.

 

NOTE: You close the GUI window to terminate the client. When you do that, you will be given an option to run the client in system tray. There is also a command-line option “sys_tray” to “pvc.bat” that you can use to launch the client to run directly in system tray. You may want to create a Windows task to do this upon system re-boot. This is useful to run scheduled sync tasks in background.

 

The Sync Tab of the Pervasync Client GUI

Go to the “bin” folder and invoke “pvc.bat” for Windows or “pvc.sh” for Linux. A GUI window will pop up. There are five tabs, Setup, Sync, Schedule, Export and Import. Setup tab is used for setup and reset. Click on Sync tab you will see the following.

Listed below are the GUI settings that need some explanations:

Sync Direction: By default, it’s TWO_WAY sync. You can use “REFRESH_ONLY” and “CHECK_IN_ONLY” to do one-way sync.

Sync User Password: You can optionally supply the sync user password. Stored password will be used if it is absent. You can have the password saved using the setup tab, or use the sync tab and click on the “Save Password” checkbox.

Single Session: When there are sync definition changes in a sync session, Pervasync will only download the definition changes and leave data changes to next sync session. By default, Pervasync will do two sync sessions with one “Sync” button click when there are sync definition changes to make sure both sync definition and data changes are synced. Check this checkbox to perform only one sync session with one click.

NOTE: If sync client resides inside a firewall and sync server resides outside the firewall, you need to set the HTTP proxy host and port using the setup tab with “Advanced Mode” turned on.

You can change the default settings if you need to. Then, click “Sync” to invoke the Sync Agent to do synchronization.

Once the sync session is completed you will see an alert box telling you whether the session succeeded or failed. The “Sync History” panel on the “Sync” tab will also show you a summary of completed sessions.

If the sync fails, first check the error stack trace on the “Sync History” panel. For more detailed debugging info, check the log files under <Pervasync Client Home>/log. If you cannot resolve the issue yourself, send the log file to Pervasync support at support@pervasync.com.

The Schedule Tab of the Pervasync Client GUI

The Schedule tab enables you to schedule up to three sync jobs that do background synchronization at a pre-determined time. In addition to the start time, you also can specify the sync direction and optionally, the sync interval.

Before you schedule background sync jobs, make sure you have the sync user password saved using the “Setup” or the “Sync” tabs.

Click “Schedule” button to start a job and click on “Cancel” button to stop a job. A scheduled sync will be skipped if there is already a sync going on at the scheduled sync start time. Sync history is available on the sync tab.

NOTE: All sync jobs will be cancelled if you exit the sync client.