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
@@ -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