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,88 @@
1
+ # this is the actual pseudo-middleware handler for Create/Update/Delete
2
+ module Rhoconnect
3
+ module Handler
4
+ module Changes
5
+ module ExecuteMethods
6
+ # combined CUD filter (aka 'queue_updates')
7
+ def execute_cud_handler(route_handler)
8
+ _extract_cud_params
9
+ _run_cud_handler(route_handler)
10
+ end
11
+
12
+ # individual filters
13
+ def execute_create_handler(route_handler)
14
+ _extract_cud_params
15
+ _run_cud_handler(route_handler, 'create')
16
+ end
17
+
18
+ def execute_update_handler(route_handler)
19
+ _extract_cud_params
20
+ # merge specific 'update' params
21
+ begin
22
+ if params["update"]
23
+ cud = params["update"]
24
+ params.delete("update")
25
+ params.merge!("update" => {params[:id] => cud})
26
+ end
27
+ rescue JSON::ParserError => jpe
28
+ log jpe.message + jpe.backtrace.join("\n")
29
+ throw :halt, [500, "Server error while processing client data"]
30
+ rescue Exception => e
31
+ log e.message + e.backtrace.join("\n")
32
+ throw :halt, [500, "Internal server error"]
33
+ end
34
+
35
+ _run_cud_handler(route_handler, 'update')
36
+ end
37
+
38
+ def execute_delete_handler(route_handler)
39
+ begin
40
+ obj = current_client.get_object(:cd, params[:id])
41
+ params.merge!("delete" => { params[:id] => obj } )
42
+ rescue JSON::ParserError => jpe
43
+ log jpe.message + jpe.backtrace.join("\n")
44
+ throw :halt, [500, "Server error while processing client data"]
45
+ rescue Exception => e
46
+ log e.message + e.backtrace.join("\n")
47
+ throw :halt, [500, "Internal server error"]
48
+ end
49
+
50
+ _run_cud_handler(route_handler, 'delete')
51
+ end
52
+
53
+ # encapsulate common code
54
+ def _run_cud_handler(route_handler, operations = ['create', 'update', 'delete'])
55
+ @handler = nil
56
+ if operations.is_a?String
57
+ operations = [operations]
58
+ end
59
+ if not current_source.is_pass_through?
60
+ @handler = Rhoconnect::Handler::Changes::Runner.new(operations, @model, current_client, route_handler, params)
61
+ else
62
+ @handler = Rhoconnect::Handler::Changes::PassThroughRunner.new(operations, @model, current_client, route_handler, params)
63
+ end
64
+ catch_all do
65
+ @handler.run
66
+ end
67
+ status 200
68
+ end
69
+
70
+ def _extract_cud_params
71
+ begin
72
+ if params["cud"]
73
+ cud = JSON.parse(params["cud"])
74
+ params.delete("cud")
75
+ params.merge!(cud)
76
+ end
77
+ rescue JSON::ParserError => jpe
78
+ log jpe.message + jpe.backtrace.join("\n")
79
+ throw :halt, [500, "Server error while processing client data"]
80
+ rescue Exception => e
81
+ log e.message + e.backtrace.join("\n")
82
+ throw :halt, [500, "Internal server error"]
83
+ end
84
+ end
85
+ end
86
+ end
87
+ end
88
+ end
@@ -0,0 +1,11 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Changes
4
+ class PassThroughRunner < Rhoconnect::Handler::Changes::Runner
5
+ def run
6
+ @engine.do_pass_through_cud
7
+ end
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Changes
4
+ class Runner
5
+ attr_accessor :source,:client,:engine,:model,:params,:operations
6
+
7
+ def initialize(operations,model,client,route_handler, params = {})
8
+ raise ArgumentError.new(UNKNOWN_CLIENT) unless client
9
+ raise ArgumentError.new(UNKNOWN_SOURCE) unless (model and model.source)
10
+ raise ArgumentError.new('Invalid app for source') unless model.source.app
11
+
12
+ @source,@client = model.source,client
13
+ @model = model
14
+ @client.last_sync = Time.now if @client
15
+ @params = params
16
+ @operations = operations
17
+ @engine = Rhoconnect::Handler::Changes::Engine.new(@operations, @model, route_handler, @params)
18
+ end
19
+
20
+ def run
21
+ _process_blobs(params)
22
+ processed = 0
23
+ operations.each do |op|
24
+ key,value = op,params[op]
25
+ processed += _receive_cud(key,value) if value
26
+ end
27
+ @engine.do_cud
28
+ end
29
+
30
+ private
31
+ def _receive_cud(operation,params)
32
+ return 0 if not operations.include?(operation)
33
+ @source.push_queue(operation,@client.id,params,true)
34
+ return 1
35
+ end
36
+
37
+ def _process_blobs(params)
38
+ unless params[:blob_fields].nil?
39
+ [:create,:update].each do |utype|
40
+ objects = params[utype] || {}
41
+ objects.each do |id,obj|
42
+ params[:blob_fields].each do |field|
43
+ blob = params["#{field}-#{id}"]
44
+ obj[field] = @model.store_blob(obj,field,blob)
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,31 @@
1
+ require 'rhoconnect/handler/helpers.rb'
2
+ require 'rhoconnect/handler/changes/execute_methods.rb'
3
+ require 'rhoconnect/handler/changes/runner.rb'
4
+ require 'rhoconnect/handler/changes/pass_through_runner.rb'
5
+ require 'rhoconnect/handler/changes/engine.rb'
6
+
7
+ module Rhoconnect
8
+ module Handler
9
+ module Changes
10
+ def self.registered(app)
11
+ # CUD
12
+ app.post "/", :rc_handler => :cud, :login_required => true, :admin_required => false,
13
+ :source_required => true, :client_required => true,
14
+ :deprecated_route => {:verb => :post, :url => ['/api/application', '/application', '/api/application/queue_updates']} do
15
+ operation = params[:operation]
16
+ @model.send operation.to_sym, params["#{operation}_object".to_sym]
17
+ end
18
+
19
+ app.put "/:id", :rc_handler => :update, :login_required => true, :admin_required => false,
20
+ :source_required => true, :client_required => true do
21
+ @model.update(params[:update_object])
22
+ end
23
+
24
+ app.delete "/:id", :rc_handler => :delete, :login_required => true, :admin_required => false,
25
+ :source_required => true, :client_required => true do
26
+ @model.delete(params[:delete_object])
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,29 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Helpers
4
+ module AuthMethod
5
+ def auth_method(operation,client_id=-1)
6
+ edockey = nil
7
+ docobj = nil
8
+ if client_id == -1
9
+ edockey = :errors
10
+ docobj = @source
11
+ else
12
+ edockey = :search_errors
13
+ docobj = Client.load(client_id,{:source_name => @source.name})
14
+ end
15
+ begin
16
+ docobj.flush_data(edockey) if operation == 'login'
17
+ @model.send operation
18
+ rescue Exception => e
19
+ log "Model raised #{operation} exception: #{e}"
20
+ log e.backtrace.join("\n")
21
+ docobj.put_data(edockey,{"#{operation}-error"=>{'message'=>e.message}},true)
22
+ return false
23
+ end
24
+ true
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,18 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Helpers
4
+ module Binding
5
+ def bind_handler(method_name, method_proc)
6
+ # do nothing if already bound
7
+ return method_proc if method_proc.is_a?Method
8
+
9
+ self.class.send :define_method, method_name, method_proc
10
+ method = self.class.instance_method(method_name)
11
+ self.class.send :remove_method, method_name
12
+ # bind it to self
13
+ method.bind(self)
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,53 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Helpers
4
+ module BulkData
5
+ def do_bulk_data(partition, client, sources = nil)
6
+ raise ArgumentError.new(UNKNOWN_CLIENT) unless client
7
+ name = Rhoconnect::BulkData.get_name(partition,client.user_id)
8
+ data = Rhoconnect::BulkData.load(name)
9
+
10
+ partition_sources = client.app.partition_sources(partition,client.user_id)
11
+ sources ||= partition_sources
12
+ return {:result => :nop} if sources.length <= 0
13
+
14
+ do_bd_sync = data.nil?
15
+ do_bd_sync = (data.completed? and
16
+ (data.refresh_time <= Time.now.to_i or !data.dbfiles_exist?)) unless do_bd_sync
17
+
18
+ if do_bd_sync
19
+ data.delete if data
20
+ data = Rhoconnect::BulkData.create(:name => name,
21
+ :app_id => client.app_id,
22
+ :user_id => client.user_id,
23
+ :partition_sources => partition_sources,
24
+ :sources => sources,
25
+ :refresh_time => Time.now.to_i + Rhoconnect.bulk_sync_poll_interval)
26
+ Rhoconnect::BulkData.enqueue("data_name" => name)
27
+ end
28
+
29
+ if data and data.completed? and data.dbfiles_exist?
30
+ client.update_clientdoc(sources)
31
+ sources.each do |src|
32
+ s = Source.load(src, {:user_id => client.user_id, :app_id => client.app_id})
33
+ errors = {}
34
+ s.lock(:errors) do
35
+ errors = s.get_data(:errors)
36
+ end
37
+ unless errors.empty?
38
+ # FIXME: :result => :bulk_sync_error, :errors => "#{errors}"
39
+ log "Bulk sync errors are found in #{src}: #{errors}"
40
+ # Delete all related bulk files
41
+ data.delete_files
42
+ return {:result => :url, :url => ''}
43
+ end
44
+ end
45
+ {:result => :url, :url => data.url}
46
+ elsif data
47
+ {:result => :wait}
48
+ end
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,14 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Helpers
4
+ module SourceJob
5
+ # Enqueue a job for the source based on job type
6
+ def async(job_type,queue_name,params=nil)
7
+ Rhoconnect::SourceJob.queue = queue_name
8
+ Resque.enqueue(Rhoconnect::SourceJob,job_type,@source.id,
9
+ @source.app_id,@source.user_id,params)
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,4 @@
1
+ require 'rhoconnect/handler/helpers/auth_method.rb'
2
+ require 'rhoconnect/handler/helpers/binding.rb'
3
+ require 'rhoconnect/handler/helpers/source_job.rb'
4
+ require 'rhoconnect/handler/helpers/bulk_data.rb'
@@ -0,0 +1,99 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module PluginCallbacks
4
+ module ExecuteMethods
5
+ def execute_push_objects_handler(route_handler)
6
+ source = _load_source
7
+ @model = Rhoconnect::Model::Base.create(source)
8
+ @handler = Rhoconnect::Handler::PluginCallbacks::Runner.new(route_handler, @model, params)
9
+ @handler.run
10
+ 'done'
11
+ end
12
+ # same functionality in push_deletes - only differs in controller's route implementation
13
+ alias_method :execute_push_deletes_handler, :execute_push_objects_handler
14
+
15
+ # the following methods are not exposed as handlers - instead they're used directly
16
+ # TODO: potentially deprecate them - push_* are fast enough already
17
+ def do_fast_insert
18
+ source = _load_source
19
+ timeout = params[:timeout] || 10
20
+ raise_on_expire = params[:raise_on_expire] || false
21
+ new_objs = params[:data]
22
+ source.lock(:md,timeout,raise_on_expire) do |s|
23
+ diff_count = new_objs.size
24
+ source.put_data(:md, new_objs, true)
25
+ source.update_count(:md_size,diff_count)
26
+ end
27
+ source.announce_changes
28
+ 'done'
29
+ end
30
+
31
+ def do_fast_update
32
+ source = _load_source
33
+ timeout = params[:timeout] || 10
34
+ raise_on_expire = params[:raise_on_expire] || false
35
+ remove_hash = params[:delete_data]
36
+ new_hash = params[:data]
37
+
38
+ if ((remove_hash and remove_hash.size > 0) or (new_hash and new_hash.size > 0))
39
+ source.lock(:md,timeout,raise_on_expire) do |s|
40
+ # get the objects from DB, remove prev attr data, add new attr data
41
+ update_keys = Set.new
42
+ update_keys += Set.new(remove_hash.keys) if remove_hash
43
+ update_keys += Set.new(new_hash.keys) if new_hash
44
+ objs_to_update = source.get_objects(:md, update_keys.to_a) || {}
45
+ diff_count = -objs_to_update.size
46
+ # remove old values from DB
47
+ source.delete_data(:md, objs_to_update)
48
+ # update data
49
+ remove_hash.each do |key, obj|
50
+ next unless objs_to_update[key]
51
+ obj.each do |attrib, value|
52
+ objs_to_update[key].delete(attrib)
53
+ objs_to_update.delete(key) if objs_to_update[key].empty?
54
+ end
55
+ end if remove_hash
56
+ new_hash.each do |key, obj|
57
+ objs_to_update[key] ||= {}
58
+ objs_to_update[key].merge!(obj)
59
+ end if new_hash
60
+ # store new data into DB
61
+ source.put_data(:md, objs_to_update, true)
62
+ diff_count += objs_to_update.size
63
+ source.update_count(:md_size,diff_count)
64
+ end
65
+ source.announce_changes
66
+ end
67
+ 'done'
68
+ end
69
+
70
+ def do_fast_delete
71
+ source = _load_source
72
+ timeout = params[:timeout] || 10
73
+ raise_on_expire = params[:raise_on_expire] || false
74
+
75
+ delete_objs = params[:data]
76
+ source.lock(:md,timeout,raise_on_expire) do |s|
77
+ diff_count = -delete_objs.size
78
+ source.delete_data(:md, delete_objs)
79
+ source.update_count(:md_size,diff_count)
80
+ end
81
+ source.announce_changes
82
+ 'done'
83
+ end
84
+
85
+ private
86
+ def _load_source
87
+ source = Source.load(params[:source_id],{:app_id=>APP_NAME,:user_id=>params[:user_id]})
88
+ # if source does not exist create one for dynamic adapter
89
+ unless source
90
+ sconfig = Rhoconnect.source_config(params[:source_id])
91
+ source = Source.create(sconfig.merge!({:name => params[:source_id]}),{:user_id => params[:user_id], :app_id => APP_NAME})
92
+ current_app.sources << source.name
93
+ end
94
+ source
95
+ end
96
+ end
97
+ end
98
+ end
99
+ end
@@ -0,0 +1,28 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module PluginCallbacks
4
+ class Runner
5
+ attr_accessor :source, :model, :route_handler, :params
6
+
7
+ include Rhoconnect::Handler::Helpers::Binding
8
+
9
+ def initialize(route_handler, model, params = {})
10
+ raise ArgumentError.new(UNKNOWN_SOURCE) unless (model and model.source)
11
+ raise ArgumentError.new('Invalid app for source') unless model.source.app
12
+ raise ArgumentError.new('Invalid plugin_callbacks handler') unless route_handler
13
+ # if handler is not bound - bind it to self
14
+ # normally it should be bound to a Controller's instance
15
+
16
+ @source = model.source
17
+ @model = model
18
+ @route_handler = bind_handler(:plugin_callback_handler_method, route_handler)
19
+ @params = params
20
+ end
21
+
22
+ def run
23
+ @route_handler.call
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,67 @@
1
+ require 'rhoconnect/handler/plugin_callbacks/execute_methods.rb'
2
+ require 'rhoconnect/handler/plugin_callbacks/runner.rb'
3
+
4
+ module Rhoconnect
5
+ module Handler
6
+ module PluginCallbacks
7
+ def self.registered(app)
8
+ # push objects
9
+ app.post "/push_objects", \
10
+ { :rc_handler => :push_objects,
11
+ :admin_required => true,
12
+ :login_required => false,
13
+ :source_required => false,
14
+ :client_required => false,
15
+ :deprecated_route => {:verb => :post, :url => ['/api/push_objects', '/api/source/push_objects']}
16
+ } do
17
+ @model.push_objects(params)
18
+ end
19
+
20
+ # push_deletes
21
+ app.post "/push_deletes", \
22
+ { :rc_handler => :push_deletes,
23
+ :admin_required => true,
24
+ :login_required => false,
25
+ :source_required => false,
26
+ :client_required => false,
27
+ :deprecated_route => {:verb => :post, :url => ['/api/push_deletes', '/api/source/push_deletes']}
28
+ } do
29
+ @model.push_deletes(params)
30
+ end
31
+
32
+ # fast insert
33
+ app.post "/fast_insert", \
34
+ { :admin_required => true,
35
+ :login_required => false,
36
+ :source_required => false,
37
+ :client_required => false,
38
+ :deprecated_route => {:verb => :post, :url => ['/api/fast_insert', '/api/source/fast_insert']}
39
+ } do
40
+ do_fast_insert
41
+ end
42
+
43
+ # fast update
44
+ app.post "/fast_update", \
45
+ { :admin_required => true,
46
+ :login_required => false,
47
+ :source_required => false,
48
+ :client_required => false,
49
+ :deprecated_route => {:verb => :post, :url => ['/api/fast_update', '/api/source/fast_update']}
50
+ } do
51
+ do_fast_update
52
+ end
53
+
54
+ # fast object delete
55
+ app.post "/fast_delete", \
56
+ { :admin_required => true,
57
+ :login_required => false,
58
+ :source_required => false,
59
+ :client_required => false,
60
+ :deprecated_route => {:verb => :post, :url => ['/api/fast_delete', '/api/source/fast_delete']}
61
+ } do
62
+ do_fast_delete
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,93 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Query
4
+ class Engine
5
+ attr_accessor :source, :model, :route_handler, :params
6
+
7
+ include Rhoconnect::Handler::Helpers::AuthMethod
8
+ include Rhoconnect::Handler::Helpers::SourceJob
9
+ include Rhoconnect::Handler::Helpers::Binding
10
+
11
+ def initialize(model, route_handler, params = {})
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
+ # if handler is not bound - bind it to self
16
+ # normally it should be bound to a Controller's instance
17
+
18
+ @source = model.source
19
+ @route_handler = bind_handler(:sync_handler_method, route_handler)
20
+ @params = params
21
+ @model = model
22
+ end
23
+
24
+ def do_sync
25
+ query_res = nil
26
+ if source.query_queue or source.queue
27
+ query_res = async(:query, source.query_queue || source.queue, params[:query])
28
+ else
29
+ source.if_need_refresh do
30
+ Rhoconnect::Stats::Record.update("source:query:#{source.name}") do
31
+ if auth_method('login')
32
+ query_res = run_query
33
+ auth_method('logoff')
34
+ end
35
+ # re-wind refresh time in case of error
36
+ query_failure = source.exists?(:errors)
37
+ source.rewind_refresh_time(query_failure)
38
+ end
39
+ end
40
+ end
41
+ query_res
42
+ end
43
+
44
+ def run_query
45
+ errordoc = nil
46
+ docobj = nil
47
+ result = nil
48
+ begin
49
+ errordoc = :errors
50
+ docobj = @source
51
+ [:metadata,:schema].each do |method|
52
+ _get_model_data(method)
53
+ end
54
+ @model.before_query
55
+ @route_handler.call
56
+ result = @model.after_query
57
+ # operation,sync succeeded, remove errors
58
+ docobj.lock(errordoc) do
59
+ docobj.flush_data(errordoc)
60
+ end
61
+ rescue Exception => e
62
+ # store sync,operation exceptions to be sent to all clients for this source/user
63
+ log "Model raised query exception: #{e}"
64
+ log e.backtrace.join("\n")
65
+ docobj.lock(errordoc) do
66
+ docobj.put_data(errordoc,{"query-error"=>{'message'=>e.message}},true)
67
+ end
68
+ end
69
+ # pass through expects result hash
70
+ @source.is_pass_through? ? result : true
71
+ end
72
+
73
+ # Metadata Operation; source model returns json
74
+ def _get_model_data(method)
75
+ if @model.respond_to?(method)
76
+ data = @model.send(method)
77
+ if data
78
+ @source.put_value(method,data)
79
+ if method == :schema
80
+ parsed = JSON.parse(data)
81
+ schema_version = parsed['version']
82
+ raise "Mandatory version key is not defined in model schema method" if schema_version.nil?
83
+ @source.put_value("#{method}_sha1",Digest::SHA1.hexdigest(schema_version))
84
+ else
85
+ @source.put_value("#{method}_sha1",Digest::SHA1.hexdigest(data))
86
+ end
87
+ end
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
@@ -0,0 +1,21 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Query
4
+ module ExecuteMethods
5
+ def execute_query_handler(route_handler)
6
+ content_type :json
7
+ @handler = nil
8
+ if not current_source.is_pass_through?
9
+ @handler = Rhoconnect::Handler::Query::Runner.new(@model, current_client, route_handler, params)
10
+ else
11
+ @handler = Rhoconnect::Handler::Query::PassThroughRunner.new(@model, current_client, route_handler, params)
12
+ end
13
+ formatted_res = @handler.run
14
+ response.headers[Rhoconnect::PAGE_TOKEN_HEADER] = formatted_res[1]['token']
15
+ response.headers[Rhoconnect::PAGE_OBJECT_COUNT_HEADER] = formatted_res[2]['count'].to_s
16
+ response.body = formatted_res.to_json
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,35 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Query
4
+ class PassThroughRunner < Rhoconnect::Handler::Query::Runner
5
+ def run
6
+ token = params[:token]
7
+ ack_token(token) if token
8
+ res = []
9
+ query_result = engine.do_sync
10
+ res = send_new_page(query_result)
11
+ format_result(res[0],res[1],res[2],res[3])
12
+ end
13
+
14
+ def send_new_page(data)
15
+ data ||= {}
16
+ data.each_key do |object_id|
17
+ data[object_id].each { |attrib,value| data[object_id][attrib] = '' if value.nil? }
18
+ end
19
+ token = ''
20
+ compute_errors_page
21
+ res = build_page do |r|
22
+ r['insert'] = data
23
+ r['metadata'] = compute_metadata
24
+ end
25
+ if res['insert']
26
+ token = @client.compute_token(:page_token)
27
+ else
28
+ _delete_errors_page
29
+ end
30
+ [token,0,data.size,res]
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end