public
Description: Rhosync is a rails application to facilitate accessing information from hosted backend applications and syncing that information to mobile devices.
Homepage: http://rhomobile.com
Clone URL: git://github.com/rhomobile/rhosync.git
larsburgess (author)
Fri Oct 30 13:59:40 -0700 2009
commit  f463b9dc0e080004805c49d19aa28aa016d26c34
tree    ad1066eb2a370acd4b24742952fd0372277a7eae
parent  3dd579be01cc59468bf5aa881f6d0369ddf28e25 parent  31e21afede70cbcbe65a4c1c8f65d1a80aa9cca1
name age message
file .gitignore Mon Oct 05 14:30:55 -0700 2009 Added rake taks spec:html to generate html repo... [robinsp]
file Capfile Thu Mar 12 19:03:12 -0700 2009 * partial support for createobjects w/ blob [#1... [larsburgess]
file LICENSE Thu Sep 18 11:37:40 -0700 2008 adding license [larsburgess]
file README.textile Mon Jan 26 14:32:59 -0800 2009 updating README w/ latest instructions [larsburgess]
file Rakefile Tue Dec 16 18:01:29 -0800 2008 adding bootstrap task [larsburgess]
directory app/ Wed Oct 28 17:30:00 -0700 2009 removing unused models [larsburgess]
directory config/ Sun Oct 25 08:14:00 -0700 2009 active branch is 1-2-stable [larsburgess]
directory db/ Wed Oct 28 17:30:00 -0700 2009 removing unused models [larsburgess]
directory doc/ Fri Sep 25 15:44:50 -0700 2009 * version 2 of protocol * fixed minor bug of de... [larsburgess]
directory jobs/ Wed Oct 07 17:06:29 -0700 2009 ensure arg is int not string [VGraupera]
directory lib/ Thu Oct 22 13:54:29 -0700 2009 refactoring client-mapping methods to Sync modu... [larsburgess]
directory public/ Thu Jul 16 17:59:06 -0700 2009 forcing this directory to stay [larsburgess]
directory script/ Thu Jun 25 18:28:24 -0700 2009 now that BJ works get rid of usage of both Sync... [adamblum]
directory spec/ Thu Oct 22 13:54:29 -0700 2009 refactoring client-mapping methods to Sync modu... [larsburgess]
directory stories/ Thu Dec 25 17:30:17 -0800 2008 contains the initial implementation of apps now... [adamblum]
directory test/ Wed Oct 28 17:30:00 -0700 2009 removing unused models [larsburgess]
directory vendor/ Mon Oct 26 10:24:25 -0700 2009 don't raise exception if backend record not fou... [larsburgess]
README.textile

RhoSync

Rhosync is a Ruby-based server to facilitate accessing information from backend applications and keeping that information
in sync with occasionally connected mobile devices. Specifically it is a Ruby on Rails application that allows managing groups of application objects exposed by a web service. The RhoSync server then manages synchronization of that information to and from mobile devices.

INTRODUCTION

RhoSync retrieves data via web services (REST or SOAP) from backend enterprise applications for distribution to downstream mobile devices. It keeps a master store of all enterprise application data and keeps track of the information that users have received. It is written to be far simpler to be far simpler to deploy and configure than similar technologies that have come and gone over the past 20 years.

It is also more focused on the complete end to end ‘web service backend’ to mobile device (with an enabling master data store on the server) than earlier equivalents. These products were generally focused on the device endpoint syncing to a server-based database. With the success of Software as a Service (SaaS) products such as SugarCRM and SalesForce, synchronization directly to a server database is much more rarely a viable option. Instead we focus on the web service access scenario. RhoSync is also focused on arbitrary enterprise application data as opposed to being a PIM and email focused product such as Funambol.

There is a RhoSync client embedded in the Rhodes runtime, but other RhoSync clients could be created.

PREREQUISITES

  • Ruby w/ rubygems installed
  • SQLite, MySQL or other database that plays nicely with Rails

INSTALLATION

sudo gem install rspec-rails rake git clone git://github.com/rhomobile/rhosync.git cd rhosync

Install your database driver of choice

sudo gem install sqlite3-ruby (-v=1.2.3 if you’re in windows) or sudo gem install msyql

If you don’t have the file “log/development.log” then go ahead and create the file:

mkdir -p log; touch log/development.log (or create manually if in windows)

Install required gems

sudo rake gems:install

Configure config/database.yml to tell rails how to connect to your database:

config/database.yml

Then run the db:bootstrap rake task provided, creating the database and associated tables that RhoSync needs. It will also load the source adapters that we ship with.

rake db:bootstrap

Then use your Rails server of choice to run the application. If you don’t have a Rails server, you can install mongrel with:

sudo gem install mongrel

Then start your server:

script/server

Then you can view the Sources from your web browser:

http://localhost:3000

If you login as “admin” (or create an account with the name “admin” by registering) you will see the default applications that RhoSync ships with (SugarCRM and Siebel), since they are by default owned by “admin”. Each of these has sync data sources associated with it.

h2. SET UP A DATA SOURCE

* Edit the “login”, “password” and “URL” fields if you are using one of the existing sources for SugarCRM or Siebel to correspond to your own URL
* Otherwise create a new Source from the application form and edit those same fields.
* If you are using another backend you will need to create an application and populate it with some data sources
* On the Source editing form supply Source Adapter class, the file for which must be located in the RhoSync /lib subdirectory
* OR you can create individual login, query, create, update and delete fields with the appropriate code. These methods (from the Source Adapter class or the form) will get called by the RhoSync server to populate data from a data source.


h2. HOW IT WORKS

Rhosync normalizes all backend application data into a common server-based database schema, in preparation for delivering the further downstream, generally to mobile devices.

Specifically the “master server data table” is a “property bag” (also known as an “entity-attribute-value” or EAV) model, which keeps track of data sources, individual objects and the name/value pairs for those objects. This allows handling of diverse backend application data structures within a single master store. It also provides for efficient delivery of single “fields” of data in either direction (e.g. just the status changing of a trouble ticket).

The connection code for logging into a backend application (via REST or SOAP APIs), calling the data retrieval, create, update and delete functions, logging off, and populating the master data table (OBJECT_VALUES described below) are each written in Ruby.

h2. DATABASE SCHEMA

There are three important tables that describe fully the universe of data sources and their contents for downstream syncing. These are the APPLICATIONS table, the SOURCES table and the OBJECT_VALUES table (and the corresponding Source and ObjectValues models).

h3. APPLICATIONS TABLE

A RhoSync Application is a grouped set of data source objects. It has the following columns:
* NAME – some string to identify the app
* DESCRIPTION – some text to describe the collection of source
* ADMIN (not exposed in the UI) – who “owns” the app, set to whoever created the app automatically by the RhoSync web UI

h3. SOURCES TABLE

This table contains all of the information necessary to connect to a given backend application object:

* URL – the URL to connect to (for REST adapters) or the URL to the WSDL (for SOAP services)
* SERVEROPTIONAL a logical name for the data source server (AcmeCorpSugar)
* LOGIN – the username or logon ID for the backend
* PASSWORD – password (stored in the clear right now) for the backend system
* SOURCE ADAPTER – this is the name of a class used for login, query, create, update and delete operations. The Ruby file for this class needs to be placed in the /lib subdirectory of your RhoSync installation.

OR you can enter all of the code for each of the methods in the fields below
* LOGIN – a set of Ruby code generally for logging into the backend system. Generally this is a SOAP or REST call which populates a session_id variable (that variable must be used in the call code below).
* CALL – the actual code for getting data back (generally uses the session_id acquired in the prolog)
* CREATECALL – code to create records in the backend from the object values table
* UPDATECALL – update code for the backend
* DELETECALL – record deletion code for the backend
* LOGOUTOPTIONAL, code to logoff the backend system
* SYNC – this is the code used to take apart the returned data and stuff it into the OBJECT_VALUES property bag table.
* APP_ID (not exposed in the UI) – this refers to the application that contains the data source

h3. OBJECT_VALUES

Thid table contains all of the actual instance data for all applications and sources.
* object – the unique identifier of the object (generally an integer “record ID” from the backend system)
* attribute – the name of the attribute (e.g. “Account Name”, “Industry”)
* value – the value of the attribute (e.g. “Acme Corp”, “software”)
* source_id – reference back to the source (see below) used for syncing

h2. GENERATING A SOURCE ADAPTER

The RhoGen utility supplied by Rhodes will generate a RhoSync Source Adapter class. For example:
rhogen source SugarAccounts

h2. SAMPLE SOURCE ADAPTER

This is a sample source adapter Rub class to retrieve and edit Sugar Account objects. It is the SugarAccounts.rb located in the /lib subdirectory of RhoSync.

class SugarAccounts < SourceAdapter

def initialize(source)
super(source)
end

def login
u = source.login p = Digest::MD5.hexdigest(source.password)
ua = {’user_name’ => u,‘password’ => p}
ss = client.login(ua,nil)
if ss.error.number.to_i != 0
p ‘failed to login – #{ss.error.description}’
return
else
session_id = ss['id'] uid = client.get_user_id(session_id)
end
end

def query
module_name = ‘Accounts’
query = ‘’ # gets all the acounts, you can also use SQL like ’accounts.name like ’%company%’’
order_by = ‘’ # in default order. you can also use SQL like ’accounts.name’
offset = 0
select_fields = [‘name’,‘industry’] # this can’t be an empty array
max_results = ‘10000’ # if set to 0 or ‘’, this doesn’t return all the results
deleted = 0 # whether you want to retrieve deleted records, too
result = client.get_entry_list(session_id,module_name,query,order_by,offset,select_fields,max_results,deleted);
end

def sync
result.entry_list.each do |x| x.name_value_list.each do |y| o=ObjectValue.new o.source_id=source.id
o.object=x[‘id’]
o.attrib=y.name
o.value=y.value
o.save
end
end
end

def create(name_value_list)
result=client.set_entry(@session_id,‘Accounts’,name_value_list)
end

def update(name_value_list)
result=client.set_entry(@session_id,‘Accounts’,name_value_list)
end

def delete(name_value_list)
name_value_list.push({’name’=>’deleted’,‘value’=>’1’});
result=client.set_entry(@session_id,‘Accounts’,name_value_list)
end

def logoff
client.logout(@session_id)
end
end

h2. SUPPORT

Email us questions or, even better, post them to the Google Group called Rhomobile.