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
@@ -1,87 +1,196 @@
1
1
  module Document
2
-
2
+ class << self
3
+ def included(base)
4
+ base.extend ClassMethods
5
+ end
6
+ end
7
+
8
+ module ClassMethods
9
+ def define_valid_doctypes(doctypes = [])
10
+ @valid_doctypes ||= Set.new
11
+ doctypes.each do |doctype|
12
+ @valid_doctypes.add(doctype.to_sym)
13
+ end
14
+ @enforce_valid_doctypes ||= true
15
+ end
16
+
17
+ def valid_doctypes
18
+ @valid_doctypes ||= Set.new
19
+ @valid_doctypes
20
+ end
21
+
22
+ def enforce_valid_doctypes
23
+ @enforce_valid_doctypes ||= false
24
+ end
25
+ def enforce_valid_doctypes=(enforce_flag)
26
+ @enforce_valid_doctypes = enforce_flag
27
+ end
28
+ end
29
+
30
+ def set_db_doc(doctype, data, append=false)
31
+ verify_doctype(doctype)
32
+ Store.get_store(store_index(doctype)).set_db_doc(docname(doctype), data, append)
33
+ end
34
+
35
+ def get_db_doc(doctype)
36
+ verify_doctype(doctype)
37
+ Store.get_store(store_index(doctype)).get_db_doc(docname(doctype))
38
+ end
39
+
3
40
  # Store wrapper methods for document
4
41
  def get_data(doctype,type=Hash)
5
- Store.get_data(docname(doctype), type)
42
+ verify_doctype(doctype)
43
+ Store.get_store(store_index(doctype)).get_data(docname(doctype), type)
6
44
  end
7
-
45
+
8
46
  def get_object(doctype, key)
9
- Store.get_object(docname(doctype), key)
47
+ verify_doctype(doctype)
48
+ Store.get_store(store_index(doctype)).get_object(docname(doctype), key)
10
49
  end
11
-
50
+
12
51
  def get_objects(doctype, keys)
13
- Store.get_objects(docname(doctype), keys)
52
+ verify_doctype(doctype)
53
+ Store.get_store(store_index(doctype)).get_objects(docname(doctype), keys)
14
54
  end
15
-
55
+
16
56
  def get_list(doctype)
17
- Store.get_list(docname(doctype))
57
+ verify_doctype(doctype)
58
+ Store.get_store(store_index(doctype)).get_list(docname(doctype))
18
59
  end
19
-
60
+
20
61
  def get_value(doctype)
21
- Store.get_value(docname(doctype))
62
+ verify_doctype(doctype)
63
+ Store.get_store(store_index(doctype)).get_value(docname(doctype))
22
64
  end
23
-
65
+
24
66
  def put_object(doctype, key, data={})
25
- Store.put_object(docname(doctype), key, data)
67
+ verify_doctype(doctype)
68
+ Store.get_store(store_index(doctype)).put_object(docname(doctype), key, data)
26
69
  end
27
-
70
+
28
71
  def put_data(doctype,data,append=false)
29
- Store.put_data(docname(doctype),data,append)
72
+ verify_doctype(doctype)
73
+ Store.get_store(store_index(doctype)).put_data(docname(doctype),data,append)
30
74
  end
31
-
75
+
76
+ def put_tmp_data(doctype, data, append=false)
77
+ Store.get_store(store_index(doctype)).put_tmp_data(docname(doctype),data,append)
78
+ end
79
+
32
80
  def put_list(doctype,data,append=false)
33
- Store.put_list(docname(doctype),data,append)
81
+ verify_doctype(doctype)
82
+ Store.get_store(store_index(doctype)).put_list(docname(doctype),data,append)
34
83
  end
35
-
84
+
36
85
  def update_objects(doctype,updates)
37
- Store.update_objects(docname(doctype),updates)
86
+ verify_doctype(doctype)
87
+ Store.get_store(store_index(doctype)).update_objects(docname(doctype),updates)
38
88
  end
39
-
89
+
40
90
  def remove_objects(doctype,deletes)
41
- Store.delete_objects(docname(doctype),deletes)
91
+ verify_doctype(doctype)
92
+ Store.get_store(store_index(doctype)).delete_objects(docname(doctype),deletes)
42
93
  end
43
-
94
+
44
95
  def put_value(doctype,data)
45
- Store.put_value(docname(doctype),data)
96
+ verify_doctype(doctype)
97
+ Store.get_store(store_index(doctype)).put_value(docname(doctype),data)
46
98
  end
47
-
99
+
48
100
  def delete_data(doctype,data)
49
- Store.delete_data(docname(doctype),data)
50
- end
51
-
52
- def flash_data(doctype)
53
- Store.flash_data(docname(doctype))
101
+ verify_doctype(doctype)
102
+ Store.get_store(store_index(doctype)).delete_data(docname(doctype),data)
54
103
  end
55
-
56
- def flash_source_data(doctype, from_source)
57
- self.source_name=from_source
58
- docnamestr = docname('') + doctype
59
- Store.flash_data(docnamestr)
104
+
105
+ def flush_data(doctype)
106
+ verify_doctype(doctype)
107
+ Store.flush_data(docname(doctype))
60
108
  end
61
-
109
+
62
110
  def rename(srcdoctype,dstdoctype)
63
- Store.rename(docname(srcdoctype),docname(dstdoctype))
111
+ verify_doctype(srcdoctype)
112
+ verify_doctype(dstdoctype)
113
+ Store.get_store(store_index(srcdoctype)).rename(docname(srcdoctype),docname(dstdoctype))
64
114
  end
65
-
66
- def get_zdata(doctype)
67
- Store.get_zdata(docname(doctype))
115
+
116
+ def rename_tmp_data(srcdoctype,dstdoctype)
117
+ verify_doctype(dstdoctype)
118
+ Store.get_store(store_index(srcdoctype)).rename_tmp_data(docname(srcdoctype),docname(dstdoctype))
68
119
  end
69
-
70
- def flush_zdata(doctype)
71
- Store.flush_zdata(docname(doctype))
120
+
121
+ def clone(srcdoctype, dstdocname)
122
+ verify_doctype(srcdoctype)
123
+ Store.get_store(store_index(srcdoctype)).clone(docname(srcdoctype), dstdocname)
72
124
  end
73
-
74
- def put_zdata(doctype,assoc_key, data={},append=false)
75
- Store.put_zdata(docname(doctype),assoc_key, data,append)
76
- end
77
-
125
+
78
126
  # Generate the fully-qualified docname
79
127
  def docname(doctype)
80
128
  "#{self.class.class_prefix(self.class)}:#{self.app_id}:#{self.doc_suffix(doctype)}"
81
129
  end
82
-
130
+
131
+ # default data sharding
132
+ def store_index(doctype)
133
+ 0
134
+ end
135
+
136
+ def compute_store_index(doctype, source, user_id)
137
+ index = 0
138
+ # app-partitioned sources go to 0
139
+ # everything else if sharded
140
+ if(source.partition == :user)
141
+ index_char = Digest::SHA1.hexdigest("#{user_id}:#{source.name}")[0]
142
+ # designate Store 0 only for system data
143
+ num_user_stores = Store.num_stores - 1
144
+ if num_user_stores > 0
145
+ index = index_char.hex/(16/num_user_stores)
146
+ if index >= num_user_stores
147
+ index = num_user_stores - 1
148
+ end
149
+ # make up for fact that user store index starts from 1
150
+ index += 1
151
+ end
152
+ end
153
+ index
154
+ end
155
+
156
+ def exists?(dockey)
157
+ verify_doctype(dockey)
158
+ Store.get_store(store_index(dockey)).exists?(docname(dockey))
159
+ end
160
+
83
161
  # Update count for a given document
84
162
  def update_count(doctype,count)
85
- Store.update_count(docname(doctype), count)
86
- end
87
- end
163
+ verify_doctype(doctype)
164
+ Store.get_store(store_index(doctype)).update_count(docname(doctype), count)
165
+ end
166
+
167
+ def verify_doctype(doctype)
168
+ # doctype must be in the list (or list must be empty - which is default for 'all documents are valid')
169
+ return true if !self.class.enforce_valid_doctypes or self.class.valid_doctypes.member?(doctype.to_sym) or (self.class.valid_doctypes.size == 0)
170
+ raise Rhoconnect::InvalidDocumentException.new("Invalid document type #{doctype} for #{self.class.name}")
171
+ end
172
+
173
+ # interface for doc diffs
174
+ def get_diff_data(srcdoctype, dstdocname, p_size = nil)
175
+ verify_doctype(srcdoctype)
176
+ Store.get_store(store_index(srcdoctype)).get_diff_data(docname(srcdoctype), dstdocname, p_size)
177
+ end
178
+
179
+ def get_diff_data_bruteforce(srcdoctype, dstdocname, p_size = nil)
180
+ verify_doctype(srcdoctype)
181
+ Store.get_store(store_index(srcdoctype)).get_diff_data_bruteforce(docname(srcdoctype), dstdocname, p_size)
182
+ end
183
+
184
+ def update_elements(doctype, inserts_elements_map, deletes_elements_map)
185
+ verify_doctype(doctype)
186
+ Store.get_store(store_index(doctype)).update_elements(docname(doctype), inserts_elements_map, deletes_elements_map)
187
+ end
188
+
189
+ # Computes token for a single client request
190
+ def compute_token(doc_key)
191
+ verify_doctype(doc_key)
192
+ token = get_token
193
+ Store.get_store(store_index(doc_key)).put_value(docname(doc_key),token)
194
+ token.to_s
195
+ end
196
+ end
@@ -0,0 +1,77 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Authenticate
4
+ module ExecuteMethods
5
+ def execute_authenticate_handler(route_handler)
6
+ _logout
7
+ _login(route_handler)
8
+ end
9
+
10
+ def execute_admin_authenticate_handler(route_handler)
11
+ token = ''
12
+ _logout
13
+ _login(route_handler)
14
+ u = User.load(params[:login])
15
+ token = _do_get_api_token(params, u)
16
+ end
17
+
18
+ def execute_rps_authenticate_handler(route_handler)
19
+ _check_login do
20
+ _rps_login(route_handler) ? status(204) : status(401)
21
+ end
22
+ end
23
+
24
+ # helper methods
25
+ private
26
+ def _logout
27
+ session[:login] = nil
28
+ end
29
+
30
+ def _login(route_handler)
31
+ _check_login do
32
+ @handler = Rhoconnect::Handler::Authenticate::Runner.new(current_app, route_handler, params)
33
+ user = @handler.run
34
+ if user
35
+ session[:login] = user.login
36
+ session[:app_name] = APP_NAME
37
+ status(200)
38
+ else
39
+ raise LoginException.new("Unable to authenticate '#{params[:login]}'")
40
+ end
41
+ end
42
+ end
43
+
44
+ def _rps_login(route_handler)
45
+ res = false
46
+ if current_app
47
+ auth = Rack::Auth::Basic::Request.new(request.env)
48
+ if auth.provided? and auth.basic? and auth.credentials
49
+ params[:login] = auth.credentials.first
50
+ params[:password] = auth.credentials.last
51
+ res = route_handler.call
52
+ end
53
+ end
54
+ res
55
+ end
56
+
57
+ def _check_login
58
+ begin
59
+ yield
60
+ rescue LoginException => le
61
+ throw :halt, [401, le.message]
62
+ rescue Exception => e
63
+ throw :halt, [500, e.message]
64
+ end
65
+ end
66
+
67
+ def _do_get_api_token(params,user)
68
+ if user and user.admin == 1 and user.token
69
+ user.token.value
70
+ else
71
+ raise ApiException.new(422, "Invalid/missing API user")
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,49 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Authenticate
4
+ class Runner
5
+ attr_accessor :app, :route_handler, :params
6
+
7
+ include Rhoconnect::Handler::Helpers::Binding
8
+
9
+ def initialize(app, route_handler, params = {})
10
+ raise ArgumentError.new('Invalid app') unless app
11
+ raise ArgumentError.new('Invalid authenticate handler') unless route_handler
12
+ @app = app
13
+ @route_handler = bind_handler(:authenricate_handler_method, route_handler)
14
+ @params = params
15
+ end
16
+
17
+ def run
18
+ if params[:login].nil? or params[:login].empty?
19
+ return false
20
+ end
21
+ user = _do_authenticate
22
+ end
23
+
24
+ private
25
+ def _do_authenticate
26
+ user = nil
27
+ if params[:login] == 'rhoadmin'
28
+ user = @route_handler.call
29
+ else
30
+ if Rhoconnect.appserver
31
+ auth_result = Rhoconnect::Model::DynamicAdapterModel.authenticate(params[:login],params[:password])
32
+ else
33
+ auth_result = @route_handler.call
34
+ end
35
+ if auth_result
36
+ params[:login] = auth_result if auth_result.is_a? String
37
+ user = User.load(params[:login]) if User.is_exist?(params[:login])
38
+ if not user
39
+ user = User.create(:login => params[:login])
40
+ app.users << user.id
41
+ end
42
+ end
43
+ end
44
+ user
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,3 @@
1
+ require 'rhoconnect/handler/helpers'
2
+ require 'rhoconnect/handler/authenticate/runner'
3
+ require 'rhoconnect/handler/authenticate/execute_methods'
@@ -0,0 +1,28 @@
1
+ require 'rhoconnect/handler/helpers'
2
+
3
+ # Bulk Data extenstion
4
+ module Rhoconnect
5
+ module Handler
6
+ module BulkData
7
+ def self.registered(app)
8
+ app.helpers Rhoconnect::Handler::Helpers::BulkData
9
+ # bulk sync request
10
+ app.post "/bulk_data", \
11
+ { :login_required => true,
12
+ :client_required => true,
13
+ :source_required => false,
14
+ :admin_required => false,
15
+ :deprecated_route => {:verb => :get, :url => ['/application/bulk_data', '/api/application/bulk_data']}
16
+ } do
17
+ content_type :json
18
+ sources_param = params[:sources]
19
+ if sources_param.is_a?String
20
+ sources_param = sources_param.split(',')
21
+ end
22
+ data = do_bulk_data(params[:partition].to_sym,current_client, sources_param)
23
+ data.to_json
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,271 @@
1
+ module Rhoconnect
2
+ module Handler
3
+ module Changes
4
+ class Engine
5
+ attr_accessor :source, :model, :route_handler, :params, :operations
6
+
7
+ include Rhoconnect::Handler::Helpers::SourceJob
8
+ include Rhoconnect::Handler::Helpers::Binding
9
+ include Rhoconnect::Handler::Helpers::AuthMethod
10
+
11
+ def initialize(operations, 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 CUD handler') unless route_handler
15
+
16
+ @source = model.source
17
+ # if handler is not bound - bind it to self
18
+ # normally it should be bound to a Controller's instance
19
+ @route_handler = bind_handler(:cud_handler_method, route_handler)
20
+ @params = params
21
+ @model = model
22
+ @operations = operations
23
+ end
24
+
25
+ def do_cud
26
+ if source.cud_queue or source.queue
27
+ async(:cud,source.cud_queue || source.queue)
28
+ else
29
+ run_cud
30
+ end
31
+ end
32
+
33
+ # Pass through CUD to adapter, no data stored
34
+ def do_pass_through_cud
35
+ return if auth_method('login') == false
36
+ res,processed_objects = {},[]
37
+ begin
38
+ operations.each do |op|
39
+ objects = params[op]
40
+ params[:operation] = op if objects
41
+ objects.each do |key,value|
42
+ case op
43
+ when 'create'
44
+ params[:create_object] = value
45
+ @route_handler.call
46
+ when 'update'
47
+ value['id'] = key
48
+ params[:update_object] = value
49
+ @route_handler.call
50
+ when 'delete'
51
+ value['id'] = key
52
+ params[:delete_object] = value
53
+ @route_handler.call
54
+ end
55
+ processed_objects << key
56
+ end if objects
57
+ end
58
+ rescue Exception => e
59
+ log "Error in pass through method: #{e.message}"
60
+ res['error'] = {'message' => e.message }
61
+ end
62
+ auth_method('logoff')
63
+ res['processed'] = processed_objects
64
+ res.to_json
65
+ end
66
+
67
+ def run_cud
68
+ return if auth_method('login') == false
69
+ operations.each do |op|
70
+ send op.to_sym
71
+ end
72
+ auth_method('logoff')
73
+ end
74
+
75
+ # CUD Operations
76
+ def create
77
+ _measure_and_process_cud('create')
78
+ end
79
+
80
+ def update
81
+ _measure_and_process_cud('update')
82
+ end
83
+
84
+ def delete
85
+ _measure_and_process_cud('delete')
86
+ end
87
+
88
+ private
89
+ def _measure_and_process_cud(operation)
90
+ Rhoconnect::Stats::Record.update("source:#{operation}:#{@source.name}") do
91
+ params[:operation] = operation
92
+ _process_cud(operation)
93
+ params.delete(:operation)
94
+ end
95
+ end
96
+
97
+ def _process_create(modified_recs,key,value)
98
+ params[:create_object] = value
99
+ link = route_handler.call
100
+ # Store object-id link for the client
101
+ # If we have a link, store object in client document
102
+ # Otherwise, store object for delete on client
103
+ modified_recs.each do |modified_rec|
104
+ if link
105
+ modified_rec[:links] ||= {}
106
+ modified_rec[:links][modified_rec[:key]] = { 'l' => link.to_s }
107
+ modified_rec[:creates] ||= {}
108
+ modified_rec[:creates][link.to_s] = value
109
+ else
110
+ modified_rec[:deletes] ||= {}
111
+ modified_rec[:deletes][modified_rec[:key]] = value
112
+ end
113
+ end
114
+ end
115
+
116
+ def _process_update(modified_recs,key,value)
117
+ # Add id to object hash to forward to backend call
118
+ value['id'] = key
119
+ params[:update_object] = value
120
+ # Perform operation
121
+ route_handler.call
122
+ end
123
+
124
+ def _process_delete(modified_recs,key,value)
125
+ value['id'] = key
126
+ params[:delete_object] = value
127
+ route_handler.call
128
+ # Perform operation
129
+ modified_recs.each do |modified_rec|
130
+ modified_rec[:dels] ||= {}
131
+ modified_rec[:dels][modified_rec[:key]] = value
132
+ end
133
+ end
134
+
135
+ def _process_cud(operation)
136
+ # take everything from the queue and erase it
137
+ # so that no other process will be able to process it again
138
+ operation_hashes = []
139
+ client_ids = []
140
+ operation_hashes,client_ids = @source.process_queue(operation)
141
+ invalid_meta = @model.validate(operation,operation_hashes,client_ids)
142
+
143
+ errors,links,deletes,creates,dels = {},{},{},{},{}
144
+ operation_hashes.each_with_index do |client_operation_data,index|
145
+ client_id = client_ids[index]
146
+
147
+ current_invalid_meta = invalid_meta[index] || {}
148
+ client_operation_data.each do |key, value|
149
+ begin
150
+ continue_loop = true
151
+ modified_recs = [{:client_id => client_id, :key => key, :value => value }]
152
+ record_invalid_meta = current_invalid_meta[key] || {}
153
+ # Remove object from queue
154
+ client_operation_data.delete(key)
155
+
156
+ # skip the rec - if it is a duplicate of some other record
157
+ next if record_invalid_meta[:duplicate_of]
158
+
159
+ # prepare duplicate docs
160
+ duplicates = record_invalid_meta[:duplicates] || {}
161
+ duplicates.each do |duplicate|
162
+ modified_recs << duplicate
163
+ end
164
+
165
+ # raise conflict error if record is marked with one
166
+ raise Rhoconnect::Model::ObjectConflictErrorException.new(record_invalid_meta[:error]) if record_invalid_meta[:error]
167
+
168
+ # Call on source adapter to process individual object
169
+ case operation
170
+ when 'create'
171
+ _process_create(modified_recs,key,value)
172
+ when 'update'
173
+ _process_update(modified_recs,key,value)
174
+ when 'delete'
175
+ _process_delete(modified_recs,key,value)
176
+ end
177
+ rescue Exception => e
178
+ log "Model raised #{operation} exception: #{e}"
179
+ log e.backtrace.join("\n")
180
+ continue_loop = false
181
+ modified_recs.each do |modified_rec|
182
+ modified_rec[:errors] ||= {}
183
+ modified_rec[:errors][modified_rec[:key]] = modified_rec[:value]
184
+ modified_rec[:errors]["#{modified_rec[:key]}-error"] = {'message'=>e.message}
185
+ end
186
+ end
187
+
188
+ { :errors => errors,
189
+ :links => links,
190
+ :deletes => deletes,
191
+ :creates => creates,
192
+ :dels => dels }.each do |doc_name, doc|
193
+ modified_recs.each do |modified_rec|
194
+ doc[modified_rec[:client_id]] ||= {}
195
+ next unless modified_rec[doc_name]
196
+ doc[modified_rec[:client_id]].merge!(modified_rec[doc_name])
197
+ end
198
+ end
199
+ break unless continue_loop
200
+ end
201
+
202
+ # Record rest of queue (if something in the middle failed)
203
+ if not client_operation_data.empty?
204
+ @source.push_queue(operation,client_id,client_operation_data,true)
205
+ end
206
+ end
207
+
208
+ # now, process all the modified docs
209
+ processed_clients = {}
210
+ client_ids.each do |client_id|
211
+ processed_clients[client_id] = Client.load(client_id,{:source_name => @source.name}) unless processed_clients[client_id]
212
+ end
213
+ { "delete_page" => deletes,
214
+ "#{operation}_links" => links,
215
+ "#{operation}_errors" => errors }.each do |doctype,client_docs|
216
+ client_docs.each do |client_id,data|
217
+ client = processed_clients[client_id]
218
+ client.put_data(doctype,data,true) unless data.empty?
219
+ end
220
+ end
221
+
222
+ if operation == 'create'
223
+ total_creates = {}
224
+ creates.each do |client_id,client_doc|
225
+ next if client_doc.empty?
226
+ client = processed_clients[client_id]
227
+ client.put_data(:cd,client_doc,true)
228
+ client.update_count(:cd_size,client_doc.size)
229
+ total_creates.merge!(client_doc)
230
+ end
231
+ unless total_creates.empty?
232
+ @source.lock(:md) do |s|
233
+ s.put_data(:md,total_creates,true)
234
+ s.update_count(:md_size,total_creates.size)
235
+ end
236
+ end
237
+ end
238
+
239
+ if operation == 'delete'
240
+ # Clean up deleted objects from master document and corresponding client document
241
+ total_dels = {}
242
+ objs = {}
243
+ dels.each do |client_id,client_doc|
244
+ next if client_doc.empty?
245
+ client = processed_clients[client_id]
246
+ client.delete_data(:cd,client_doc)
247
+ client.update_count(:cd_size,-client_doc.size)
248
+ total_dels.merge!(client_doc)
249
+ end
250
+ unless total_dels.empty?
251
+ @source.lock(:md) do |s|
252
+ s.delete_data(:md,total_dels)
253
+ s.update_count(:md_size,-total_dels.size)
254
+ end
255
+ end
256
+ end
257
+ if operation == 'update'
258
+ errors.each do |client_id, error_doc|
259
+ next if error_doc.empty?
260
+ client = processed_clients[client_id]
261
+ cd = client.get_data(:cd)
262
+ error_doc.each do |key, value|
263
+ client.put_data(:update_rollback,{key => cd[key]},true) if cd[key]
264
+ end
265
+ end
266
+ end
267
+ end
268
+ end
269
+ end
270
+ end
271
+ end