rhoconnect 3.4.5 → 4.0.0.beta.10

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 (337) hide show
  1. data/CHANGELOG.md +57 -3
  2. data/Gemfile +9 -7
  3. data/Gemfile.lock +37 -37
  4. data/Rakefile +18 -7
  5. data/bench/benchapp/Gemfile +1 -1
  6. data/bench/benchapp/config.ru +0 -3
  7. data/bench/benchapp/controllers/ruby/application.rb +17 -0
  8. data/bench/benchapp/controllers/ruby/application_controller.rb +17 -0
  9. data/bench/benchapp/controllers/ruby/mock_adapter_controller.rb +8 -0
  10. data/bench/benchapp/controllers/ruby/queue_mock_adapter_controller.rb +8 -0
  11. data/bench/benchapp/{sources → models/ruby}/mock_adapter.rb +1 -1
  12. data/bench/benchapp/{sources → models/ruby}/queue_mock_adapter.rb +0 -0
  13. data/bench/benchapp/spec/{sources → models/ruby}/mock_adapter_spec.rb +1 -1
  14. data/bench/benchapp/spec/{sources → models/ruby}/queue_mock_adapter_spec.rb +1 -1
  15. data/bench/benchapp/spec/spec_helper.rb +2 -2
  16. data/bench/blobapp/Gemfile +1 -1
  17. data/bench/blobapp/config.ru +0 -3
  18. data/bench/blobapp/controllers/ruby/application_controller.rb +17 -0
  19. data/bench/blobapp/controllers/ruby/blob_adapter_controller.rb +8 -0
  20. data/bench/blobapp/{sources → models/ruby}/blob_adapter.rb +9 -2
  21. data/bench/blobapp/spec/{sources → models/ruby}/blob_adapter_spec.rb +1 -1
  22. data/bench/blobapp/spec/spec_helper.rb +1 -1
  23. data/bench/lib/bench/cli.rb +1 -1
  24. data/bench/scripts/blob_cud_script.rb +1 -1
  25. data/bench/scripts/query_md_script.rb +1 -1
  26. data/bench/scripts/query_only_script.rb +1 -1
  27. data/bench/scripts/query_script.rb +1 -1
  28. data/bench/scripts/test_query_script.rb +7 -1
  29. data/bench/spec/mock_adapter_spec.rb +1 -1
  30. data/bench/spec/result_spec.rb +3 -3
  31. data/bin/rhoconnect +5 -3
  32. data/commands/dtach/dtach_install.rb +2 -2
  33. data/commands/execute.rb +8 -3
  34. data/commands/generators/app.rb +3 -3
  35. data/commands/generators/controller.rb +6 -0
  36. data/commands/generators/model.rb +6 -0
  37. data/commands/generators/source.rb +3 -3
  38. data/commands/generators/update.rb +1 -1
  39. data/commands/redis/redis_about.rb +2 -2
  40. data/commands/redis/redis_download.rb +1 -1
  41. data/commands/redis/redis_install.rb +4 -3
  42. data/commands/redis/redis_restart.rb +4 -4
  43. data/commands/redis/redis_start.rb +5 -4
  44. data/commands/redis/redis_startbg.rb +5 -4
  45. data/commands/redis/redis_status.rb +13 -0
  46. data/commands/redis/redis_stop.rb +3 -3
  47. data/commands/rhoconnect/config.rb +28 -16
  48. data/commands/rhoconnect/flushdb.rb +1 -2
  49. data/commands/rhoconnect/get_token.rb +15 -11
  50. data/commands/rhoconnect/restart.rb +13 -5
  51. data/commands/rhoconnect/set_admin_password.rb +8 -8
  52. data/commands/rhoconnect/start.rb +74 -16
  53. data/commands/rhoconnect/startbg.rb +1 -1
  54. data/commands/rhoconnect/startdebug.rb +1 -1
  55. data/commands/rhoconnect/stop.rb +13 -1
  56. data/commands/rhoconnect/web.rb +5 -5
  57. data/commands/rhoconnect_console/console.rb +7 -5
  58. data/commands/{rhoconnect → rhoconnect_spec}/spec.rb +0 -0
  59. data/commands/rhoconnect_war/war.rb +9 -9
  60. data/commands/utilities/blank_app.ru +56 -0
  61. data/commands/utilities/redis_runner.rb +54 -19
  62. data/doc/authentication.txt +80 -6
  63. data/doc/blob-sync.txt +104 -97
  64. data/doc/bulk-sync.txt +1 -1
  65. data/doc/client-java.txt +3 -3
  66. data/doc/client-objc.txt +2 -2
  67. data/doc/client.txt +4 -4
  68. data/doc/command-line.txt +105 -200
  69. data/doc/data-partitioning.txt +40 -0
  70. data/doc/deploying.txt +249 -77
  71. data/doc/extending-rhoconnect-server.txt +40 -57
  72. data/doc/heroku-addon.txt +2 -0
  73. data/doc/install.txt +45 -95
  74. data/doc/introduction.txt +1 -1
  75. data/doc/java-plugin.txt +365 -190
  76. data/doc/metadata.txt +1 -1
  77. data/doc/migration.txt +108 -142
  78. data/doc/preparing-production.txt +1 -1
  79. data/doc/push-backend-setup.txt +2 -0
  80. data/doc/push-client-setup-android.txt +78 -0
  81. data/doc/push-client-setup-bb.txt +81 -0
  82. data/doc/push-client-setup-ios.txt +70 -0
  83. data/doc/push-client-setup-rps.txt +200 -0
  84. data/doc/push-client-setup.txt +63 -66
  85. data/doc/push-server-setup.txt +67 -40
  86. data/doc/push-testing.txt +29 -0
  87. data/doc/push.txt +21 -6
  88. data/doc/rest-api.txt +128 -55
  89. data/doc/rhoconnect-redis-stack.txt +120 -0
  90. data/doc/settings.txt +4 -12
  91. data/doc/source-adapters-intro.txt +28 -0
  92. data/doc/source-adapters.txt +235 -272
  93. data/doc/stats-middleware.txt +9 -29
  94. data/doc/supported-platforms.txt +21 -30
  95. data/doc/testing.txt +40 -42
  96. data/doc/tutorial.txt +72 -57
  97. data/examples/simple/Gemfile +1 -1
  98. data/examples/simple/application.rb +4 -5
  99. data/examples/simple/my_server.rb +2 -2
  100. data/examples/simple/settings/settings.yml +1 -1
  101. data/generators/rhoconnect.rb +151 -50
  102. data/generators/templates/application/Gemfile +1 -1
  103. data/generators/templates/application/Rakefile +3 -3
  104. data/generators/templates/application/config.ru +1 -4
  105. data/generators/templates/application/controllers/application_controller.rb +17 -0
  106. data/generators/templates/application/controllers/js/application_controller.js +14 -0
  107. data/generators/templates/application/controllers/ruby/application_controller.rb +17 -0
  108. data/generators/templates/application/package.json +8 -0
  109. data/generators/templates/application/rcgemfile +2 -5
  110. data/generators/templates/application/settings/settings.yml +3 -3
  111. data/generators/templates/application/spec/application_controller_spec.rb +23 -0
  112. data/generators/templates/application/spec/js_spec.rb +25 -0
  113. data/generators/templates/application/spec/spec_helper.rb +21 -7
  114. data/generators/templates/source/controllers/js/controller.js +7 -0
  115. data/generators/templates/source/controllers/ruby/controller.rb +8 -0
  116. data/generators/templates/source/controllers/ruby/controller_spec.rb +27 -0
  117. data/generators/templates/source/models/js/model.js +46 -0
  118. data/generators/templates/source/{source_adapter.rb → models/ruby/model.rb} +15 -10
  119. data/generators/templates/source/{source_spec.rb → models/ruby/model_spec.rb} +1 -1
  120. data/install.sh +5 -5
  121. data/installer/unix-like/create_texts.rb +2 -2
  122. data/installer/unix-like/rho_connect_install_constants.rb +2 -2
  123. data/installer/unix-like/rho_connect_install_utilities.rb +1 -1
  124. data/installer/utils/constants.rb +4 -4
  125. data/js-adapters/ballroom.js +216 -0
  126. data/js-adapters/node.rb +52 -0
  127. data/js-adapters/node_channel.rb +181 -0
  128. data/js-adapters/request.js +27 -0
  129. data/js-adapters/response.js +57 -0
  130. data/js-adapters/rhoconnect_helpers.js +60 -0
  131. data/js-adapters/router.js +60 -0
  132. data/js-adapters/server.js +5 -0
  133. data/lib/rhoconnect/api/app/ans_login.rb +3 -3
  134. data/lib/rhoconnect/api/app/bulk_data.rb +10 -10
  135. data/lib/rhoconnect/api/app/fast_delete.rb +11 -10
  136. data/lib/rhoconnect/api/app/fast_insert.rb +11 -10
  137. data/lib/rhoconnect/api/app/fast_update.rb +11 -10
  138. data/lib/rhoconnect/api/app/login.rb +5 -5
  139. data/lib/rhoconnect/api/app/push_deletes.rb +12 -11
  140. data/lib/rhoconnect/api/app/push_objects.rb +12 -11
  141. data/lib/rhoconnect/api/app/query.rb +8 -7
  142. data/lib/rhoconnect/api/app/queue_updates.rb +98 -94
  143. data/lib/rhoconnect/api/app/search.rb +8 -7
  144. data/lib/rhoconnect/api/client/client_get_db_doc.rb +5 -5
  145. data/lib/rhoconnect/api/client/client_set_db_doc.rb +8 -8
  146. data/lib/rhoconnect/api/client/create.rb +7 -7
  147. data/lib/rhoconnect/api/client/get_client_params.rb +4 -4
  148. data/lib/rhoconnect/api/client/list_client_docs.rb +17 -17
  149. data/lib/rhoconnect/api/client/register.rb +12 -12
  150. data/lib/rhoconnect/api/client/reset.rb +5 -5
  151. data/lib/rhoconnect/api/readstate/set_refresh_time.rb +9 -9
  152. data/lib/rhoconnect/api/source/get_source_params.rb +4 -4
  153. data/lib/rhoconnect/api/source/list_sources.rb +16 -16
  154. data/lib/rhoconnect/api/source/update_source_params.rb +6 -6
  155. data/lib/rhoconnect/api/store/get_db_doc.rb +4 -4
  156. data/lib/rhoconnect/api/store/set_db_doc.rb +7 -7
  157. data/lib/rhoconnect/api/system/get_adapter.rb +4 -4
  158. data/lib/rhoconnect/api/system/get_license_info.rb +8 -8
  159. data/lib/rhoconnect/api/system/login.rb +15 -15
  160. data/lib/rhoconnect/api/system/reset.rb +11 -11
  161. data/lib/rhoconnect/api/system/save_adapter.rb +4 -4
  162. data/lib/rhoconnect/api/system/stats.rb +22 -22
  163. data/lib/rhoconnect/api/user/create_user.rb +7 -7
  164. data/lib/rhoconnect/api/user/delete_client.rb +6 -6
  165. data/lib/rhoconnect/api/user/delete_user.rb +11 -10
  166. data/lib/rhoconnect/api/user/list_clients.rb +4 -4
  167. data/lib/rhoconnect/api/user/list_source_docs.rb +10 -10
  168. data/lib/rhoconnect/api/user/list_users.rb +3 -3
  169. data/lib/rhoconnect/api/user/ping.rb +3 -3
  170. data/lib/rhoconnect/api/user/show_user.rb +3 -3
  171. data/lib/rhoconnect/api/user/update_user.rb +5 -5
  172. data/lib/rhoconnect/api/user/user_get_db_doc.rb +5 -5
  173. data/lib/rhoconnect/api/user/user_set_db_doc.rb +10 -10
  174. data/lib/rhoconnect/api_token.rb +5 -6
  175. data/lib/rhoconnect/app.rb +6 -46
  176. data/lib/rhoconnect/application/init.rb +5 -2
  177. data/lib/rhoconnect/async.rb +76 -39
  178. data/lib/rhoconnect/bulk_data/bulk_data.rb +6 -4
  179. data/lib/rhoconnect/client.rb +59 -9
  180. data/lib/rhoconnect/condition/admin_required.rb +27 -0
  181. data/lib/rhoconnect/condition/client_required.rb +50 -0
  182. data/lib/rhoconnect/condition/login_required.rb +22 -0
  183. data/lib/rhoconnect/condition/source_required.rb +49 -0
  184. data/lib/rhoconnect/condition/verbs.rb +17 -0
  185. data/lib/rhoconnect/condition/verify_success.rb +19 -0
  186. data/lib/rhoconnect/controller/app_base.rb +74 -0
  187. data/lib/rhoconnect/controller/base.rb +68 -0
  188. data/lib/rhoconnect/controller/clients_controller.rb +79 -0
  189. data/lib/rhoconnect/controller/dynamic_adapter_controller.rb +93 -0
  190. data/lib/rhoconnect/controller/js_base.rb +124 -0
  191. data/lib/rhoconnect/controller/read_state_controller.rb +22 -0
  192. data/lib/rhoconnect/controller/source_adapter_base.rb +14 -0
  193. data/lib/rhoconnect/controller/sources_controller.rb +44 -0
  194. data/lib/rhoconnect/controller/store_controller.rb +25 -0
  195. data/lib/rhoconnect/controller/system_controller.rb +67 -0
  196. data/lib/rhoconnect/controller/users_controller.rb +99 -0
  197. data/lib/rhoconnect/db_adapter.rb +1 -3
  198. data/lib/rhoconnect/document.rb +159 -50
  199. data/lib/rhoconnect/handler/authenticate/execute_methods.rb +77 -0
  200. data/lib/rhoconnect/handler/authenticate/runner.rb +49 -0
  201. data/lib/rhoconnect/handler/authenticate.rb +3 -0
  202. data/lib/rhoconnect/handler/bulk_data.rb +28 -0
  203. data/lib/rhoconnect/handler/changes/engine.rb +271 -0
  204. data/lib/rhoconnect/handler/changes/execute_methods.rb +88 -0
  205. data/lib/rhoconnect/handler/changes/pass_through_runner.rb +11 -0
  206. data/lib/rhoconnect/handler/changes/runner.rb +53 -0
  207. data/lib/rhoconnect/handler/changes.rb +31 -0
  208. data/lib/rhoconnect/handler/helpers/auth_method.rb +29 -0
  209. data/lib/rhoconnect/handler/helpers/binding.rb +18 -0
  210. data/lib/rhoconnect/handler/helpers/bulk_data.rb +53 -0
  211. data/lib/rhoconnect/handler/helpers/source_job.rb +14 -0
  212. data/lib/rhoconnect/handler/helpers.rb +4 -0
  213. data/lib/rhoconnect/handler/plugin_callbacks/execute_methods.rb +99 -0
  214. data/lib/rhoconnect/handler/plugin_callbacks/runner.rb +28 -0
  215. data/lib/rhoconnect/handler/plugin_callbacks.rb +67 -0
  216. data/lib/rhoconnect/handler/query/engine.rb +93 -0
  217. data/lib/rhoconnect/handler/query/execute_methods.rb +21 -0
  218. data/lib/rhoconnect/handler/query/pass_through_runner.rb +35 -0
  219. data/lib/rhoconnect/handler/query/runner.rb +270 -0
  220. data/lib/rhoconnect/handler/query.rb +19 -0
  221. data/lib/rhoconnect/handler/search/engine.rb +60 -0
  222. data/lib/rhoconnect/handler/search/execute_methods.rb +32 -0
  223. data/lib/rhoconnect/handler/search/pass_through_runner.rb +18 -0
  224. data/lib/rhoconnect/handler/search/runner.rb +104 -0
  225. data/lib/rhoconnect/handler/search.rb +26 -0
  226. data/lib/rhoconnect/handler/sync.rb +29 -0
  227. data/lib/rhoconnect/jobs/source_job.rb +13 -4
  228. data/lib/rhoconnect/js_adapter.rb +79 -0
  229. data/lib/rhoconnect/license.rb +10 -2
  230. data/lib/rhoconnect/middleware/current_user.rb +14 -1
  231. data/lib/rhoconnect/middleware/helpers.rb +10 -93
  232. data/lib/rhoconnect/middleware/x_domain_session_wrapper.rb +1 -1
  233. data/lib/rhoconnect/model/base.rb +229 -0
  234. data/lib/rhoconnect/model/dynamic_adapter_model.rb +90 -0
  235. data/lib/rhoconnect/model/js_base.rb +121 -0
  236. data/lib/rhoconnect/ping/android.rb +1 -1
  237. data/lib/rhoconnect/predefined_adapters/bench_adapter.rb +7 -4
  238. data/lib/rhoconnect/read_state.rb +3 -3
  239. data/lib/rhoconnect/server.rb +159 -190
  240. data/lib/rhoconnect/source.rb +100 -11
  241. data/lib/rhoconnect/stats/record.rb +10 -10
  242. data/lib/rhoconnect/store.rb +905 -591
  243. data/lib/rhoconnect/{model.rb → store_orm.rb} +53 -115
  244. data/lib/rhoconnect/tasks.rb +18 -4
  245. data/lib/rhoconnect/test_methods.rb +30 -17
  246. data/lib/rhoconnect/user.rb +35 -17
  247. data/lib/rhoconnect/utilities.rb +1 -1
  248. data/lib/rhoconnect/version.rb +2 -2
  249. data/lib/rhoconnect/web-console/server.rb +29 -14
  250. data/lib/rhoconnect/web-console/views/home.js +10 -10
  251. data/lib/rhoconnect/web-console/views/new_ping.js +1 -1
  252. data/lib/rhoconnect.rb +120 -51
  253. data/rhoconnect.gemspec +4 -3
  254. data/spec/api/api_helper.rb +1 -6
  255. data/spec/api/app/fast_delete_spec.rb +4 -4
  256. data/spec/api/app/fast_insert_spec.rb +4 -4
  257. data/spec/api/app/fast_update_spec.rb +8 -8
  258. data/spec/api/app/push_deletes_spec.rb +2 -2
  259. data/spec/api/app/push_objects_spec.rb +5 -5
  260. data/spec/api/client/client_get_db_doc_spec.rb +6 -4
  261. data/spec/api/client/client_set_db_doc_spec.rb +3 -2
  262. data/spec/api/client/get_client_params_spec.rb +14 -0
  263. data/spec/api/client/list_client_docs_spec.rb +30 -20
  264. data/spec/api/client/reset_spec.rb +36 -0
  265. data/spec/api/source/get_source_params_spec.rb +23 -17
  266. data/spec/api/system/get_license_info_spec.rb +0 -20
  267. data/spec/api/system/login_spec.rb +8 -0
  268. data/spec/api/system/reset_spec.rb +0 -1
  269. data/spec/api/system/stats_spec.rb +5 -5
  270. data/spec/api/user/create_user_spec.rb +14 -6
  271. data/spec/api/user/delete_user_spec.rb +20 -18
  272. data/spec/api/user/list_users_spec.rb +5 -6
  273. data/spec/api/user/update_user_spec.rb +5 -4
  274. data/spec/apps/rhotestapp/config.ru +16 -1
  275. data/spec/apps/rhotestapp/controllers/js/js_sample_controller.js +23 -0
  276. data/spec/apps/rhotestapp/controllers/js/sample2_controller.js +32 -0
  277. data/spec/apps/rhotestapp/controllers/ruby/application_controller.rb +21 -0
  278. data/spec/apps/rhotestapp/controllers/ruby/sample_adapter_controller.rb +8 -0
  279. data/spec/apps/rhotestapp/models/js/js_sample.js +55 -0
  280. data/spec/apps/rhotestapp/models/js/sample2.js +25 -0
  281. data/spec/apps/rhotestapp/{sources → models/ruby}/base_adapter.rb +0 -0
  282. data/spec/apps/rhotestapp/{sources → models/ruby}/fixed_schema_adapter.rb +0 -0
  283. data/spec/apps/rhotestapp/{sources → models/ruby}/other_adapter.rb +0 -0
  284. data/spec/apps/rhotestapp/{sources → models/ruby}/sample_adapter.rb +0 -0
  285. data/spec/apps/rhotestapp/{sources → models/ruby}/simple_adapter.rb +2 -2
  286. data/spec/apps/rhotestapp/{sources → models/ruby}/sub_adapter.rb +0 -0
  287. data/spec/apps/rhotestapp/settings/settings.yml +0 -1
  288. data/spec/bulk_data/bulk_data_spec.rb +20 -5
  289. data/spec/cli/cli_spec.rb +83 -0
  290. data/spec/client_spec.rb +20 -17
  291. data/spec/client_sync_spec.rb +244 -406
  292. data/spec/controllers/js_base_spec.rb +89 -0
  293. data/spec/doc/doc_spec.rb +18 -18
  294. data/spec/document_spec.rb +29 -13
  295. data/spec/dynamic_adapter_spec.rb +6 -6
  296. data/spec/generator/generator_spec.rb +7 -4
  297. data/spec/jobs/bulk_data_job_spec.rb +14 -10
  298. data/spec/jobs/source_job_spec.rb +8 -8
  299. data/spec/license_spec.rb +5 -2
  300. data/spec/models/js_model_spec.rb +39 -0
  301. data/spec/node_spec.rb +42 -0
  302. data/spec/perf/store_perf_spec.rb +67 -12
  303. data/spec/ping/android_spec.rb +1 -1
  304. data/spec/read_state_spec.rb +1 -1
  305. data/spec/rhoconnect_spec.rb +1 -1
  306. data/spec/server/cors_spec.rb +14 -18
  307. data/spec/server/server_spec.rb +265 -88
  308. data/spec/server/stats_spec.rb +1 -1
  309. data/spec/source_adapter_spec.rb +54 -27
  310. data/spec/source_spec.rb +8 -3
  311. data/spec/source_sync_spec.rb +538 -468
  312. data/spec/spec_helper.rb +35 -4
  313. data/spec/stats/record_spec.rb +10 -10
  314. data/spec/{model_spec.rb → store_orm_spec.rb} +56 -54
  315. data/spec/store_spec.rb +159 -179
  316. data/spec/support/shared_examples.rb +36 -27
  317. data/spec/sync_states_spec.rb +40 -33
  318. data/spec/test_methods_spec.rb +18 -14
  319. data/spec/user_spec.rb +17 -30
  320. metadata +156 -52
  321. data/bench/benchapp/application.rb +0 -39
  322. data/bench/blobapp/application.rb +0 -44
  323. data/commands/rhoconnect/clean_start.rb +0 -9
  324. data/commands/rhoconnect/create_user.rb +0 -18
  325. data/commands/rhoconnect/delete_device.rb +0 -9
  326. data/commands/rhoconnect/delete_user.rb +0 -8
  327. data/commands/rhoconnect/reset.rb +0 -16
  328. data/commands/rhoconnect/reset_refresh.rb +0 -11
  329. data/generators/templates/application/application.rb +0 -43
  330. data/lib/rhoconnect/client_sync.rb +0 -434
  331. data/lib/rhoconnect/dynamic_adapter.rb +0 -91
  332. data/lib/rhoconnect/middleware/admin_user.rb +0 -23
  333. data/lib/rhoconnect/middleware/current_request.rb +0 -16
  334. data/lib/rhoconnect/middleware/login_required.rb +0 -22
  335. data/lib/rhoconnect/source_adapter.rb +0 -132
  336. data/lib/rhoconnect/source_sync.rb +0 -464
  337. data/spec/apps/rhotestapp/application.rb +0 -23
@@ -0,0 +1,270 @@
1
+ module Rhoconnect
2
+ # implementation classes
3
+ module Handler
4
+ module Query
5
+ class Runner
6
+ attr_accessor :source,:client,:p_size,:engine,:params
7
+
8
+ def initialize(model,client,route_handler, params = {})
9
+ raise ArgumentError.new(UNKNOWN_CLIENT) unless client
10
+ raise ArgumentError.new(UNKNOWN_SOURCE) unless (model and model.source)
11
+ raise ArgumentError.new('Invalid app for source') unless model.source.app
12
+
13
+ @source,@client,@p_size = model.source,client,params[:p_size] ? params[:p_size].to_i : 500
14
+ @client.last_sync = Time.now if @client
15
+ @params = params
16
+ @engine = Rhoconnect::Handler::Query::Engine.new(model, route_handler, @params)
17
+ end
18
+
19
+ def run
20
+ res = []
21
+ token = params[:token]
22
+ if not ack_token(token)
23
+ res = resend_page(token)
24
+ else
25
+ query_result = @engine.do_sync
26
+ res = send_new_page
27
+ end
28
+ format_result(res[0],res[1],res[2],res[3])
29
+ end
30
+
31
+ # Resend token for a client, also sends exceptions
32
+ def resend_page(token=nil)
33
+ token,progress_count,total_count,res = '',0,0,{}
34
+ schema_page = @client.get_value(:schema_page)
35
+ if schema_page
36
+ res = {'schema-changed' => 'true'}
37
+ else
38
+ res = build_page do |r|
39
+ r['insert'] = @client.get_data(:page)
40
+ r['delete'] = @client.get_data(:delete_page)
41
+ r['links'] = @client.get_data(:create_links_page)
42
+ r['metadata'] = @client.get_value(:metadata_page)
43
+ progress_count = 0
44
+ total_count = @client.get_value(:total_count_page).to_i
45
+ end
46
+ end
47
+ token = @client.get_value(:page_token)
48
+ [token,progress_count,total_count,res]
49
+ end
50
+
51
+ def ack_token(token)
52
+ stored_token = @client.get_value(:page_token)
53
+ if stored_token
54
+ if token and stored_token == token
55
+ @client.put_value(:page_token,nil)
56
+ @client.flush_data(:schema_page)
57
+ @client.flush_data(:metadata_page)
58
+ @client.flush_data(:create_links_page)
59
+ @client.flush_data(:page)
60
+ @client.flush_data(:delete_page)
61
+ _delete_errors_page
62
+ return true
63
+ end
64
+ else
65
+ return true
66
+ end
67
+ false
68
+ end
69
+
70
+ def format_result(token,progress_count,total_count,res)
71
+ count = 0
72
+ count += res['insert'].length if res['insert']
73
+ count += res['delete'].length if res['delete']
74
+ [ {'version'=>Rhoconnect::SYNC_VERSION},
75
+ {'token'=>(token ? token : '')},
76
+ {'count'=>count},
77
+ {'progress_count'=>progress_count},
78
+ {'total_count'=>total_count},
79
+ res ]
80
+ end
81
+
82
+ def build_page
83
+ res = {}
84
+ yield res
85
+ res.reject! {|key,value| value.nil? or value.empty?}
86
+ res.merge!(_send_errors)
87
+ res
88
+ end
89
+
90
+ def send_new_page
91
+ token,progress_count,total_count,res = '',0,0,{}
92
+ if schema_changed?
93
+ _expire_bulk_data
94
+ token = @client.compute_token(:page_token)
95
+ res = {'schema-changed' => 'true'}
96
+ else
97
+ compute_errors_page
98
+ res = build_page do |r|
99
+ total_count,r['insert'],r['delete'] = compute_page
100
+ r['links'] = compute_links_page
101
+ r['metadata'] = compute_metadata
102
+ end
103
+ if res['insert'] or res['delete'] or res['links']
104
+ token = @client.compute_token(:page_token)
105
+ else
106
+ _delete_errors_page
107
+ end
108
+ end
109
+ # TODO: progress count can not be computed properly
110
+ # without comparing what has actually changes
111
+ # so we need to obsolete it in the future versions
112
+ progress_count = 0
113
+ [token,progress_count,total_count,res]
114
+ end
115
+
116
+ def send_new_page_bruteforce
117
+ token,progress_count,total_count,res = '',0,0,{}
118
+ if schema_changed?
119
+ _expire_bulk_data
120
+ token = @client.compute_token(:page_token)
121
+ res = {'schema-changed' => 'true'}
122
+ else
123
+ compute_errors_page
124
+ res = build_page do |r|
125
+ total_count,r['insert'],r['delete'] = compute_page_bruteforce
126
+ r['links'] = compute_links_page
127
+ r['metadata'] = compute_metadata
128
+ end
129
+ if res['insert'] or res['delete'] or res['links']
130
+ token = @client.compute_token(:page_token)
131
+ else
132
+ _delete_errors_page
133
+ end
134
+ end
135
+ # TODO: progress count can not be computed properly
136
+ # without comparing what has actually changes
137
+ # so we need to obsolete it in the future versions
138
+ progress_count = 0
139
+ [token,progress_count,total_count,res]
140
+ end
141
+
142
+ # Checks if schema changed
143
+ def schema_changed?
144
+ if engine.model.respond_to?(:schema)
145
+ schema_sha1 = @source.get_value(:schema_sha1)
146
+ if @client.get_value(:schema_sha1).nil?
147
+ @client.put_value(:schema_sha1,schema_sha1)
148
+ return false
149
+ elsif @client.get_value(:schema_sha1) == schema_sha1
150
+ return false
151
+ end
152
+ @client.put_value(:schema_sha1,schema_sha1)
153
+ @client.put_value(:schema_page,schema_sha1)
154
+ return true
155
+ else
156
+ return false
157
+ end
158
+ end
159
+
160
+ # Computes the metadata sha1 and returns metadata if client's sha1 doesn't
161
+ # match source's sha1
162
+ def compute_metadata
163
+ metadata_sha1,metadata = @source.lock(:metadata) do |s|
164
+ [s.get_value(:metadata_sha1),s.get_value(:metadata)]
165
+ end
166
+ return if @client.get_value(:metadata_sha1) == metadata_sha1
167
+ @client.put_value(:metadata_sha1,metadata_sha1)
168
+ @client.put_value(:metadata_page,metadata)
169
+ metadata
170
+ end
171
+
172
+
173
+ # Computes diffs between master doc and client doc, trims it to page size,
174
+ # stores page, and returns page as hash
175
+ def compute_page
176
+ inserts_elements_map,deletes_elements_map,total_count = @source.lock(:md) do |s|
177
+ inserts_elements_map = @client.get_diff_data(:cd,s.docname(:md),@p_size)
178
+ total_count = s.get_value(:md_size).to_i
179
+ deletes_elements_map = s.get_diff_data(:md,@client.docname(:cd),@p_size)
180
+ [inserts_elements_map,deletes_elements_map,total_count]
181
+ end
182
+ # until sync is not done - set cd_size to 0
183
+ # once there are no changes, then, set cd_size to md_size
184
+ cd_size = inserts_elements_map.size > 0 ? 0 : total_count
185
+ @client.put_value(:cd_size, cd_size)
186
+
187
+ # now, find the exact changes
188
+ inserts,deletes = Store.get_inserts_deletes(inserts_elements_map,deletes_elements_map)
189
+
190
+ @client.put_data(:page,inserts)
191
+ @client.put_data(:delete_page,deletes,true)
192
+ @client.put_value(:total_count_page,total_count)
193
+ @client.update_elements(:cd,inserts_elements_map,deletes_elements_map)
194
+
195
+ [total_count,inserts,deletes]
196
+ end
197
+
198
+ # Computes diffs between master doc and client doc, trims it to page size,
199
+ # stores page, and returns page as hash
200
+ def compute_page_bruteforce
201
+ inserts_elements_map,deletes_elements_map,total_count = @source.lock(:md) do |s|
202
+ inserts_elements_map,deletes_elements_map = @client.get_diff_data_bruteforce(:cd,s.docname(:md),@p_size)
203
+ total_count = s.get_value(:md_size).to_i
204
+ [inserts_elements_map,deletes_elements_map,total_count]
205
+ end
206
+ # until sync is not done - set cd_size to 0
207
+ # once there are no changes, then, set cd_size to md_size
208
+ cd_size = inserts_elements_map.size > 0 ? 0 : total_count
209
+ @client.put_value(:cd_size, cd_size)
210
+
211
+ # now, find the exact changes
212
+ inserts,deletes = Store.get_inserts_deletes(inserts_elements_map,deletes_elements_map)
213
+
214
+ @client.put_data(:page,inserts)
215
+ @client.put_data(:delete_page,deletes,true)
216
+ @client.put_value(:total_count_page,total_count)
217
+ @client.update_elements(:cd,inserts_elements_map,deletes_elements_map)
218
+
219
+ [total_count,inserts,deletes]
220
+ end
221
+
222
+ # Computes errors for client and stores a copy as errors page
223
+ def compute_errors_page
224
+ ['create','update','delete'].each do |operation|
225
+ @client.lock("#{operation}_errors") do |c|
226
+ c.rename("#{operation}_errors","#{operation}_errors_page")
227
+ end
228
+ end
229
+ @client.lock("update_rollback") do |c|
230
+ c.rename("update_rollback","update_rollback_page")
231
+ end
232
+ end
233
+
234
+ # Computes create links for a client and stores a copy as links page
235
+ def compute_links_page
236
+ @client.lock(:create_links) do |c|
237
+ c.rename(:create_links,:create_links_page)
238
+ c.get_data(:create_links_page)
239
+ end
240
+ end
241
+
242
+ private
243
+ def _delete_errors_page
244
+ ['create','update','delete'].each do |operation|
245
+ @client.flush_data("#{operation}_errors_page")
246
+ end
247
+ @client.flush_data("update_rollback_page")
248
+ end
249
+
250
+ def _send_errors
251
+ res = {}
252
+ ['create','update','delete'].each do |operation|
253
+ res["#{operation}-error"] = @client.get_data("#{operation}_errors_page")
254
+ end
255
+ res["source-error"] = @source.lock(:errors) { |s| s.get_data(:errors) }
256
+ res["update-rollback"] = @client.get_data(:update_rollback_page)
257
+ res.reject! {|key,value| value.nil? or value.empty?}
258
+ res
259
+ end
260
+
261
+ # expires the bulk data for the client
262
+ def _expire_bulk_data
263
+ [:user,:app].each do |partition|
264
+ Rhoconnect.expire_bulk_data(@client.user_id,partition)
265
+ end
266
+ end
267
+ end
268
+ end
269
+ end
270
+ end
@@ -0,0 +1,19 @@
1
+ require 'rhoconnect/handler/helpers.rb'
2
+ require 'rhoconnect/handler/query/execute_methods.rb'
3
+ require 'rhoconnect/handler/query/runner.rb'
4
+ require 'rhoconnect/handler/query/pass_through_runner.rb'
5
+ require 'rhoconnect/handler/query/engine.rb'
6
+
7
+ module Rhoconnect
8
+ module Handler
9
+ module Query
10
+ def self.registered(app)
11
+ app.get "/", :rc_handler => :query, :login_required => true, :admin_required => false,
12
+ :source_required => true, :client_required => true,
13
+ :deprecated_route => {:verb => :get, :url => ['/api/application', '/application', '/api/application/query']} do
14
+ @model.query(params[:query])
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,60 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Search
4
+ class Engine
5
+ attr_accessor :source, :client, :model, :route_handler, :params
6
+
7
+ include Rhoconnect::Handler::Helpers::AuthMethod
8
+ include Rhoconnect::Handler::Helpers::Binding
9
+
10
+ def initialize(model, client, route_handler, params = {})
11
+ raise ArgumentError.new(UNKNOWN_CLIENT) unless client
12
+ raise ArgumentError.new(UNKNOWN_SOURCE) unless (model and model.source)
13
+ raise ArgumentError.new('Invalid app for source') unless model.source.app
14
+ raise ArgumentError.new('Invalid sync handler') unless route_handler
15
+
16
+ @client = client
17
+ @source = model.source
18
+ @model = model
19
+ # if handler is not bound - bind it to self
20
+ # normally it should be bound to a Controller's instance
21
+ @route_handler = bind_handler(:search_handler_method, route_handler)
22
+ @params = params
23
+ end
24
+
25
+ def do_search
26
+ return if auth_method('login',client.id) == false
27
+ res = run_search
28
+ auth_method('logoff',client.id)
29
+ res
30
+ end
31
+
32
+ def run_search
33
+ errordoc = nil
34
+ docobj = nil
35
+ result = nil
36
+ begin
37
+ errordoc = :search_errors
38
+ docobj = client
39
+ client.compute_token(:search_token)
40
+ result = @route_handler.call
41
+ client.put_data(:search,result) unless @source.is_pass_through?
42
+ # operation,sync succeeded, remove errors
43
+ docobj.lock(errordoc) do
44
+ docobj.flush_data(errordoc)
45
+ end
46
+ rescue Exception => e
47
+ # store sync,operation exceptions to be sent to all clients for this source/user
48
+ log "Model raised search exception: #{e}"
49
+ log e.backtrace.join("\n")
50
+ docobj.lock(errordoc) do
51
+ docobj.put_data(errordoc,{"search-error"=>{'message'=>e.message}},true)
52
+ end
53
+ end
54
+ # pass through expects result hash
55
+ @source.is_pass_through? ? result : true
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,32 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Search
4
+ module ExecuteMethods
5
+ def execute_search_handler(route_handler)
6
+ content_type :json
7
+ return [].to_json unless params[:sources]
8
+ res = []
9
+ params[:sources].each do |source_params|
10
+ s = Source.load(source_params['name'],{:app_id => current_client.app_id,
11
+ :user_id => current_client.user_id})
12
+ current_client.source_name = source_params['name']
13
+ @model = Rhoconnect::Model::Base.create(s)
14
+
15
+ params[:token] = source_params['token'] if source_params['token']
16
+ if not s.is_pass_through?
17
+ @handler = Rhoconnect::Handler::Search::Runner.new(@model, current_client, route_handler, params)
18
+ else
19
+ @handler = Rhoconnect::Handler::Search::PassThroughRunner.new(@model, current_client, route_handler, params)
20
+ end
21
+ @model = @handler.engine.model
22
+ search_res = @handler.run
23
+ res << search_res if search_res
24
+ end
25
+ response.headers[Rhoconnect::PAGE_TOKEN_HEADER] = res[0][1]['token'] if res[0][1] and res[0][1]['token']
26
+ response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER] = res[0][3]['count'].to_s if res[0][3] and res[0][3]['count']
27
+ res.to_json
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,18 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Search
4
+ # this class just overrides one method
5
+ class PassThroughRunner < Rhoconnect::Handler::Search::Runner
6
+ private
7
+ def _do_search
8
+ # call model search unless client is sending token for ack
9
+ res = @engine.do_search if params.nil? or !params[:token]
10
+ res,diffsize = [res,res.size]
11
+ formatted_res = _format_search_result(res,diffsize)
12
+ _delete_search if diffsize == 0
13
+ formatted_res
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,104 @@
1
+ module Rhoconnect
2
+ # implementation classes
3
+ module Handler
4
+ module Search
5
+ class Runner
6
+ attr_accessor :source,:client,:p_size,:model,:engine,:params
7
+
8
+ def initialize(model,client,route_handler, params = {})
9
+ raise ArgumentError.new(UNKNOWN_CLIENT) unless client
10
+ raise ArgumentError.new(UNKNOWN_SOURCE) unless (model and model.source)
11
+ raise ArgumentError.new('Invalid app for source') unless model.source.app
12
+
13
+ @source,@client,@p_size = model.source,client,params[:p_size] ? params[:p_size].to_i : 500
14
+ @model = model
15
+ @client.last_sync = Time.now if @client
16
+ @params = params
17
+ @engine = Rhoconnect::Handler::Search::Engine.new(@model, @client, route_handler, @params)
18
+ end
19
+
20
+ def run
21
+ if params
22
+ return _resend_search_result if params[:token] and params[:resend]
23
+ if params[:token] and !_ack_search(params[:token])
24
+ formatted_result = _format_search_result
25
+ _delete_search
26
+ return formatted_result
27
+ end
28
+ end
29
+ _do_search
30
+ end
31
+
32
+ private
33
+ def _do_search
34
+ # call model search unless client is sending token for ack
35
+ res = @engine.do_search if params.nil? or !params[:token]
36
+ res,diffsize = _compute_search
37
+ formatted_res = _format_search_result(res,diffsize)
38
+ _delete_search if diffsize == 0
39
+ formatted_res
40
+ end
41
+
42
+ # Computes search result, updates md for source and cd for client with the result
43
+ def _compute_search
44
+ cd_inserts_elements_map = @client.get_diff_data(:cd,@client.docname(:search),@p_size)
45
+
46
+ @client.update_elements(:cd, cd_inserts_elements_map, {})
47
+ @client.update_count(:cd_size,cd_inserts_elements_map.size)
48
+ # remove previous search page and build new one
49
+ @client.flush_data(:search_page)
50
+ @client.update_elements(:search_page,cd_inserts_elements_map,{})
51
+ client_res = @client.get_data(:search_page)
52
+
53
+ @source.lock(:md) do |s|
54
+ md_inserts_elements_map = s.get_diff_data(:md,@client.docname(:cd))
55
+ s.update_elements(:md, md_inserts_elements_map, {})
56
+ s.update_count(:md_size,md_inserts_elements_map.size)
57
+ end
58
+
59
+ [client_res,client_res.size]
60
+ end
61
+
62
+ def _resend_search_result
63
+ res = @client.get_data(:search_page)
64
+ _format_search_result(res,res.size)
65
+ end
66
+
67
+ def _ack_search(search_token)
68
+ if @client.get_value(:search_token) != search_token
69
+ _delete_search
70
+ @client.put_data(:search_errors,
71
+ {'search-error'=>{'message'=>'Search error - invalid token'}}
72
+ )
73
+ return false
74
+ end
75
+ true
76
+ end
77
+
78
+ def _delete_search
79
+ [:search, :search_page, :search_token, :search_errors].each do |search_doc|
80
+ @client.flush_data(search_doc)
81
+ end
82
+ end
83
+
84
+ def _format_search_result(res={},diffsize=nil)
85
+ error = @client.get_data(:search_errors)
86
+ if not error.empty?
87
+ [ {'version'=>Rhoconnect::SYNC_VERSION},
88
+ {'source'=>@source.name},
89
+ {'search-error'=>error} ]
90
+ else
91
+ search_token = @client.get_value(:search_token)
92
+ search_token ||= ''
93
+ return [] if res.empty?
94
+ [ {'version'=>Rhoconnect::SYNC_VERSION},
95
+ {'token' => search_token},
96
+ {'source'=>@source.name},
97
+ {'count'=>res.size},
98
+ {'insert'=>res} ]
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
104
+ end
@@ -0,0 +1,26 @@
1
+ require 'rhoconnect/handler/helpers'
2
+ require 'rhoconnect/handler/search/execute_methods'
3
+ require 'rhoconnect/handler/search/runner'
4
+ require 'rhoconnect/handler/search/pass_through_runner'
5
+ require 'rhoconnect/handler/search/engine'
6
+
7
+ module Rhoconnect
8
+ module Handler
9
+ module Search
10
+ def self.registered(app)
11
+ # search request
12
+ app.post "/search", \
13
+ { :login_required => true,
14
+ :client_required => true,
15
+ :source_required => false,
16
+ :admin_required => false,
17
+ :rc_handler => :search,
18
+ :deprecated_route => {:verb => :get, :url => ['/application/search', '/api/application/search']}
19
+ } do
20
+ search_params = params[:search]
21
+ @model.search(search_params)
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ require 'rhoconnect/handler/query'
2
+ require 'rhoconnect/handler/changes'
3
+ require 'rhoconnect/handler/plugin_callbacks'
4
+
5
+ module Rhoconnect
6
+ module Handler
7
+ module Sync
8
+ def self.registered(app)
9
+ app.set_default :admin_required, false
10
+ app.set_default :login_required, true
11
+ app.set_default :source_required, true
12
+ app.set_default :client_required, true
13
+
14
+ app.register Rhoconnect::Handler::Query
15
+ app.register Rhoconnect::Handler::Changes
16
+ app.register Rhoconnect::Handler::PluginCallbacks
17
+
18
+ # source name is available inherently from controller
19
+ app.before do
20
+ params[:source_name] = app._rest_name
21
+ params[:source_id] = app._rest_name
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+
29
+
@@ -3,13 +3,22 @@ module Rhoconnect
3
3
  class << self
4
4
  attr_accessor :queue
5
5
  end
6
-
6
+
7
7
  def self.perform(job_type,source_id,app_id,user_id,params)
8
8
  source = Source.load(source_id,{:app_id => app_id,:user_id => user_id})
9
- source_sync = SourceSync.new(source)
9
+ params ||= {}
10
+
10
11
  case job_type.to_sym
11
- when :query then source_sync.do_query(params)
12
- when :cud then source_sync.do_cud
12
+ when :query
13
+ handler_sync = lambda { @model.query(params[:query])}
14
+ @model = Rhoconnect::Model::Base.create(source)
15
+ source_sync = Rhoconnect::Handler::Query::Engine.new(@model, handler_sync, params)
16
+ source_sync.do_sync
17
+ when :cud
18
+ handler_cud = lambda { @model.send params[:operation].to_sym, params["#{params[:operation]}_object".to_sym] }
19
+ @model = Rhoconnect::Model::Base.create(source)
20
+ source_cud = Rhoconnect::Handler::Changes::Engine.new(['create', 'update', 'delete'], @model, handler_cud, params)
21
+ source_cud.do_cud
13
22
  end
14
23
  end
15
24
  end
@@ -0,0 +1,79 @@
1
+ # module Rhoconnect
2
+ # class JsAdapter < SourceAdapter
3
+ # attr_accessor :name
4
+ #
5
+ # def initialize(source)
6
+ # @source = source
7
+ # @name = source.name
8
+ # end
9
+ #
10
+ # def self.method_missing method_name, *args
11
+ # #grab function and args and publish to channel
12
+ # begin
13
+ # json = create_json_hash(method_name,args)
14
+ # NodeChannel.publish_channel_and_wait(json)
15
+ # rescue Exception => e
16
+ # puts "#{method_name error} - #{e.message}"
17
+ # end
18
+ # end
19
+ #
20
+ # def login(params=nil)
21
+ # begin
22
+ # json = create_json_hash('get',params)
23
+ # NodeChannel.publish_channel_and_wait(json)
24
+ # rescue Exception=>e
25
+ # puts "error login #{e.message}\n #{e.backtrace}"
26
+ # end
27
+ # end
28
+ #
29
+ # def query(params=nil)
30
+ # begin
31
+ # json = create_json_hash('get',params)
32
+ # @result = NodeChannel.publish_channel_and_wait(json)
33
+ # puts "res is ******* #{@result}"
34
+ # @result
35
+ # rescue Exception=>e
36
+ # puts "error query #{e.message}\n#{e.backtrace}"
37
+ # end
38
+ # end
39
+ #
40
+ # # def search(params=nil)
41
+ # # json = create_json_hash('search',params)
42
+ # # NodeChannel.publish_channel_and_wait(json)
43
+ # # end
44
+ #
45
+ # # def sync
46
+ # # @result
47
+ # # super
48
+ # # end
49
+ #
50
+ # def create(create_hash)
51
+ # json = create_json_hash('post',create_hash)
52
+ # NodeChannel.publish_channel_and_wait(json)
53
+ # end
54
+ #
55
+ # def update(update_hash)
56
+ # puts "update hash is #{update_hash}"
57
+ # json = create_json_hash('put',update_hash)
58
+ # NodeChannel.publish_channel_and_wait(json)
59
+ # end
60
+ #
61
+ # def delete(delete_hash)
62
+ # puts "create hash is #{delete_hash}"
63
+ # json = create_json_hash('delete',delete_hash)
64
+ # NodeChannel.publish_channel_and_wait(json)
65
+ # end
66
+ #
67
+ #
68
+ # private
69
+ #
70
+ # def create_json_hash(operation,params)
71
+ # json = {
72
+ # :url => "#{operation}-/#{@name}",
73
+ # :args => params,
74
+ # :route => 'request'
75
+ # }
76
+ # end
77
+ # end
78
+ #
79
+ # end