rhoconnect 3.0.0.beta1 → 3.0.0.beta3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: