rhoconnect 3.4.5 → 4.0.0.beta.10

Sign up to get free protection for your applications and to get access to all the features.
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