rhoconnect 3.0.0.beta1 → 3.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/CHANGELOG +16 -2
  2. data/Gemfile +14 -5
  3. data/Gemfile.lock +13 -23
  4. data/Rakefile +86 -0
  5. data/bench/bench_runner.rb +5 -4
  6. data/bench/benchapp/Gemfile +17 -8
  7. data/bench/blobapp/Gemfile +13 -14
  8. data/doc/adapters-crm.txt +226 -0
  9. data/doc/adapters-intro.txt +18 -0
  10. data/doc/client.txt +29 -2
  11. data/doc/heroku-addon.txt +54 -0
  12. data/doc/install.txt +1 -2
  13. data/doc/migration.txt +18 -6
  14. data/doc/net-plugin.txt +276 -0
  15. data/doc/plugin-intro.txt +6 -0
  16. data/doc/push.txt +1 -1
  17. data/doc/rails-plugin.txt +116 -0
  18. data/doc/rest-api.txt +2 -2
  19. data/doc/settings.txt +59 -0
  20. data/doc/tutorial.txt +8 -5
  21. data/generators/rhoconnect.rb +30 -0
  22. data/generators/templates/application/Gemfile +16 -7
  23. data/generators/templates/application/gitignore +4 -0
  24. data/install.sh +74 -106
  25. data/installer/deb-scripts/LICENSE +75 -0
  26. data/installer/deb-scripts/install.sh +300 -0
  27. data/installer/deb-scripts/scripts/rho_connect_install_constants.rb +32 -0
  28. data/installer/deb-scripts/scripts/rho_connect_install_installers.rb +103 -0
  29. data/installer/deb-scripts/scripts/rho_connect_install_utilities.rb +110 -0
  30. data/installer/deb-scripts/scripts/rhoinstaller.rb +55 -0
  31. data/installer/deb-scripts/utils/README +67 -0
  32. data/installer/deb-scripts/utils/create_texts.rb +76 -0
  33. data/installer/deb-scripts/utils/redis_init_script +124 -0
  34. data/installer/deb-scripts/utils/redis_log_rotate +8 -0
  35. data/installer/unix-like/install.sh +361 -0
  36. data/installer/unix-like/post-install.sh +8 -0
  37. data/installer/unix-like/pre-install.sh +8 -0
  38. data/installer/unix-like/rho_connect_install_constants.rb +9 -14
  39. data/installer/unix-like/rho_connect_install_debian.rb +7 -5
  40. data/installer/unix-like/rho_connect_install_dnd.rb +6 -6
  41. data/installer/unix-like/rho_connect_install_get_params.rb +1 -1
  42. data/installer/unix-like/rho_connect_install_installers.rb +39 -38
  43. data/installer/unix-like/rho_connect_install_utilities.rb +9 -10
  44. data/installer/unix-like/rho_connect_install_yum.rb +6 -5
  45. data/installer/unix-like/rhoinstaller.rb +8 -3
  46. data/installer/utils/create_texts.rb +313 -85
  47. data/installer/windows/rhosync.nsi +5 -5
  48. data/lib/rhoconnect/api/application/clientcreate.rb +1 -1
  49. data/lib/rhoconnect/api/application/clientregister.rb +1 -1
  50. data/lib/rhoconnect/api/application/clientreset.rb +1 -1
  51. data/lib/rhoconnect/client.rb +0 -1
  52. data/lib/rhoconnect/client_sync.rb +1 -0
  53. data/lib/rhoconnect/console/app/routes/home.rb +1 -1
  54. data/lib/rhoconnect/console/app/routes/user.rb +8 -3
  55. data/lib/rhoconnect/console/app/views/adapter.erb +2 -2
  56. data/lib/rhoconnect/console/app/views/ping.erb +14 -2
  57. data/lib/rhoconnect/console/app/views/users.erb +8 -1
  58. data/lib/rhoconnect/jobs/ping_job.rb +11 -3
  59. data/lib/rhoconnect/model.rb +2 -2
  60. data/lib/rhoconnect/read_state.rb +2 -0
  61. data/lib/rhoconnect/server.rb +4 -3
  62. data/lib/rhoconnect/source.rb +33 -6
  63. data/lib/rhoconnect/source_adapter.rb +5 -9
  64. data/lib/rhoconnect/source_sync.rb +11 -5
  65. data/lib/rhoconnect/store.rb +7 -4
  66. data/lib/rhoconnect/tasks.rb +3 -3
  67. data/lib/rhoconnect/version.rb +1 -1
  68. data/lib/rhoconnect.rb +22 -8
  69. data/rhoconnect.gemspec +4 -22
  70. data/spec/api/application/rhoconnect_api_spec.rb +54 -8
  71. data/spec/api/source/get_source_params_spec.rb +2 -1
  72. data/spec/api/source/list_sources_spec.rb +3 -3
  73. data/spec/app_spec.rb +8 -1
  74. data/spec/apps/rhotestapp/settings/settings.yml +10 -5
  75. data/spec/apps/rhotestapp/sources/other_adapter.rb +7 -0
  76. data/spec/client_sync_spec.rb +5 -8
  77. data/spec/dynamic_adapter_spec.rb +8 -8
  78. data/spec/generator/generator_spec.rb +4 -2
  79. data/spec/jobs/ping_job_spec.rb +53 -0
  80. data/spec/model_spec.rb +2 -2
  81. data/spec/rhosync_spec.rb +1 -1
  82. data/spec/server/server_spec.rb +3 -14
  83. data/spec/source_sync_spec.rb +84 -2
  84. data/spec/support/shared_examples.rb +2 -2
  85. data/tasks/redis.rake +2 -2
  86. metadata +30 -41
  87. data/spec/api/rhosync_api_spec.rb.orig +0 -606
@@ -0,0 +1,54 @@
1
+ Heroku Addon
2
+ ==========
3
+
4
+ RhoConnect is now available for those using <a href='http://heroku.com' target='_blank'>Heroku</a> as an addon.
5
+
6
+
7
+
8
+ Adding RhoConnect from Heroku
9
+ -----------------------
10
+ To use RhoConnect from Heroku, install the RhoConnect add-on:
11
+
12
+ :::term
13
+ $ heroku addons:add rhoconnect
14
+
15
+ ###Setup
16
+
17
+ From inside your heroku account, setup the url to your backend service that RhoConnect will connect to.
18
+
19
+ First, click the addons drop down and select rhoconnect.
20
+ <p><img src='https://s3.amazonaws.com/rhodocs/rhoconnect-service/addon_rhoconnect.png' width="479" height="319"/></p>
21
+
22
+ You will be redirected to the admin console of your RhoConnect instance where you can set the backend app url. Select Backend App Url from the right menu.
23
+ <p><img src='https://s3.amazonaws.com/rhodocs/rhoconnect-service/console.png' width="800" height="280"/></p>
24
+
25
+
26
+ From here you can enter a url to your backend service. Enter a url (for example http://myrailsapp.com), and click the add link to save the url.
27
+
28
+ RhoConnect is now setup with your backend service.
29
+
30
+ Connecting a simple rhodes app
31
+ -------------------------------
32
+ To view a full tutorial about creating a rhodes application and the features of rhodes see [Rhodes framework](http://docs.rhomobile.com/rhodes/tutorial).
33
+
34
+ ###Gem installation:
35
+
36
+ :::ruby
37
+ [sudo] gem install rhodes
38
+
39
+ Next using the rhodes gem you can create a rhodes app.
40
+
41
+ :::ruby
42
+ rhodes app sample_app url_of_rhoconnect_instance
43
+
44
+ To get the value for the url_of_rhoconnect_instance argument, go to the RhoConnect console and click on the right Backend App URL link. From there you can copy the syncserver url.
45
+
46
+ <p><img src='https://s3.amazonaws.com/rhodocs/rhoconnect-service/console.png' width="800" height="280"/></p>
47
+
48
+
49
+ ----
50
+ [RhoConnect Introduction](http://docs.rhomobile.com/rhosync/introduction)
51
+
52
+ [RhoConnect Installation](http://docs.rhomobile.com/rhosync/install)
53
+
54
+ [RhoConnect Tutorial](http://docs.rhomobile.com/rhosync/tutorial)
data/doc/install.txt CHANGED
@@ -24,5 +24,4 @@ Your RhoConnect application folder will be located in C:\RhoConnect\rhoconnect b
24
24
  To install the RhoConnect gem, run:
25
25
 
26
26
  :::term
27
- $ [sudo] gem install rhoconnect --pre
28
-
27
+ $ [sudo] gem install rhoconnect --pre
data/doc/migration.txt CHANGED
@@ -19,14 +19,25 @@ Create a new `Gemfile` file in your application directory with the following con
19
19
 
20
20
  gem 'rhoconnect', '3.0.0'
21
21
 
22
+ # Helps with some of the limitations of green threads, not needed in ruby 1.9.x
23
+ gem 'SystemTimer', '~> 1.2.3', :platforms => :ruby_18
24
+
25
+ platforms :jruby do
26
+ gem 'jdbc-sqlite3', ">= 3.7.2"
27
+ gem 'dbi', ">= 0.4.5"
28
+ gem 'dbd-jdbc', ">= 0.1.4"
29
+ gem 'jruby-openssl', ">= 0.7.4"
30
+ gem 'warbler'
31
+ end
32
+
33
+ gem 'sqlite3', ">= 1.3.3", :platforms => [:ruby, :mswin, :mingw]
34
+
35
+ # For jruby trinidad JRuby web server is used
36
+ gem 'trinidad', :platforms => :jruby
37
+
22
38
  group :development do
23
39
  # By default to run application thin web server is used
24
- gem 'thin', '1.2.11', :platforms => :ruby
25
-
26
- # For jruby trinidad JRuby web server is used
27
- gem 'trinidad', :platforms => :jruby
28
- # Alternative for jruby
29
- # gem 'jetty-rackup', :platforms => :jruby
40
+ gem 'thin', :platforms => [:ruby, :mswin, :mingw]
30
41
  end
31
42
 
32
43
  group :test do
@@ -34,6 +45,7 @@ Create a new `Gemfile` file in your application directory with the following con
34
45
  gem 'rspec', '~> 2.6.0'
35
46
  gem 'rcov', '>= 0.9.8'
36
47
  end
48
+
37
49
 
38
50
  ## Edit the Rakefile
39
51
 
@@ -0,0 +1,276 @@
1
+ rhoconnect.NET
2
+ ===
3
+
4
+ A .NET 4 framework library for the [Rhoconnect](http://rhomobile.com/products/rhosync) App Integration Server.
5
+
6
+ Using rhoconnect.NET, your [ASP.NET MVC3](http://www.asp.net/mvc/mvc3) application's data will transparently synchronize with a mobile application built on the [Rhodes framework](http://rhomobile.com/products/rhodes), or any of the available [Rhoconnect clients](http://rhomobile.com/products/rhosync/).
7
+
8
+ ## Getting started
9
+
10
+ Copy the [`rhoconnect.NET`](https://github.com/rhomobile/rhoconnect.NET) github repository to your PC:
11
+
12
+ $ git clone git@github.com:rhomobile/rhoconnect.NET.git
13
+
14
+ By default, the `rhoconnect.NET` repository contains the pre-built `RhoconnectNET.dll` library in the `bin/Release` subdirectory.
15
+ However, you can build your own library using the provided Microsoft Visual Studio .NET solution file and the source code files.
16
+
17
+ In order to use `Rhoconnect.NET` functionality in your `ASP.NET MVC 3` application, first you need to include the `Rhoconnect.NET` library
18
+ as a dependency to your application. Click `Project => Add Reference` menu item in the Visual Studio and navigate to the `RhoconnectNET.dll` library.
19
+ After this step is completed, you can add references to the `Rhoconnect.NET` namespace into the application's and Controller's files:
20
+
21
+ using RhoconnectNET;
22
+ using RhoconnectNET.Controllers;
23
+
24
+
25
+ ## Registering `Rhoconnect.NET` routes for your application
26
+
27
+ To establish the communication channel between ASP.NET MVC 3 application and Rhoconnect server,
28
+ you need to implement the following `init_rhoconnect` and `rhoconnect_authenticate` methods in the `Global.asax.cs` file
29
+ and call them from the `Application_Start` method:
30
+
31
+ protected void Application_Start()
32
+ {
33
+ ... ASP.NET initialization routines ...
34
+ ... typically, registering routes and filters is done here ...
35
+
36
+ // after app is properly initialized
37
+ // call RhoconnectNET initialization
38
+ init_rhoconnect();
39
+ }
40
+
41
+ // implement init_rhoconnect() method to establish
42
+ // communication link between `Rhoconnect` server
43
+ // and ASP.NET MVC 3 application
44
+ const bool init_rhoconnect()
45
+ {
46
+ // this call allows parsing JSON structures into Objects
47
+ ValueProviderFactories.Factories.Add(new JsonValueProviderFactory());
48
+
49
+ // this call establishes communication between Rhoconnect and ASP.NET application
50
+ // as a last parameter we supply authentication routine that will called
51
+ // by rhoconnect server to authenticate users.
52
+ RhoconnectNET.Client.set_app_endpoint("my_rhoconnect_server_url",
53
+ "my_mvc_app_root_url",
54
+ "rhoconnect_api_token",
55
+ rhoconnect_authenticate);
56
+ }
57
+
58
+ const bool rhoconnect_authenticate(String username, String password, Hashtable params)
59
+ {
60
+ // perform your authentication here
61
+ return true;
62
+ }
63
+
64
+ `RhoconnectNET.Client.set_app_point` method is a main point
65
+ in establishing the communication link between `Rhoconnect` server and the ASP.NET MVC 3 application
66
+ and it has the following parameters:
67
+
68
+ <table border="1">
69
+ <tr>
70
+ <td>String</td>
71
+ <td><code>rhoconnect_url</code></td>
72
+ <td>rhoconnect server's url, for example <code>http://localhost:9292</code>.</td>
73
+ </tr>
74
+ <tr>
75
+ <td>String</td>
76
+ <td><code>app_endpoint</code></td>
77
+ <td>your MVC app url, for example <code>http://my_pc_host/MyApp</code>.</td>
78
+ </tr>
79
+ <tr>
80
+ <td>String</td>
81
+ <td><code>api_token</code></td>
82
+ <td>rhoconnect server's api_token, for example <code>secrettoken</code>.</td>
83
+ </tr>
84
+ <tr>
85
+ <td>Func&lt;String, String, Hashtable, bool&gt;</td>
86
+ <td><code>Authenticating_Routine</code></td>
87
+ <td>handle to the application's authenticating routine (if null, <code>true</code> is returned by default).</td>
88
+ </tr>
89
+ </table>
90
+
91
+ `Rhoconnect.NET` installs a `/rhoconnect/authenticate` route into your application which will receive credentials from the client.
92
+ By providing the `rhoconnect_authenticate` method and registering it with the `Rhoconnect.NET` in the `set_app_endpoint`
93
+ method, you map your application specific authentication to the Rhoconnect `authenticate` requests:
94
+
95
+ const bool rhoconnect_authenticate(String username, String password, Hashtable params)
96
+ {
97
+ // perform real authentication here
98
+ return true;
99
+ }
100
+
101
+ ## Implementing CRUD functionality
102
+ `Rhoconnect.NET` lib installs `/rhoconnect/<CRUD>` routes in your application which the Rhoconnect instance
103
+ invokes to perform CRUD operations on the data for the dataset you want to synchronize.
104
+ Each of the routes is mapped to a corresponding `rhoconnect_<operation>` method in the **IRhoconnectCRUD** interface
105
+ which you must implement in the dataset's Controller class.
106
+
107
+ public class MyDataController : Controller, IRhoconnectCRUD
108
+ {
109
+ ... implementation of Controller routes
110
+
111
+ // next four methods must be implemented
112
+ // and will be called by Rhoconnect server
113
+ JsonResult rhoconnect_query_objects(String partition);
114
+ ActionResult rhoconnect_create(String objJson, String partition);
115
+ ActionResult rhoconnect_update(Dictionary<string, object> changes, String partition);
116
+ ActionResult rhoconnect_delete(Object objId, String partition);
117
+ }
118
+
119
+ ## Query the datasets
120
+ The route `/rhoconnect/query` is mapped to the `rhoconnect_query_objects` method of the **IRhoconnectCRUD**
121
+ interface that you must implement in the corresponding dataset's Controller class. It must
122
+ return a collection of source objects in the form of a JsonResult:
123
+
124
+ JsonResult rhoconnect_query_objects(String partition)
125
+ {
126
+ return Json(db.Products.ToDictionary("id"));
127
+ }
128
+
129
+ In the above example, the Products object set is converted to `Dictionary<String, Object>`
130
+ where the dictionary's key must correspond to an unique object's `id` field.
131
+ After dictionary is created , it is converted to JsonResult and sent to the Rhoconnect server.
132
+
133
+ ## Create new objects
134
+ The route `/rhoconnect/create` is mapped to the `rhoconnect_create` method of the IRhoconnectCRUD
135
+ interface that you must implement in the corresponding dataset's Controller class. It should
136
+ return a newly created object's id in case of success:
137
+
138
+ public ActionResult rhoconnect_create(String objJson, String partition)
139
+ {
140
+ Product new_product = (Product)RhoconnectNET.Helpers.deserialize_json(objJson, typeof(Product));
141
+ db.Products.AddObject(new_product);
142
+ db.SaveChanges();
143
+ return RhoconnectNET.Helpers.serialize_result(new_product.id);
144
+ }
145
+
146
+ ## Update existing objects
147
+ In the similar fashion, the route `/rhoconnect/update` is mapped to the `rhoconnect_update` method of the IRhoconnectCRUD
148
+ interface that you must implement in the corresponding dataset's Controller class. It should
149
+ return an updated object's id in case of success:
150
+
151
+ public ActionResult rhoconnect_update(Dictionary<string, object> changes, String partition)
152
+ {
153
+ String obj_id = changes["id"]);
154
+ Product product_to_update = db.Products.First(p => p.id == obj_id);
155
+ // this method will update only the modified fields
156
+ RhoconnectNET.Helpers.merge_changes(product_to_update, changes);
157
+ db.ObjectStateManager.ChangeObjectState(product_to_update, EntityState.Modified);
158
+ db.SaveChanges();
159
+ return RhoconnectNET.Helpers.serialize_result(obj_id);
160
+ }
161
+
162
+ ## Delete objects from the dataset
163
+ The route `/rhoconnect/delete` is mapped to the `rhoconnect_delete` method of the IRhoconnectCRUD
164
+ interface that you must implement in the corresponding dataset's Controller class. It should
165
+ return a deleted object's id in case of success:
166
+
167
+ public ActionResult rhoconnect_delete(Object objId, String partition)
168
+ {
169
+ String key = objId.ToString();
170
+
171
+ Product product_to_delete = db.Products.Single(p => p.id == key);
172
+ db.Products.DeleteObject(product_to_delete);
173
+ db.SaveChanges();
174
+ return RhoconnectNET.Helpers.serialize_result(objId);
175
+ }
176
+
177
+ ## Partitioning Datasets
178
+ Each of the above methods have a partition key supplied with the CRUD request. This partition key is used by `Rhoconnect` to uniquely identify the model dataset when it is stored in a rhoconnect instance. It is typically an attribute on the model or related model. `Rhoconnect` supports two types of partitions:
179
+
180
+ * :app - No unique key will be used, a shared dataset is synchronized for all users.
181
+ * lambda { some lambda } - Execute a lambda which returns the unique key string.
182
+
183
+ For example, the `Product` model above might have a relationship to the User model. This provides us a simple way to organize the `Product` dataset for rhoconnect by reusing this relationship.
184
+ In this case, your implementation might filter out data on a per user basis.
185
+
186
+ For more information about Rhoconnect partitions, please refer to the [Rhoconnect docs](http://docs.rhomobile.com/rhosync/source-adapters#data-partitioning).
187
+
188
+ ## Implementing MVC callbacks
189
+ All of the above methods are necessary to establish the communication from the Rhoconnect instance to your ASP.NET MVC application.
190
+ However, to complete the implementation, it is necessary to implement a reverse way to notify the Rhoconnect instance about the changes made in your MVC app.
191
+ Typically, your MVC Controller class reacts to the actions by implementing the CRUD POST routes, for example:
192
+
193
+ [HttpPost]
194
+ public ActionResult Create(Product new_product)
195
+ {
196
+ if (ModelState.IsValid)
197
+ {
198
+ db.Product.AddObject(new_product);
199
+ db.SaveChanges();
200
+ return RedirectToAction("Index");
201
+ }
202
+
203
+ return View(new_product);
204
+ }
205
+
206
+ Here, you need to insert a call which will notify the Rhoconnect instance that a new object has been created.
207
+ For this reason, `RhoconnectNET` library provides three callback routines for CUD notifications.
208
+ The above example will look like this after inserting the corresponding callback routine:
209
+
210
+ [HttpPost]
211
+ public ActionResult Create(Product product)
212
+ {
213
+ if (ModelState.IsValid)
214
+ {
215
+ db.Product.AddObject(product);
216
+ db.SaveChanges();
217
+
218
+ // insert these lines to provide
219
+ // notifications to Rhoconnect server
220
+ Hashtable reqHash = new Hashtable();
221
+ reqHash.Add(new_product.id.ToString(), new_products);
222
+ RhoconnectNET.Client.notify_on_create("Product", "partition_string", reqHash);
223
+
224
+ return RedirectToAction("Index");
225
+ }
226
+
227
+ return View(new_product);
228
+ }
229
+
230
+ In the example above, user need to call `RhoconnectNET.Client.notify_on_create` method
231
+ with the following parameters:
232
+
233
+ - String rhoconnect_source_name : dataset's name
234
+ - String rhoconnect_partition : partition to which the object belongs (see above section "Partitioning datasets")
235
+ - Hashtable<String, Object> object_hash : Hashtable with object's id as a key and the object itself as a value
236
+
237
+ In the same fashion , your dataset's Controller need to implement `Edit` and `Delete` callback notifications:
238
+
239
+ [HttpPost]
240
+ public ActionResult Edit(Product product)
241
+ {
242
+ if (ModelState.IsValid)
243
+ {
244
+ db.Products.Attach(product);
245
+ db.ObjectStateManager.ChangeObjectState(product, EntityState.Modified);
246
+ db.SaveChanges();
247
+
248
+ // insert this callback to notify Rhoconnect
249
+ // about the update operation
250
+ Hashtable reqHash = new Hashtable();
251
+ reqHash.Add(product.id.ToString(), product);
252
+ RhoconnectNET.Client.notify_on_update("Product", "partition_string", reqHash);
253
+
254
+ return RedirectToAction("Index");
255
+ }
256
+ return View(product);
257
+ }
258
+
259
+ [HttpPost, ActionName("Delete")]
260
+ public ActionResult DeleteConfirmed(String id)
261
+ {
262
+ Product product = db.Products.Single(p => p.id == id);
263
+ db.Products.DeleteObject(product);
264
+ db.SaveChanges();
265
+
266
+ // insert this callback to notify Rhoconnect
267
+ // about the delete operation
268
+ RhoconnectNET.Client.notify_on_delete("Product", rhoconnect_partition(), id);
269
+
270
+ return RedirectToAction("Index");
271
+ }
272
+
273
+ ## Meta
274
+ Created and maintained by Maxim Zverev.
275
+
276
+ Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
@@ -0,0 +1,6 @@
1
+ RhoConnect Plugins Introduction
2
+ ===
3
+
4
+ Rhoconnect Plugins allow you to connect your backend apps seamlessly with rhoconnect.
5
+
6
+ <img src='https://s3.amazonaws.com/rhodocs/rhoconnect-service/intro-plugin.png' alt='image' height='467' width='800' />
data/doc/push.txt CHANGED
@@ -48,7 +48,7 @@ To setup your RhoConnect application for Android push, you will need to update `
48
48
 
49
49
  Replace `:authtoken:` value with actual authentication token. This token MUST be related to the role-based google account registered for your application. See [the rhodes push instructions](/rhodes/device-caps#push-notifications) for more details. To retrieve this token, use sample script [c2dm.rb](http://github.com/rhomobile/rhodes/blob/master/bin/c2dm.rb). Uncomment last two lines and put your google account specific data, then run it. It will print token to stdout.
50
50
 
51
- For those who interested in what this token means, here is the description: <a href="http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html"/>.
51
+ For those who interested in what this token means, the description is [here](http://code.google.com/apis/accounts/docs/AuthForInstalledApps.html).
52
52
 
53
53
  Now start up your RhoConnect application and setup [push notifications](/rhodes/device-caps#push-notifications) in your Rhodes application.
54
54
 
@@ -0,0 +1,116 @@
1
+ rhoconnect-rb
2
+ ===
3
+
4
+ A ruby library for the [Rhoconnect](http://rhomobile.com/products/rhosync) App Integration Server.
5
+
6
+ Using rhoconnect-rb, your application's model data will transparently synchronize with a mobile application built on the [Rhodes framework](http://rhomobile.com/products/rhodes), or any of the available [Rhoconnect clients](http://rhomobile.com/products/rhosync/). This client includes built-in support for [ActiveRecord](http://ar.rubyonrails.org/) and [DataMapper](http://datamapper.org/) models.
7
+
8
+ ## Getting started
9
+
10
+ Load the `rhoconnect-rb` library:
11
+
12
+ require 'rhoconnect-rb'
13
+
14
+ Note, if you are using datamapper, install the `dm-serializer` library and require it in your application. `rhoconnect-rb` depends on this utility to interact with Rhoconnect applications using JSON.
15
+
16
+ ## Usage
17
+ Now include Rhoconnect::Resource in a model that you want to synchronize with your mobile application:
18
+
19
+ class Product < ActiveRecord::Base
20
+ include Rhoconnect::Resource
21
+ end
22
+
23
+ Or, if you are using DataMapper:
24
+
25
+ class Product
26
+ include DataMapper::Resource
27
+ include Rhoconnect::Resource
28
+ end
29
+
30
+ ### Partitioning Datasets
31
+
32
+ Next, your models will need to declare a partition key for `rhoconnect-rb`. This partition key is used by `rhoconnect-rb` to uniquely identify the model dataset when it is stored in a rhoconnect instance. It is typically an attribute on the model or related model. `rhoconnect-rb` supports two types of partitions:
33
+
34
+ * :app - No unique key will be used, a shared dataset is synchronized for all users.
35
+ * lambda { some lambda } - Execute a lambda which returns the unique key string.
36
+
37
+ For example, the `Product` model above might have a `belongs_to :user` relationship. This provides us a simple way to organize the `Product` dataset for rhoconnect by reusing this relationship. The partition identifying a username would be declared as:
38
+
39
+ class Product < ActiveRecord::Base
40
+ include Rhoconnect::Resource
41
+
42
+ belongs_to :user
43
+
44
+ def partition
45
+ lambda { self.user.username }
46
+ end
47
+ end
48
+
49
+ Now all of the `Product` data synchronized by rhoconnect will organized by `self.user.username`. Note: You can also used a fixed key if the dataset doesn't require a dynamic value:
50
+
51
+ def partition
52
+ :app
53
+ end
54
+
55
+ For more information about Rhoconnect partitions, please refer to the [Rhoconnect docs](http://docs.rhomobile.com/rhosync/source-adapters#data-partitioning).
56
+
57
+ ### Querying Datasets
58
+
59
+ `rhoconnect-rb` installs a `/rhoconnect/query` route in your application which the Rhoconnect instance invokes to query the dataset for the dataset you want to synchronize. This route is mapped to a `rhoconnect_query` method in your model. This method should return a collection of objects:
60
+
61
+ class Product < ActiveRecord::Base
62
+ include Rhoconnect::Resource
63
+
64
+ belongs_to :user
65
+
66
+ def partition
67
+ lambda { self.user.username }
68
+ end
69
+
70
+ def self.rhoconnect_query(partition)
71
+ Product.where(:user_id => partition)
72
+ end
73
+ end
74
+
75
+ In this example, `self.rhoconnect_query` returns a list of products where the partition string (provided by the rhoconnect instance) matches the `user_id` field in the products table.
76
+
77
+ ### Configuration and Authentication
78
+
79
+ Configure Rhoconnect in an initializer like `config/initializers/rhoconnect.rb` (for Rails), or directly in your application (i.e. Sinatra). Here you will setup the rhoconnect uri (the location of your rhoconnect instance), and app\_endpoint (the location of your ruby app):
80
+
81
+
82
+ # Use rhoconnect:get_token to get the token value.
83
+
84
+ config.uri = "http://myrhoconnect.com"
85
+ config.token = "secrettoken"
86
+ config.app_endpoint = "http://myapp.heroku.com"
87
+
88
+ If `app_endpoint` is defined, your Rhoconnect instance will be configured to query data from the endpoint using the rhoconnect_query method in your model. For example, if your `app_endpoint` is defined as "http://myapp.heroku.com", Rhoconnect will query data with:
89
+
90
+ POST http://myapp.heroku.com/rhoconnect/query
91
+
92
+ Example:
93
+
94
+ Rhoconnect.configure do |config|
95
+ config.uri = "http://myrhoconnect-server.com"
96
+ config.token = "secrettoken"
97
+ config.app_endpoint = "http://myapp.heroku.com"
98
+ end
99
+
100
+ Example with authentication:
101
+
102
+ `rhoconnect-rb` installs a `/rhoconnect/authenticate` route into your application which will receive credentials from the client. Add block which handles the credentials:
103
+
104
+ Rhoconnect.configure do |config|
105
+ config.uri = "http://myrhoconnect-server.com"
106
+ config.token = "secrettoken"
107
+ config.authenticate = lambda { |credentials|
108
+ User.authenticate(credentials[:login], credentials[:password])
109
+ }
110
+ end
111
+
112
+
113
+ ## Meta
114
+ Created and maintained by Lucas Campbell-Rossen, Vladimir Tarasov and Lars Burgess.
115
+
116
+ Released under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
data/doc/rest-api.txt CHANGED
@@ -69,7 +69,7 @@ Reset the server: flush db and re-bootstrap server
69
69
  )
70
70
 
71
71
  ### `ping`
72
- Sends PUSH message to all devices of the specified user:
72
+ Sends PUSH message to all devices of the specified user(s):
73
73
 
74
74
  :::ruby
75
75
  # :message - message which will be used to display notification popup dialog on the device
@@ -79,7 +79,7 @@ Sends PUSH message to all devices of the specified user:
79
79
  # :sources - list of data source names to be synced upon receiving PUSH notification
80
80
  ping_params = {
81
81
  :api_token => token,
82
- :user_id => user_id,
82
+ :user_id => [array_of_users],
83
83
  :sources => source_name,
84
84
  :message => 'hello world',
85
85
  :vibrate => 2000,
data/doc/settings.txt ADDED
@@ -0,0 +1,59 @@
1
+ RhoConnect settings
2
+ ===
3
+
4
+ All Rhoconnect application and source settings located in the *`settings/settings.yml`* file.
5
+ There are two main categories: application environment settings and source settings.
6
+
7
+ ## Application settings
8
+
9
+ Application-wide settings are specified per deployment environment (`:test`, `:development`, `:production`).
10
+ Each of the environment categories must have the following entries:
11
+
12
+ :::yaml
13
+ :syncserver: <url> - application's base url
14
+ :redis: <url> - Redis url
15
+ :licensefile: <filename> - application's license file
16
+
17
+ In addition, the following settings can be specified:
18
+
19
+ :::yaml
20
+ :poll_interval_default: <secs> - default sync poll interval setting for source adapters.
21
+ This setting is used as a default if source doesn't specify
22
+ its own value. Also, it is applied to dynamic adapters
23
+ as a default sync poll interval.
24
+ :bulk_data_poll_interval: <secs> - poll interval setting for bulk data sync
25
+
26
+ ## Source settings
27
+
28
+ All source-specific settings are specified under the corresponding source name entry in the `:sources` category.
29
+ Typical source settings include:
30
+
31
+ :::yaml
32
+ :poll_interval: <secs> - source's sync poll interval.
33
+ :force_default: <true|false> - if specified, this setting forces to use
34
+ default application poll interval
35
+ even if source has its own setting.
36
+ :partition_type: <app|user> - default partition type for the source
37
+ :retry_limit: <number_of_retries> - this option allows to for the user to
38
+ perform sync upto <number_of_retries> times
39
+ in case of previous sync failure.
40
+ Normally, each sync resets the refresh time
41
+ according to the polling interval regardless
42
+ of the sync success or failure. In case of failure,
43
+ it may not be a desired scenario because user will
44
+ be getting an error on all sync attempts until
45
+ the next polling interval will expire. This setting
46
+ allows to overcome this issue.The following flow
47
+ shows the algorithm in place:
48
+
49
+ 1) If sync fails and :retry_limit is set to N > 0,
50
+ refresh_time is not updated for next N retries (or until any of them succeeds).
51
+ Here 'retry' means that user will be able to initiate another sync request
52
+ (since refresh_time is not updated).
53
+
54
+ 2) If one of the retry succeeds - source's refresh time is updated and retry counter is reset.
55
+ 3) If the `:retry_limit` is reached and all attempts have failed -
56
+ source's refresh time is updated to prevent excessive polling on the permanently down backend.
57
+ 4) Also, if more then `:poll_interval` seconds has elapsed
58
+ since last refresh_time - source's retry counter is reset.
59
+
data/doc/tutorial.txt CHANGED
@@ -18,11 +18,16 @@ Now you are ready to write your RhoConnect app. You can generate an app with th
18
18
  :::term
19
19
  $ rhoconnect app storemanager-server
20
20
  $ cd storemanager-server/
21
+
22
+ Next, install the application's dependencies. RhoConnect applications use [bundler](http://gembundler.com/) to manage dependencies, so you can install them with:
23
+
24
+ :::term
25
+ $ [sudo] bundle install
21
26
 
22
27
  **If you are running this for the first time on Mac or Linux**, you will need to install [dtach](http://dtach.sourceforge.net/):
23
28
 
24
29
  :::term
25
- $ sudo rake dtach:install
30
+ $ [sudo] rake dtach:install
26
31
 
27
32
  ### Verify Installation
28
33
 
@@ -36,8 +41,6 @@ If everything went well you should see:
36
41
 
37
42
  [07:01:15 PM 2010-05-04] Rhoconnect Server v3.0.0 started...
38
43
 
39
- **NOTE: You will be prompted to edit the session secret in your config.ru to something other than "\<changeme\>"**
40
-
41
44
  Defining RhoConnect Source Adapters
42
45
  ---
43
46
 
@@ -164,9 +167,9 @@ We need to declare the standard libraries that we are using at the top of the fi
164
167
  For convenience, we'll add an instance variable @base which contains the base URL of the web service and set the value in the constructor:
165
168
 
166
169
  :::ruby
167
- def initialize(source,credential)
170
+ def initialize(source)
168
171
  @base = 'http://rhostore.heroku.com/products'
169
- super(source,credential)
172
+ super(source)
170
173
  end
171
174
 
172
175
  Then fill in the query method: