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.
- data/CHANGELOG +16 -2
- data/Gemfile +14 -5
- data/Gemfile.lock +13 -23
- data/Rakefile +86 -0
- data/bench/bench_runner.rb +5 -4
- data/bench/benchapp/Gemfile +17 -8
- data/bench/blobapp/Gemfile +13 -14
- data/doc/adapters-crm.txt +226 -0
- data/doc/adapters-intro.txt +18 -0
- data/doc/client.txt +29 -2
- data/doc/heroku-addon.txt +54 -0
- data/doc/install.txt +1 -2
- data/doc/migration.txt +18 -6
- data/doc/net-plugin.txt +276 -0
- data/doc/plugin-intro.txt +6 -0
- data/doc/push.txt +1 -1
- data/doc/rails-plugin.txt +116 -0
- data/doc/rest-api.txt +2 -2
- data/doc/settings.txt +59 -0
- data/doc/tutorial.txt +8 -5
- data/generators/rhoconnect.rb +30 -0
- data/generators/templates/application/Gemfile +16 -7
- data/generators/templates/application/gitignore +4 -0
- data/install.sh +74 -106
- data/installer/deb-scripts/LICENSE +75 -0
- data/installer/deb-scripts/install.sh +300 -0
- data/installer/deb-scripts/scripts/rho_connect_install_constants.rb +32 -0
- data/installer/deb-scripts/scripts/rho_connect_install_installers.rb +103 -0
- data/installer/deb-scripts/scripts/rho_connect_install_utilities.rb +110 -0
- data/installer/deb-scripts/scripts/rhoinstaller.rb +55 -0
- data/installer/deb-scripts/utils/README +67 -0
- data/installer/deb-scripts/utils/create_texts.rb +76 -0
- data/installer/deb-scripts/utils/redis_init_script +124 -0
- data/installer/deb-scripts/utils/redis_log_rotate +8 -0
- data/installer/unix-like/install.sh +361 -0
- data/installer/unix-like/post-install.sh +8 -0
- data/installer/unix-like/pre-install.sh +8 -0
- data/installer/unix-like/rho_connect_install_constants.rb +9 -14
- data/installer/unix-like/rho_connect_install_debian.rb +7 -5
- data/installer/unix-like/rho_connect_install_dnd.rb +6 -6
- data/installer/unix-like/rho_connect_install_get_params.rb +1 -1
- data/installer/unix-like/rho_connect_install_installers.rb +39 -38
- data/installer/unix-like/rho_connect_install_utilities.rb +9 -10
- data/installer/unix-like/rho_connect_install_yum.rb +6 -5
- data/installer/unix-like/rhoinstaller.rb +8 -3
- data/installer/utils/create_texts.rb +313 -85
- data/installer/windows/rhosync.nsi +5 -5
- data/lib/rhoconnect/api/application/clientcreate.rb +1 -1
- data/lib/rhoconnect/api/application/clientregister.rb +1 -1
- data/lib/rhoconnect/api/application/clientreset.rb +1 -1
- data/lib/rhoconnect/client.rb +0 -1
- data/lib/rhoconnect/client_sync.rb +1 -0
- data/lib/rhoconnect/console/app/routes/home.rb +1 -1
- data/lib/rhoconnect/console/app/routes/user.rb +8 -3
- data/lib/rhoconnect/console/app/views/adapter.erb +2 -2
- data/lib/rhoconnect/console/app/views/ping.erb +14 -2
- data/lib/rhoconnect/console/app/views/users.erb +8 -1
- data/lib/rhoconnect/jobs/ping_job.rb +11 -3
- data/lib/rhoconnect/model.rb +2 -2
- data/lib/rhoconnect/read_state.rb +2 -0
- data/lib/rhoconnect/server.rb +4 -3
- data/lib/rhoconnect/source.rb +33 -6
- data/lib/rhoconnect/source_adapter.rb +5 -9
- data/lib/rhoconnect/source_sync.rb +11 -5
- data/lib/rhoconnect/store.rb +7 -4
- data/lib/rhoconnect/tasks.rb +3 -3
- data/lib/rhoconnect/version.rb +1 -1
- data/lib/rhoconnect.rb +22 -8
- data/rhoconnect.gemspec +4 -22
- data/spec/api/application/rhoconnect_api_spec.rb +54 -8
- data/spec/api/source/get_source_params_spec.rb +2 -1
- data/spec/api/source/list_sources_spec.rb +3 -3
- data/spec/app_spec.rb +8 -1
- data/spec/apps/rhotestapp/settings/settings.yml +10 -5
- data/spec/apps/rhotestapp/sources/other_adapter.rb +7 -0
- data/spec/client_sync_spec.rb +5 -8
- data/spec/dynamic_adapter_spec.rb +8 -8
- data/spec/generator/generator_spec.rb +4 -2
- data/spec/jobs/ping_job_spec.rb +53 -0
- data/spec/model_spec.rb +2 -2
- data/spec/rhosync_spec.rb +1 -1
- data/spec/server/server_spec.rb +3 -14
- data/spec/source_sync_spec.rb +84 -2
- data/spec/support/shared_examples.rb +2 -2
- data/tasks/redis.rake +2 -2
- metadata +30 -41
- 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
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',
|
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
|
|
data/doc/net-plugin.txt
ADDED
@@ -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<String, String, Hashtable, bool></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).
|
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,
|
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 =>
|
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
|
170
|
+
def initialize(source)
|
168
171
|
@base = 'http://rhostore.heroku.com/products'
|
169
|
-
super(source
|
172
|
+
super(source)
|
170
173
|
end
|
171
174
|
|
172
175
|
Then fill in the query method:
|