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.
- 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:
|