rhoconnect 3.0.0.beta1
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.
- data/CHANGELOG +208 -0
- data/CREDITS +38 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +97 -0
- data/LICENSE +75 -0
- data/README.md +10 -0
- data/Rakefile +82 -0
- data/bench/bench +7 -0
- data/bench/bench_runner.rb +112 -0
- data/bench/benchapp/Gemfile +21 -0
- data/bench/benchapp/Gemfile.lock +76 -0
- data/bench/benchapp/Rakefile +22 -0
- data/bench/benchapp/application.rb +39 -0
- data/bench/benchapp/config.ru +36 -0
- data/bench/benchapp/settings/license.key +1 -0
- data/bench/benchapp/settings/settings.yml +20 -0
- data/bench/benchapp/sources/mock_adapter.rb +55 -0
- data/bench/benchapp/sources/queue_mock_adapter.rb +2 -0
- data/bench/benchapp/spec/sources/mock_adapter_spec.rb +25 -0
- data/bench/benchapp/spec/sources/queue_mock_adapter_spec.rb +25 -0
- data/bench/benchapp/spec/spec_helper.rb +42 -0
- data/bench/blobapp/Gemfile +31 -0
- data/bench/blobapp/Gemfile.lock +103 -0
- data/bench/blobapp/Rakefile +25 -0
- data/bench/blobapp/application.rb +44 -0
- data/bench/blobapp/config.ru +36 -0
- data/bench/blobapp/settings/license.key +1 -0
- data/bench/blobapp/settings/settings.yml +16 -0
- data/bench/blobapp/sources/blob_adapter.rb +71 -0
- data/bench/blobapp/spec/sources/blob_adapter_spec.rb +25 -0
- data/bench/blobapp/spec/spec_helper.rb +42 -0
- data/bench/lib/bench/cli.rb +16 -0
- data/bench/lib/bench/logging.rb +13 -0
- data/bench/lib/bench/mock_client.rb +41 -0
- data/bench/lib/bench/result.rb +50 -0
- data/bench/lib/bench/runner.rb +107 -0
- data/bench/lib/bench/session.rb +67 -0
- data/bench/lib/bench/statistics.rb +56 -0
- data/bench/lib/bench/test_data.rb +98 -0
- data/bench/lib/bench/timer.rb +10 -0
- data/bench/lib/bench/utils.rb +49 -0
- data/bench/lib/bench.rb +129 -0
- data/bench/lib/testdata/100-data.txt +148 -0
- data/bench/lib/testdata/5-data.txt +9 -0
- data/bench/lib/testdata/images/icon.ico +0 -0
- data/bench/lib/testdata/images/icon.png +0 -0
- data/bench/lib/testdata/images/loading-Landscape.png +0 -0
- data/bench/lib/testdata/images/loading-LandscapeLeft.png +0 -0
- data/bench/lib/testdata/images/loading-LandscapeRight.png +0 -0
- data/bench/lib/testdata/images/loading-Portrait.png +0 -0
- data/bench/lib/testdata/images/loading-PortraitUpsideDown.png +0 -0
- data/bench/lib/testdata/images/loading.png +0 -0
- data/bench/lib/testdata/images/loading@2x.png +0 -0
- data/bench/run_bench.sh +42 -0
- data/bench/run_blob_script.sh +3 -0
- data/bench/run_cud_script.sh +3 -0
- data/bench/run_query_md_script.sh +3 -0
- data/bench/run_query_only_script.sh +3 -0
- data/bench/run_query_script.sh +3 -0
- data/bench/scripts/blob_cud_script.rb +98 -0
- data/bench/scripts/cud_script.rb +92 -0
- data/bench/scripts/helpers.rb +101 -0
- data/bench/scripts/query_md_script.rb +45 -0
- data/bench/scripts/query_only_script.rb +51 -0
- data/bench/scripts/query_script.rb +45 -0
- data/bench/spec/bench_spec_helper.rb +33 -0
- data/bench/spec/logging_spec.rb +15 -0
- data/bench/spec/mock_adapter_spec.rb +61 -0
- data/bench/spec/mock_client_spec.rb +65 -0
- data/bench/spec/result_spec.rb +61 -0
- data/bench/spec/utils_spec.rb +36 -0
- data/bin/rhoconnect +34 -0
- data/bin/rhoconnect-setup +84 -0
- data/doc/async-jobs.txt +69 -0
- data/doc/authentication.txt +76 -0
- data/doc/benchmarks.txt +168 -0
- data/doc/blob-sync.txt +130 -0
- data/doc/bulk-sync.txt +102 -0
- data/doc/client.txt +432 -0
- data/doc/command-line.txt +210 -0
- data/doc/contributing.txt +60 -0
- data/doc/deploying.txt +82 -0
- data/doc/install.txt +28 -0
- data/doc/introduction.txt +20 -0
- data/doc/licensing.txt +18 -0
- data/doc/metadata.txt +458 -0
- data/doc/migration.txt +182 -0
- data/doc/public/css/print.css +29 -0
- data/doc/public/css/screen.css +257 -0
- data/doc/public/css/style.css +20 -0
- data/doc/push.txt +135 -0
- data/doc/release.txt +41 -0
- data/doc/rest-api.txt +367 -0
- data/doc/source-adapters.txt +325 -0
- data/doc/stats-middleware.txt +69 -0
- data/doc/testing.txt +222 -0
- data/doc/tutorial.txt +315 -0
- data/doc/web-console.txt +35 -0
- data/examples/simple/Rakefile +14 -0
- data/examples/simple/application.rb +27 -0
- data/examples/simple/config.ru +49 -0
- data/examples/simple/settings/license.key +1 -0
- data/examples/simple/settings/settings.yml +23 -0
- data/examples/simple/sources/sample_adapter.rb +5 -0
- data/examples/simple/sources/simple_adapter.rb +5 -0
- data/generators/rhoconnect.rb +119 -0
- data/generators/templates/application/Gemfile +21 -0
- data/generators/templates/application/Rakefile +22 -0
- data/generators/templates/application/application.rb +39 -0
- data/generators/templates/application/config.ru +36 -0
- data/generators/templates/application/settings/license.key +1 -0
- data/generators/templates/application/settings/settings.yml +14 -0
- data/generators/templates/application/spec/spec_helper.rb +42 -0
- data/generators/templates/source/source_adapter.rb +47 -0
- data/generators/templates/source/source_spec.rb +25 -0
- data/install.sh +408 -0
- data/installer/unix-like/rho_connect_install_checkers.rb +140 -0
- data/installer/unix-like/rho_connect_install_constants.rb +51 -0
- data/installer/unix-like/rho_connect_install_debian.rb +63 -0
- data/installer/unix-like/rho_connect_install_dnd.rb +58 -0
- data/installer/unix-like/rho_connect_install_get_params.rb +30 -0
- data/installer/unix-like/rho_connect_install_installers.rb +142 -0
- data/installer/unix-like/rho_connect_install_utilities.rb +85 -0
- data/installer/unix-like/rho_connect_install_yum.rb +63 -0
- data/installer/unix-like/rhoinstaller.rb +89 -0
- data/installer/utils/create_texts.rb +366 -0
- data/installer/utils/install_test.rb +140 -0
- data/installer/windows/EnvVarUpdate.nsh +328 -0
- data/installer/windows/ServiceLib.nsh +369 -0
- data/installer/windows/configUi.ini +44 -0
- data/installer/windows/icon.ico +0 -0
- data/installer/windows/rhosync.nsi +418 -0
- data/installer/windows/uninstall.bat +7 -0
- data/lib/rhoconnect/api/admin/get_api_token.rb +14 -0
- data/lib/rhoconnect/api/admin/get_license_info.rb +8 -0
- data/lib/rhoconnect/api/admin/login.rb +6 -0
- data/lib/rhoconnect/api/admin/reset.rb +10 -0
- data/lib/rhoconnect/api/admin/stats.rb +21 -0
- data/lib/rhoconnect/api/application/bulk_data.rb +7 -0
- data/lib/rhoconnect/api/application/clientcreate.rb +8 -0
- data/lib/rhoconnect/api/application/clientlogin.rb +6 -0
- data/lib/rhoconnect/api/application/clientregister.rb +6 -0
- data/lib/rhoconnect/api/application/clientreset.rb +6 -0
- data/lib/rhoconnect/api/application/query.rb +7 -0
- data/lib/rhoconnect/api/application/queue_updates.rb +6 -0
- data/lib/rhoconnect/api/application/search.rb +6 -0
- data/lib/rhoconnect/api/client/create_client.rb +3 -0
- data/lib/rhoconnect/api/client/delete_client.rb +5 -0
- data/lib/rhoconnect/api/client/get_client_params.rb +3 -0
- data/lib/rhoconnect/api/client/list_client_docs.rb +12 -0
- data/lib/rhoconnect/api/client/list_clients.rb +3 -0
- data/lib/rhoconnect/api/client/ping.rb +7 -0
- data/lib/rhoconnect/api/source/get_adapter.rb +3 -0
- data/lib/rhoconnect/api/source/get_db_doc.rb +7 -0
- data/lib/rhoconnect/api/source/get_source_params.rb +3 -0
- data/lib/rhoconnect/api/source/list_source_docs.rb +10 -0
- data/lib/rhoconnect/api/source/list_sources.rb +15 -0
- data/lib/rhoconnect/api/source/push_deletes.rb +8 -0
- data/lib/rhoconnect/api/source/push_objects.rb +8 -0
- data/lib/rhoconnect/api/source/save_adapter.rb +3 -0
- data/lib/rhoconnect/api/source/set_db_doc.rb +8 -0
- data/lib/rhoconnect/api/source/set_refresh_time.rb +8 -0
- data/lib/rhoconnect/api/source/upload_file.rb +4 -0
- data/lib/rhoconnect/api/user/create_user.rb +7 -0
- data/lib/rhoconnect/api/user/delete_user.rb +9 -0
- data/lib/rhoconnect/api/user/list_users.rb +3 -0
- data/lib/rhoconnect/api/user/update_user.rb +4 -0
- data/lib/rhoconnect/api_token.rb +19 -0
- data/lib/rhoconnect/app.rb +76 -0
- data/lib/rhoconnect/bulk_data/bulk_data.rb +88 -0
- data/lib/rhoconnect/bulk_data/syncdb.index.schema +4 -0
- data/lib/rhoconnect/bulk_data/syncdb.schema +41 -0
- data/lib/rhoconnect/bulk_data.rb +2 -0
- data/lib/rhoconnect/client.rb +96 -0
- data/lib/rhoconnect/client_sync.rb +412 -0
- data/lib/rhoconnect/console/app/helpers/auth_helper.rb +22 -0
- data/lib/rhoconnect/console/app/helpers/extensions.rb +19 -0
- data/lib/rhoconnect/console/app/helpers/helpers.rb +57 -0
- data/lib/rhoconnect/console/app/public/ThickBox.css +649 -0
- data/lib/rhoconnect/console/app/public/home.css +438 -0
- data/lib/rhoconnect/console/app/public/images/foot_logo_rhoconnect.png +0 -0
- data/lib/rhoconnect/console/app/public/images/header_halo.jpg +0 -0
- data/lib/rhoconnect/console/app/public/images/land_separator.gif +0 -0
- data/lib/rhoconnect/console/app/public/images/landing_header.jpg +0 -0
- data/lib/rhoconnect/console/app/public/images/logo_rhoconnect.png +0 -0
- data/lib/rhoconnect/console/app/public/images/rhomobile_rhohub_logo.png +0 -0
- data/lib/rhoconnect/console/app/public/images/tabs_separator.png +0 -0
- data/lib/rhoconnect/console/app/public/jqplot/excanvas.min.js +35 -0
- data/lib/rhoconnect/console/app/public/jqplot/jqplot.barRenderer.min.js +34 -0
- data/lib/rhoconnect/console/app/public/jqplot/jqplot.canvasAxisLabelRenderer.js +187 -0
- data/lib/rhoconnect/console/app/public/jqplot/jqplot.canvasAxisTickRenderer.js +226 -0
- data/lib/rhoconnect/console/app/public/jqplot/jqplot.canvasTextRenderer.js +408 -0
- data/lib/rhoconnect/console/app/public/jqplot/jqplot.categoryAxisRenderer.min.js +34 -0
- data/lib/rhoconnect/console/app/public/jqplot/jqplot.cursor.js +952 -0
- data/lib/rhoconnect/console/app/public/jqplot/jqplot.dateAxisRenderer.js +313 -0
- data/lib/rhoconnect/console/app/public/jqplot/jqplot.dateAxisRenderer.min.js +34 -0
- data/lib/rhoconnect/console/app/public/jqplot/jqplot.pointLabels.min.js +34 -0
- data/lib/rhoconnect/console/app/public/jqplot/jquery-1.4.2.min.js +154 -0
- data/lib/rhoconnect/console/app/public/jqplot/jquery.jqplot.min.css +1 -0
- data/lib/rhoconnect/console/app/public/jqplot/jquery.jqplot.min.js +34 -0
- data/lib/rhoconnect/console/app/public/main.css +7 -0
- data/lib/rhoconnect/console/app/public/reset.css +76 -0
- data/lib/rhoconnect/console/app/public/style.css +2201 -0
- data/lib/rhoconnect/console/app/public/text.txt +0 -0
- data/lib/rhoconnect/console/app/routes/adapter.rb +28 -0
- data/lib/rhoconnect/console/app/routes/auth.rb +29 -0
- data/lib/rhoconnect/console/app/routes/client.rb +31 -0
- data/lib/rhoconnect/console/app/routes/docs.rb +145 -0
- data/lib/rhoconnect/console/app/routes/heroku.rb +19 -0
- data/lib/rhoconnect/console/app/routes/home.rb +63 -0
- data/lib/rhoconnect/console/app/routes/timing.rb +242 -0
- data/lib/rhoconnect/console/app/routes/user.rb +117 -0
- data/lib/rhoconnect/console/app/views/adapter.erb +16 -0
- data/lib/rhoconnect/console/app/views/client.erb +30 -0
- data/lib/rhoconnect/console/app/views/content.erb +14 -0
- data/lib/rhoconnect/console/app/views/doc.erb +8 -0
- data/lib/rhoconnect/console/app/views/docdata.erb +28 -0
- data/lib/rhoconnect/console/app/views/docs.erb +30 -0
- data/lib/rhoconnect/console/app/views/edituser.erb +13 -0
- data/lib/rhoconnect/console/app/views/headermenu.erb +40 -0
- data/lib/rhoconnect/console/app/views/home.erb +24 -0
- data/lib/rhoconnect/console/app/views/index.erb +58 -0
- data/lib/rhoconnect/console/app/views/jqplot.erb +52 -0
- data/lib/rhoconnect/console/app/views/layout.erb +165 -0
- data/lib/rhoconnect/console/app/views/login.erb +26 -0
- data/lib/rhoconnect/console/app/views/newuser.erb +17 -0
- data/lib/rhoconnect/console/app/views/ping.erb +28 -0
- data/lib/rhoconnect/console/app/views/result.erb +11 -0
- data/lib/rhoconnect/console/app/views/rightboxlinks.erb +15 -0
- data/lib/rhoconnect/console/app/views/select_doc.erb +17 -0
- data/lib/rhoconnect/console/app/views/upload_doc.erb +23 -0
- data/lib/rhoconnect/console/app/views/user.erb +29 -0
- data/lib/rhoconnect/console/app/views/users.erb +12 -0
- data/lib/rhoconnect/console/rhoconnect_api.rb +245 -0
- data/lib/rhoconnect/console/server.rb +32 -0
- data/lib/rhoconnect/console.rb +3 -0
- data/lib/rhoconnect/cors.rb +229 -0
- data/lib/rhoconnect/credential.rb +9 -0
- data/lib/rhoconnect/db_adapter.rb +46 -0
- data/lib/rhoconnect/document.rb +49 -0
- data/lib/rhoconnect/dynamic_adapter.rb +91 -0
- data/lib/rhoconnect/generator.rb +1 -0
- data/lib/rhoconnect/jobs/bulk_data_job.rb +203 -0
- data/lib/rhoconnect/jobs/ping_job.rb +46 -0
- data/lib/rhoconnect/jobs/source_job.rb +16 -0
- data/lib/rhoconnect/license.rb +86 -0
- data/lib/rhoconnect/lock_ops.rb +11 -0
- data/lib/rhoconnect/model.rb +414 -0
- data/lib/rhoconnect/ping/android.rb +56 -0
- data/lib/rhoconnect/ping/apple.rb +52 -0
- data/lib/rhoconnect/ping/blackberry.rb +56 -0
- data/lib/rhoconnect/ping.rb +3 -0
- data/lib/rhoconnect/read_state.rb +31 -0
- data/lib/rhoconnect/rho_indifferent_access.rb +88 -0
- data/lib/rhoconnect/server/views/index.erb +13 -0
- data/lib/rhoconnect/server.rb +286 -0
- data/lib/rhoconnect/source.rb +289 -0
- data/lib/rhoconnect/source_adapter.rb +123 -0
- data/lib/rhoconnect/source_sync.rb +302 -0
- data/lib/rhoconnect/stats/middleware.rb +20 -0
- data/lib/rhoconnect/stats/record.rb +108 -0
- data/lib/rhoconnect/store.rb +232 -0
- data/lib/rhoconnect/tasks.rb +350 -0
- data/lib/rhoconnect/test_methods.rb +220 -0
- data/lib/rhoconnect/user.rb +95 -0
- data/lib/rhoconnect/version.rb +3 -0
- data/lib/rhoconnect/x_domain_session_wrapper.rb +53 -0
- data/lib/rhoconnect.rb +285 -0
- data/rhoconnect.gemspec +67 -0
- data/spec/api/admin/api_token_spec.rb +14 -0
- data/spec/api/admin/get_api_token_spec.rb +36 -0
- data/spec/api/admin/get_license_info_spec.rb +38 -0
- data/spec/api/admin/reset_spec.rb +22 -0
- data/spec/api/admin/stats_spec.rb +66 -0
- data/spec/api/api_helper.rb +21 -0
- data/spec/api/application/rhoconnect_api_spec.rb +548 -0
- data/spec/api/client/create_client_spec.rb +13 -0
- data/spec/api/client/delete_client_spec.rb +13 -0
- data/spec/api/client/get_client_params_spec.rb +18 -0
- data/spec/api/client/list_client_docs_spec.rb +32 -0
- data/spec/api/client/list_clients_spec.rb +22 -0
- data/spec/api/client/ping_spec.rb +23 -0
- data/spec/api/rhosync_api_spec.rb.orig +606 -0
- data/spec/api/source/adapter_spec.rb +29 -0
- data/spec/api/source/get_db_doc_spec.rb +21 -0
- data/spec/api/source/get_source_params_spec.rb +32 -0
- data/spec/api/source/list_source_docs_spec.rb +25 -0
- data/spec/api/source/list_sources_spec.rb +26 -0
- data/spec/api/source/push_deletes_spec.rb +18 -0
- data/spec/api/source/push_objects_spec.rb +27 -0
- data/spec/api/source/set_db_doc_spec.rb +19 -0
- data/spec/api/source/set_refresh_time_spec.rb +43 -0
- data/spec/api/source/upload_file_spec.rb +26 -0
- data/spec/api/user/create_user_spec.rb +16 -0
- data/spec/api/user/delete_user_spec.rb +36 -0
- data/spec/api/user/list_users_spec.rb +30 -0
- data/spec/api/user/update_user_spec.rb +31 -0
- data/spec/api_token_spec.rb +14 -0
- data/spec/app_spec.rb +18 -0
- data/spec/apps/emptyapp/application.rb +27 -0
- data/spec/apps/emptyapp/settings/license.key +1 -0
- data/spec/apps/emptyapp/settings/settings.yml +14 -0
- data/spec/apps/rhotestapp/Rakefile +1 -0
- data/spec/apps/rhotestapp/application.rb +19 -0
- data/spec/apps/rhotestapp/config.ru +1 -0
- data/spec/apps/rhotestapp/settings/apple_fake_cert.pem +1 -0
- data/spec/apps/rhotestapp/settings/license.key +1 -0
- data/spec/apps/rhotestapp/settings/settings.yml +36 -0
- data/spec/apps/rhotestapp/sources/base_adapter.rb +9 -0
- data/spec/apps/rhotestapp/sources/fixed_schema_adapter.rb +28 -0
- data/spec/apps/rhotestapp/sources/sample_adapter.rb +71 -0
- data/spec/apps/rhotestapp/sources/simple_adapter.rb +41 -0
- data/spec/apps/rhotestapp/sources/sub_adapter.rb +7 -0
- data/spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem/mygem.rb +8 -0
- data/spec/apps/rhotestapp/vendor/mygem-0.1.0/lib/mygem.rb +1 -0
- data/spec/bulk_data/bulk_data_spec.rb +97 -0
- data/spec/client_spec.rb +124 -0
- data/spec/client_sync_spec.rb +774 -0
- data/spec/doc/base.html +72 -0
- data/spec/doc/doc_spec.rb +376 -0
- data/spec/doc/footer.html +4 -0
- data/spec/doc/header.html +30 -0
- data/spec/document_spec.rb +31 -0
- data/spec/dynamic_adapter_spec.rb +43 -0
- data/spec/factories/factories.rb +17 -0
- data/spec/generator/generator_spec.rb +58 -0
- data/spec/generator/generator_spec_helper.rb +9 -0
- data/spec/jobs/bulk_data_job_spec.rb +125 -0
- data/spec/jobs/ping_job_spec.rb +102 -0
- data/spec/jobs/source_job_spec.rb +29 -0
- data/spec/license_spec.rb +66 -0
- data/spec/model_spec.rb +273 -0
- data/spec/perf/bulk_data_perf_spec.rb +32 -0
- data/spec/perf/perf_spec_helper.rb +50 -0
- data/spec/perf/store_perf_spec.rb +27 -0
- data/spec/ping/android_spec.rb +91 -0
- data/spec/ping/apple_spec.rb +70 -0
- data/spec/ping/blackberry_spec.rb +62 -0
- data/spec/read_state_spec.rb +35 -0
- data/spec/rhosync_spec.rb +75 -0
- data/spec/server/cors_spec.rb +287 -0
- data/spec/server/server_spec.rb +470 -0
- data/spec/server/x_domain_session_wrapper_spec.rb +150 -0
- data/spec/source_adapter_spec.rb +125 -0
- data/spec/source_spec.rb +114 -0
- data/spec/source_sync_spec.rb +328 -0
- data/spec/spec.opts +4 -0
- data/spec/spec_helper.rb +231 -0
- data/spec/stats/middleware_spec.rb +53 -0
- data/spec/stats/record_spec.rb +92 -0
- data/spec/store_spec.rb +251 -0
- data/spec/support/shared_examples.rb +168 -0
- data/spec/sync_states_spec.rb +72 -0
- data/spec/test_methods_spec.rb +134 -0
- data/spec/testdata/1000-data.txt +1414 -0
- data/spec/testdata/compressed/compress-data.txt +1 -0
- data/spec/testdata/upload1.txt +1 -0
- data/spec/testdata/upload2.txt +1 -0
- data/spec/user_spec.rb +139 -0
- data/tasks/redis.rake +206 -0
- metadata +706 -0
|
@@ -0,0 +1,350 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'zip/zip'
|
|
3
|
+
require 'uri'
|
|
4
|
+
require File.join(File.dirname(__FILE__),'console','rhoconnect_api')
|
|
5
|
+
|
|
6
|
+
module Rhoconnect
|
|
7
|
+
module TaskHelper
|
|
8
|
+
def post(path,params)
|
|
9
|
+
req = Net::HTTP.new($host,$port)
|
|
10
|
+
resp = req.post(path, params.to_json, 'Content-Type' => 'application/json')
|
|
11
|
+
print_resp(resp, resp.is_a?(Net::HTTPSuccess) ? true : false)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def print_resp(resp,success=true)
|
|
15
|
+
if success
|
|
16
|
+
puts "=> OK"
|
|
17
|
+
else
|
|
18
|
+
puts "=> FAILED"
|
|
19
|
+
end
|
|
20
|
+
puts "=> " + resp.body if resp and resp.body and resp.body.length > 0
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def archive(path)
|
|
24
|
+
File.join(path,File.basename(path))+'.zip'
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def ask(msg)
|
|
28
|
+
print msg
|
|
29
|
+
STDIN.gets.chomp
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def load_settings(file)
|
|
33
|
+
begin
|
|
34
|
+
$settings = YAML.load_file(file)
|
|
35
|
+
rescue Exception => e
|
|
36
|
+
puts "Error opening settings file #{file}: #{e}."
|
|
37
|
+
puts e.backtrace.join("\n")
|
|
38
|
+
raise e
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def rhoconnect_socket
|
|
43
|
+
"/tmp/rhoconnect.dtach"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def rhoconnect_pid
|
|
47
|
+
"/tmp/rhoconnect.pid"
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
def windows?
|
|
51
|
+
RUBY_PLATFORM =~ /(win|w)32$/
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
def ruby19?
|
|
55
|
+
RUBY_VERSION =~ /1.9/
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def jruby?
|
|
59
|
+
defined?(JRUBY_VERSION)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def thin?
|
|
63
|
+
begin
|
|
64
|
+
require 'thin'
|
|
65
|
+
'rackup -s thin'
|
|
66
|
+
rescue LoadError
|
|
67
|
+
nil
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def mongrel?
|
|
72
|
+
begin
|
|
73
|
+
require 'mongrel'
|
|
74
|
+
'rackup -s mongrel'
|
|
75
|
+
rescue LoadError
|
|
76
|
+
nil
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def report_missing_server
|
|
81
|
+
msg =<<-EOF
|
|
82
|
+
Could not find 'thin' or 'mongrel' on your system. Please install one:
|
|
83
|
+
gem install thin
|
|
84
|
+
or
|
|
85
|
+
gem install mongrel
|
|
86
|
+
EOF
|
|
87
|
+
puts msg
|
|
88
|
+
exit 1
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# def jetty_rackup?
|
|
92
|
+
# 'jruby -S jetty-rackup'
|
|
93
|
+
# end
|
|
94
|
+
|
|
95
|
+
def trinidad?
|
|
96
|
+
'jruby -S trinidad -p 9292 -r config.ru'
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
namespace :rhoconnect do
|
|
102
|
+
include Rhoconnect::TaskHelper
|
|
103
|
+
include RhoconnectApi
|
|
104
|
+
|
|
105
|
+
task :config do
|
|
106
|
+
$settings = load_settings(File.join('settings','settings.yml'))
|
|
107
|
+
$env = (ENV['RHO_ENV'] || ENV['RACK_ENV'] || :development).to_sym
|
|
108
|
+
uri = URI.parse($settings[$env][:syncserver])
|
|
109
|
+
$url = "#{uri.scheme}://#{uri.host}"
|
|
110
|
+
$url = "#{$url}:#{uri.port}" if uri.port && uri.port != 80
|
|
111
|
+
$host = uri.host
|
|
112
|
+
$port = uri.port
|
|
113
|
+
$appname = $settings[$env][:syncserver].split('/').last
|
|
114
|
+
$token_file = File.join(ENV['HOME'],'.rhoconnect_token')
|
|
115
|
+
$token = File.read($token_file) if File.exist?($token_file)
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
task :dtach_installed do
|
|
119
|
+
if !windows? and (`which dtach` == '')
|
|
120
|
+
puts "WARNING: dtach not installed or not on path, some tasks will not work!"
|
|
121
|
+
puts " Install with '[sudo] rake dtach:install'"
|
|
122
|
+
exit
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
desc "Reset the rhoconnect database (you will need to run rhoconnect:get_token afterwards)"
|
|
127
|
+
task :reset => :config do
|
|
128
|
+
confirm = ask " Are you sure? Resetting will remove all data!\n It will also return an error code to all\n existing devices when they connect! (yes/no): "
|
|
129
|
+
if confirm == 'yes'
|
|
130
|
+
RhoconnectApi.reset($url,$token)
|
|
131
|
+
puts "Database reset."
|
|
132
|
+
else
|
|
133
|
+
puts "Cancelling."
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
desc "Fetches current api token from rhoconnect"
|
|
138
|
+
task :get_token => :config do
|
|
139
|
+
password = ''
|
|
140
|
+
login = ask "admin login: "
|
|
141
|
+
begin
|
|
142
|
+
system "stty -echo"
|
|
143
|
+
password = ask "\nadmin password: "
|
|
144
|
+
system "stty echo"
|
|
145
|
+
rescue NoMethodError, Interrupt
|
|
146
|
+
system "stty echo"
|
|
147
|
+
exit
|
|
148
|
+
end
|
|
149
|
+
puts ''
|
|
150
|
+
begin
|
|
151
|
+
$token = RhoconnectApi.get_token($url,login,password)
|
|
152
|
+
rescue
|
|
153
|
+
puts "Login failed."
|
|
154
|
+
exit
|
|
155
|
+
end
|
|
156
|
+
File.open($token_file,'w') {|f| f.write $token}
|
|
157
|
+
puts "Token is saved in: #{$token_file}"
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
desc "Clean rhoconnect, get token, and create new user"
|
|
161
|
+
task :clean_start => [:get_token, :reset, :get_token, :create_user]
|
|
162
|
+
|
|
163
|
+
desc "Alias for `rake rhoconnect:stop; rake rhoconnect:start`"
|
|
164
|
+
task :restart => [:stop, :start]
|
|
165
|
+
|
|
166
|
+
desc "Creates and subscribes user for application in rhoconnect"
|
|
167
|
+
task :create_user => :config do
|
|
168
|
+
password = ''
|
|
169
|
+
login = ask "new user login: "
|
|
170
|
+
begin
|
|
171
|
+
system "stty -echo"
|
|
172
|
+
password = ask "\nnew user password: "
|
|
173
|
+
system "stty echo"
|
|
174
|
+
rescue NoMethodError, Interrupt
|
|
175
|
+
system "stty echo"
|
|
176
|
+
exit
|
|
177
|
+
end
|
|
178
|
+
puts ''
|
|
179
|
+
RhoconnectApi.create_user($url,$token,login,password)
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
desc "Deletes a user from rhoconnect"
|
|
183
|
+
task :delete_user => :config do
|
|
184
|
+
login = ask "user to delete: "
|
|
185
|
+
RhoconnectApi.delete_user($url,$token,login)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
desc "Deletes a device from rhoconnect"
|
|
189
|
+
task :delete_device => :config do
|
|
190
|
+
user_id = ask "device's user_id: "
|
|
191
|
+
device_id = ask "device to delete: "
|
|
192
|
+
RhoconnectApi.delete_client($url,$token,user_id,device_id)
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
desc "Sets the admin password"
|
|
196
|
+
task :set_admin_password => :get_token do
|
|
197
|
+
new_pass,new_pass_confirm = '',''
|
|
198
|
+
begin
|
|
199
|
+
system "stty -echo"
|
|
200
|
+
new_pass = ask "\nnew admin password: "
|
|
201
|
+
new_pass_confirm = ask "\nconfirm new admin password: "
|
|
202
|
+
system "stty echo"
|
|
203
|
+
rescue NoMethodError, Interrupt
|
|
204
|
+
system "stty echo"
|
|
205
|
+
exit
|
|
206
|
+
end
|
|
207
|
+
if new_pass == ''
|
|
208
|
+
puts "\nNew password can't be empty."
|
|
209
|
+
elsif new_pass == new_pass_confirm
|
|
210
|
+
puts ""
|
|
211
|
+
post("/api/update_user", {:app_name => $appname, :api_token => $token,
|
|
212
|
+
:attributes => {:new_password => new_pass}})
|
|
213
|
+
else
|
|
214
|
+
puts "\nNew password and confirmation must match."
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
desc "Reset source refresh time"
|
|
219
|
+
task :reset_refresh => :config do
|
|
220
|
+
user = ask "user: "
|
|
221
|
+
source_name = ask "source name: "
|
|
222
|
+
RestClient.post("#{$url}/api/set_refresh_time", {:api_token => $token,
|
|
223
|
+
:user_name => user, :source_name => source_name})
|
|
224
|
+
end
|
|
225
|
+
|
|
226
|
+
begin
|
|
227
|
+
require 'rspec/core/rake_task'
|
|
228
|
+
require 'rcov/rcovtask' unless (windows? || ruby19?)
|
|
229
|
+
|
|
230
|
+
desc "Run source adapter specs"
|
|
231
|
+
task :spec do
|
|
232
|
+
files = File.join('spec','**','*_spec.rb')
|
|
233
|
+
RSpec::Core::RakeTask.new('rhoconnect:spec') do |t|
|
|
234
|
+
t.pattern = FileList[files]
|
|
235
|
+
t.rspec_opts = %w(-fn -b --color)
|
|
236
|
+
unless (windows? || ruby19?)
|
|
237
|
+
t.rcov = true
|
|
238
|
+
t.rcov_opts = ['--exclude', 'spec/*,gems/*']
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
rescue LoadError
|
|
243
|
+
if windows?
|
|
244
|
+
puts "rspec not available. Install it with: "
|
|
245
|
+
puts "gem install rspec\n\n"
|
|
246
|
+
else
|
|
247
|
+
puts "rspec / rcov not available. Install it with: "
|
|
248
|
+
puts "gem install rspec rcov\n\n"
|
|
249
|
+
end
|
|
250
|
+
end
|
|
251
|
+
|
|
252
|
+
desc "Start rhoconnect server"
|
|
253
|
+
task :start => :dtach_installed do
|
|
254
|
+
cmd = (jruby?) ? trinidad? : (thin? || mongrel? || report_missing_server)
|
|
255
|
+
if windows?
|
|
256
|
+
puts 'Starting server in new window...'
|
|
257
|
+
system("start cmd.exe /c #{cmd} config.ru")
|
|
258
|
+
elsif jruby?
|
|
259
|
+
puts 'Starting server in jruby environment...'
|
|
260
|
+
system("#{cmd}")
|
|
261
|
+
else
|
|
262
|
+
puts 'Detach with Ctrl+\ Re-attach with rake rhoconnect:attach'
|
|
263
|
+
sleep 2
|
|
264
|
+
sh "dtach -A #{rhoconnect_socket} #{cmd} config.ru -P #{rhoconnect_pid}"
|
|
265
|
+
end
|
|
266
|
+
end
|
|
267
|
+
|
|
268
|
+
desc "run rhoconnect console"
|
|
269
|
+
task :console, :environment do |t, args|
|
|
270
|
+
if RedisRunner.running?
|
|
271
|
+
#load development environment by default
|
|
272
|
+
ENV['RACK_ENV'] = args[:environment] || 'development'
|
|
273
|
+
sh "irb -rubygems -r #{File.join(File.dirname(__FILE__),'console')} -r #{File.dirname(__FILE__)} -r application"
|
|
274
|
+
else
|
|
275
|
+
puts "Redis is not running. Please start it by running 'rake redis:start' command."
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
desc "Stop rhoconnect server"
|
|
280
|
+
task :stop => :dtach_installed do
|
|
281
|
+
sh "cat #{rhoconnect_pid} | xargs kill -3" unless windows?
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
desc "Attach to rhoconnect console"
|
|
285
|
+
task :attach => :dtach_installed do
|
|
286
|
+
sh "dtach -a #{rhoconnect_socket}" unless windows?
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
desc "Launch the web console in a browser - uses :syncserver: in settings.yml"
|
|
290
|
+
task :web => :config do
|
|
291
|
+
windows? ? sh("start #{$url}") : sh("open #{$url}")
|
|
292
|
+
end
|
|
293
|
+
|
|
294
|
+
desc "Flush data store - WARNING: THIS REMOVES ALL DATA IN RHOCONNECT"
|
|
295
|
+
task :flushdb => :config do
|
|
296
|
+
puts "*** WARNING: THIS WILL REMOVE ALL DATA FROM YOUR REDIS STORE ***"
|
|
297
|
+
confirm = ask "Are you sure (please answer yes/no)? "
|
|
298
|
+
if confirm == 'yes'
|
|
299
|
+
Redis.new.flushdb
|
|
300
|
+
puts "Database flushed..."
|
|
301
|
+
else
|
|
302
|
+
puts "Aborted..."
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
desc "Generate a cryptographically secure secret session key"
|
|
307
|
+
task :secret do
|
|
308
|
+
begin
|
|
309
|
+
require 'securerandom'
|
|
310
|
+
puts SecureRandom.hex(64)
|
|
311
|
+
rescue LoadError
|
|
312
|
+
puts "Missing secure random generator. Try running `rake secret` in a rails application instead."
|
|
313
|
+
end
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
desc "Build executable WAR file to be used in Java App Servers"
|
|
317
|
+
task :war do
|
|
318
|
+
if jruby? then
|
|
319
|
+
puts "building the WAR file"
|
|
320
|
+
if not File::exists? "config/warble.rb"
|
|
321
|
+
puts "generating Warbler's config file"
|
|
322
|
+
includeDirs = []
|
|
323
|
+
Dir.mkdir('config') if not File.exists?('config')
|
|
324
|
+
aFile = File.new("config/warble.rb", "w+")
|
|
325
|
+
if aFile
|
|
326
|
+
includeDirs = FileList['*'].exclude do |entry|
|
|
327
|
+
entry if (not File.directory? entry) || (entry == 'spec')
|
|
328
|
+
end
|
|
329
|
+
configFile = "Warbler::Config.new do |config|\n" +
|
|
330
|
+
"config.dirs = %w(#{includeDirs.join(' ')})\n" +
|
|
331
|
+
"config.includes = FileList[\"./*\"]\n" +
|
|
332
|
+
"config.excludes = FileList[\"./*.war\",'spec']\nend"
|
|
333
|
+
aFile.write("#{configFile}")
|
|
334
|
+
aFile.close
|
|
335
|
+
else
|
|
336
|
+
puts "Unable to create config/warble.rb file!"
|
|
337
|
+
end
|
|
338
|
+
end
|
|
339
|
+
# build the executable WAR using the config/warble.rb file
|
|
340
|
+
ENV['BUNDLE_WITHOUT'] = ['development','test'].join(':')
|
|
341
|
+
sh 'warble executable war'
|
|
342
|
+
else
|
|
343
|
+
puts "Cannot build WAR files outside of JRuby environment!"
|
|
344
|
+
end
|
|
345
|
+
end
|
|
346
|
+
end
|
|
347
|
+
|
|
348
|
+
task :default => ['rhoconnect:spec']
|
|
349
|
+
|
|
350
|
+
load File.join(File.dirname(__FILE__),'..','..','tasks','redis.rake')
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
module Rhoconnect
|
|
2
|
+
class SourceAdapter
|
|
3
|
+
attr_accessor :result
|
|
4
|
+
end
|
|
5
|
+
|
|
6
|
+
module TestMethods
|
|
7
|
+
# Initializes the source adapter under test for a given user, typically in a before(:each) block
|
|
8
|
+
# setup_test_for(Product,'testuser') #=> 'testuser' will be used by rest of the specs
|
|
9
|
+
def setup_test_for(adapter,user_id)
|
|
10
|
+
app_id = 'application'
|
|
11
|
+
s_fields = {
|
|
12
|
+
:user_id => user_id,
|
|
13
|
+
:app_id => app_id
|
|
14
|
+
}
|
|
15
|
+
c_fields = {
|
|
16
|
+
:device_type => 'Apple',
|
|
17
|
+
:device_pin => 'abcd',
|
|
18
|
+
:device_port => '3333',
|
|
19
|
+
:user_id => user_id,
|
|
20
|
+
:app_id => app_id
|
|
21
|
+
}
|
|
22
|
+
@u = User.create(:login => user_id)
|
|
23
|
+
@s = Source.load(adapter.to_s,s_fields)
|
|
24
|
+
@c = Client.create(c_fields,{:source_name => adapter.to_s})
|
|
25
|
+
@ss = SourceSync.new(@s)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Executes the adapter's query method and returns
|
|
29
|
+
# the master document (:md) stored in redis
|
|
30
|
+
# For example, if your source adapter query method was:
|
|
31
|
+
# def query(params=nil)
|
|
32
|
+
# @result = {
|
|
33
|
+
# "1"=>{"name"=>"Acme", "industry"=>"Electronics"},
|
|
34
|
+
# "2"=>{"name"=>"Best", "industry"=>"Software"}
|
|
35
|
+
# }
|
|
36
|
+
# end
|
|
37
|
+
#
|
|
38
|
+
# test_query would return:
|
|
39
|
+
# {
|
|
40
|
+
# "1"=>{"name"=>"Acme", "industry"=>"Electronics"},
|
|
41
|
+
# "2"=>{"name"=>"Best", "industry"=>"Software"}
|
|
42
|
+
# }
|
|
43
|
+
def test_query
|
|
44
|
+
res = @ss.process_query
|
|
45
|
+
return @s.is_pass_through? ? res : md
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Executes the adapter's query method and returns
|
|
49
|
+
# the metadata stored in redis
|
|
50
|
+
# For example, if your source adapter metadata method was:
|
|
51
|
+
# def metadata
|
|
52
|
+
# row1 = {
|
|
53
|
+
# :label => 'Address 1',
|
|
54
|
+
# :value => '123 fake street',
|
|
55
|
+
# :name => 'address1',
|
|
56
|
+
# :type => 'labeledrow'
|
|
57
|
+
# }
|
|
58
|
+
# table = {
|
|
59
|
+
# :label => 'Table',
|
|
60
|
+
# :type => 'table',
|
|
61
|
+
# :children => [ row1, row1, row1 ]
|
|
62
|
+
# }
|
|
63
|
+
# view = {
|
|
64
|
+
# :title => 'UI meta panel',
|
|
65
|
+
# :type => 'iuipanel',
|
|
66
|
+
# :children => [table]
|
|
67
|
+
# }
|
|
68
|
+
# return the definition as JSON
|
|
69
|
+
# {'index' => view}.to_json
|
|
70
|
+
#
|
|
71
|
+
# test_metadata would return:
|
|
72
|
+
# {
|
|
73
|
+
# {'index' => view}.to_json
|
|
74
|
+
# }
|
|
75
|
+
def test_metadata
|
|
76
|
+
@ss.process_query
|
|
77
|
+
return @s.get_value(:metadata)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
# Executes the adapter's schema method and returns
|
|
81
|
+
# the schema stored in redis
|
|
82
|
+
# For example, if your source adapter schema method was:
|
|
83
|
+
# def schema
|
|
84
|
+
# {
|
|
85
|
+
# 'version' => '1.0',
|
|
86
|
+
# 'property' => {
|
|
87
|
+
# 'name' => 'string',
|
|
88
|
+
# 'brand' => 'string',
|
|
89
|
+
# 'price' => 'string',
|
|
90
|
+
# 'image_url_cropped' => 'blob,overwrite',
|
|
91
|
+
# 'image_url' => 'blob'
|
|
92
|
+
# },
|
|
93
|
+
# 'index' => {
|
|
94
|
+
# 'by_name_brand' => 'name,brand'
|
|
95
|
+
# },
|
|
96
|
+
# 'unique_index' => {
|
|
97
|
+
# 'by_price' => 'price'
|
|
98
|
+
# }
|
|
99
|
+
# }.to_json
|
|
100
|
+
# test_schema would return the above
|
|
101
|
+
def test_schema
|
|
102
|
+
@ss.process_query
|
|
103
|
+
return @s.get_value(:schema)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Returns any errors stored in redis for the previous source adapter query
|
|
107
|
+
# For example: {"query-error"=>{"message"=>"error connecting to web service!"}}
|
|
108
|
+
def query_errors
|
|
109
|
+
@s.get_data(:errors)
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
# Execute's the adapter's create method with a provided record and
|
|
113
|
+
# returns the object string from the create method. If the create method
|
|
114
|
+
# returns a string, then a link will be saved for the device next time
|
|
115
|
+
# it synchronizes. This link can be tested here.
|
|
116
|
+
#
|
|
117
|
+
# For example, in your spec:
|
|
118
|
+
# @product = {
|
|
119
|
+
# 'name' => 'iPhone',
|
|
120
|
+
# 'brand' => 'Apple',
|
|
121
|
+
# 'price' => '$299.99',
|
|
122
|
+
# 'quantity' => '5',
|
|
123
|
+
# 'sku' => '1234'
|
|
124
|
+
# }
|
|
125
|
+
# new_product_id = test_create(@product)
|
|
126
|
+
# create_errors.should == {}
|
|
127
|
+
# md[new_product_id].should == @product
|
|
128
|
+
#
|
|
129
|
+
# This will return the result of the adapter's create method. The master
|
|
130
|
+
# document (:md) should also contain the new record.
|
|
131
|
+
def test_create(record)
|
|
132
|
+
if @s.is_pass_through?
|
|
133
|
+
@ss.pass_through_cud({'create'=> {'temp-id' => record}},nil)
|
|
134
|
+
else
|
|
135
|
+
@c.put_data(:create,{'temp-id' => record})
|
|
136
|
+
@ss.process_cud(@c.id)
|
|
137
|
+
links = @c.get_data(:create_links)['temp-id']
|
|
138
|
+
links ? links['l'] : nil
|
|
139
|
+
end
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
# Returns any errors stored in redis from the previous source adapter create
|
|
143
|
+
# (same structure as query errors)
|
|
144
|
+
def create_errors
|
|
145
|
+
@c.get_data(:create_errors)
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
# Execute the source adapter's update method.
|
|
149
|
+
# Takes a record as hash of hashes (object_id => object)
|
|
150
|
+
#
|
|
151
|
+
# For example:
|
|
152
|
+
# test_update({'4' => {'price' => '$199.99'}})
|
|
153
|
+
# update_errors.should == {}
|
|
154
|
+
# test_query
|
|
155
|
+
# md[product_id]['price'].should == '$199.99'
|
|
156
|
+
#
|
|
157
|
+
# This will call the adapter's update method for object_id '4'
|
|
158
|
+
# NOTE: To test the master document, you will need to run def test_query
|
|
159
|
+
# as shown above
|
|
160
|
+
def test_update(record)
|
|
161
|
+
if @s.is_pass_through?
|
|
162
|
+
@ss.pass_through_cud({'update'=> record },nil)
|
|
163
|
+
else
|
|
164
|
+
@c.put_data(:update,record)
|
|
165
|
+
@ss.process_cud(@c.id)
|
|
166
|
+
end
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Returns any errors stored in redis from the previous source adapter update
|
|
170
|
+
# (same structure as query errors)
|
|
171
|
+
def update_errors
|
|
172
|
+
@c.get_data(:update_errors)
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Execute the source adapter's delete method.
|
|
176
|
+
# Takes a record as hash of hashes (object_id => object)
|
|
177
|
+
#
|
|
178
|
+
# For example:
|
|
179
|
+
# @product = {
|
|
180
|
+
# 'name' => 'iPhone',
|
|
181
|
+
# 'brand' => 'Apple',
|
|
182
|
+
# 'price' => '$299.99',
|
|
183
|
+
# 'quantity' => '5',
|
|
184
|
+
# 'sku' => '1234'
|
|
185
|
+
# }
|
|
186
|
+
# test_delete('4' => @product)
|
|
187
|
+
# delete_errors.should == {}
|
|
188
|
+
# md.should == {}
|
|
189
|
+
#
|
|
190
|
+
# This will call the adapter's delete method for product '4'
|
|
191
|
+
# NOTE: The master document (:md) will be updated and can be
|
|
192
|
+
# verified as shown above.
|
|
193
|
+
def test_delete(record)
|
|
194
|
+
if @s.is_pass_through?
|
|
195
|
+
@ss.pass_through_cud({'delete'=> record },nil)
|
|
196
|
+
else
|
|
197
|
+
@c.put_data(:delete,record)
|
|
198
|
+
@ss.process_cud(@c.id)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
|
|
202
|
+
# Returns any errors stored in redis from the previous source adapter delete
|
|
203
|
+
# (same structure as query errors)
|
|
204
|
+
def delete_errors
|
|
205
|
+
@c.get_data(:delete_errors)
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
# Returns the master document (:md) for the source adapter stored in redis.
|
|
209
|
+
# This is equivalent to the @result hash of hashes structure.
|
|
210
|
+
def md
|
|
211
|
+
@s.get_data(:md)
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
# Returns the client document (:cd) for the source adapter + client under test.
|
|
215
|
+
# The master document (:md) and client document (:cd) should be equal
|
|
216
|
+
def cd
|
|
217
|
+
@c.get_data(:cd)
|
|
218
|
+
end
|
|
219
|
+
end
|
|
220
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require 'digest/sha1'
|
|
2
|
+
|
|
3
|
+
module Rhoconnect
|
|
4
|
+
# Inspired by sinatra-authentication
|
|
5
|
+
# Password uses simple sha1 digest for hashing
|
|
6
|
+
class User < Model
|
|
7
|
+
field :login,:string
|
|
8
|
+
field :email,:string
|
|
9
|
+
field :salt,:string
|
|
10
|
+
field :hashed_password,:string
|
|
11
|
+
set :clients, :string
|
|
12
|
+
field :admin, :int
|
|
13
|
+
field :token_id, :string
|
|
14
|
+
|
|
15
|
+
class << self
|
|
16
|
+
def create(fields={})
|
|
17
|
+
raise ArgumentError.new("Reserved user id #{fields[:login]}") if fields[:login] && fields[:login] == '__shared__'
|
|
18
|
+
fields[:id] = fields[:login]
|
|
19
|
+
user = super(fields)
|
|
20
|
+
if Rhoconnect.stats
|
|
21
|
+
Rhoconnect::Stats::Record.set('users') { Store.incr('user:count') }
|
|
22
|
+
else
|
|
23
|
+
Store.incr('user:count')
|
|
24
|
+
end
|
|
25
|
+
user
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def authenticate(login,password)
|
|
29
|
+
return unless is_exist?(login)
|
|
30
|
+
current_user = load(login)
|
|
31
|
+
return if current_user.nil?
|
|
32
|
+
return current_user if User.encrypt(password, current_user.salt) == current_user.hashed_password
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def new_password=(pass)
|
|
37
|
+
self.password=(pass)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def password=(pass)
|
|
41
|
+
@password = pass
|
|
42
|
+
self.salt = User.random_string(10) if !self.salt
|
|
43
|
+
self.hashed_password = User.encrypt(@password, self.salt)
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def delete
|
|
47
|
+
clients.members.each do |client_id|
|
|
48
|
+
Client.load(client_id,{:source_name => '*'}).delete
|
|
49
|
+
end
|
|
50
|
+
self.token.delete if self.token
|
|
51
|
+
if Rhoconnect.stats
|
|
52
|
+
Rhoconnect::Stats::Record.set('users') { Store.decr('user:count') }
|
|
53
|
+
else
|
|
54
|
+
Store.decr('user:count')
|
|
55
|
+
end
|
|
56
|
+
super
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def create_token
|
|
60
|
+
if self.token_id && ApiToken.is_exist?(self.token_id)
|
|
61
|
+
self.token.delete
|
|
62
|
+
end
|
|
63
|
+
self.token_id = ApiToken.create(:user_id => self.login).id
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def token
|
|
67
|
+
ApiToken.load(self.token_id)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def token=(value)
|
|
71
|
+
if self.token_id && ApiToken.is_exist?(self.token_id)
|
|
72
|
+
self.token.delete
|
|
73
|
+
end
|
|
74
|
+
self.token_id = ApiToken.create(:user_id => self.login, :value => value).id
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
def update(fields)
|
|
78
|
+
fields.each do |key,value|
|
|
79
|
+
self.send("#{key.to_sym}=", value) unless key == 'login'
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
protected
|
|
84
|
+
def self.encrypt(pass, salt)
|
|
85
|
+
Digest::SHA1.hexdigest(pass+salt)
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def self.random_string(len)
|
|
89
|
+
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
|
|
90
|
+
newpass = ""
|
|
91
|
+
1.upto(len) { |i| newpass << chars[rand(chars.size-1)] }
|
|
92
|
+
return newpass
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|