rhoconnect 3.0.0.beta1 → 3.0.0.beta3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. data/CHANGELOG +16 -2
  2. data/Gemfile +14 -5
  3. data/Gemfile.lock +13 -23
  4. data/Rakefile +86 -0
  5. data/bench/bench_runner.rb +5 -4
  6. data/bench/benchapp/Gemfile +17 -8
  7. data/bench/blobapp/Gemfile +13 -14
  8. data/doc/adapters-crm.txt +226 -0
  9. data/doc/adapters-intro.txt +18 -0
  10. data/doc/client.txt +29 -2
  11. data/doc/heroku-addon.txt +54 -0
  12. data/doc/install.txt +1 -2
  13. data/doc/migration.txt +18 -6
  14. data/doc/net-plugin.txt +276 -0
  15. data/doc/plugin-intro.txt +6 -0
  16. data/doc/push.txt +1 -1
  17. data/doc/rails-plugin.txt +116 -0
  18. data/doc/rest-api.txt +2 -2
  19. data/doc/settings.txt +59 -0
  20. data/doc/tutorial.txt +8 -5
  21. data/generators/rhoconnect.rb +30 -0
  22. data/generators/templates/application/Gemfile +16 -7
  23. data/generators/templates/application/gitignore +4 -0
  24. data/install.sh +74 -106
  25. data/installer/deb-scripts/LICENSE +75 -0
  26. data/installer/deb-scripts/install.sh +300 -0
  27. data/installer/deb-scripts/scripts/rho_connect_install_constants.rb +32 -0
  28. data/installer/deb-scripts/scripts/rho_connect_install_installers.rb +103 -0
  29. data/installer/deb-scripts/scripts/rho_connect_install_utilities.rb +110 -0
  30. data/installer/deb-scripts/scripts/rhoinstaller.rb +55 -0
  31. data/installer/deb-scripts/utils/README +67 -0
  32. data/installer/deb-scripts/utils/create_texts.rb +76 -0
  33. data/installer/deb-scripts/utils/redis_init_script +124 -0
  34. data/installer/deb-scripts/utils/redis_log_rotate +8 -0
  35. data/installer/unix-like/install.sh +361 -0
  36. data/installer/unix-like/post-install.sh +8 -0
  37. data/installer/unix-like/pre-install.sh +8 -0
  38. data/installer/unix-like/rho_connect_install_constants.rb +9 -14
  39. data/installer/unix-like/rho_connect_install_debian.rb +7 -5
  40. data/installer/unix-like/rho_connect_install_dnd.rb +6 -6
  41. data/installer/unix-like/rho_connect_install_get_params.rb +1 -1
  42. data/installer/unix-like/rho_connect_install_installers.rb +39 -38
  43. data/installer/unix-like/rho_connect_install_utilities.rb +9 -10
  44. data/installer/unix-like/rho_connect_install_yum.rb +6 -5
  45. data/installer/unix-like/rhoinstaller.rb +8 -3
  46. data/installer/utils/create_texts.rb +313 -85
  47. data/installer/windows/rhosync.nsi +5 -5
  48. data/lib/rhoconnect/api/application/clientcreate.rb +1 -1
  49. data/lib/rhoconnect/api/application/clientregister.rb +1 -1
  50. data/lib/rhoconnect/api/application/clientreset.rb +1 -1
  51. data/lib/rhoconnect/client.rb +0 -1
  52. data/lib/rhoconnect/client_sync.rb +1 -0
  53. data/lib/rhoconnect/console/app/routes/home.rb +1 -1
  54. data/lib/rhoconnect/console/app/routes/user.rb +8 -3
  55. data/lib/rhoconnect/console/app/views/adapter.erb +2 -2
  56. data/lib/rhoconnect/console/app/views/ping.erb +14 -2
  57. data/lib/rhoconnect/console/app/views/users.erb +8 -1
  58. data/lib/rhoconnect/jobs/ping_job.rb +11 -3
  59. data/lib/rhoconnect/model.rb +2 -2
  60. data/lib/rhoconnect/read_state.rb +2 -0
  61. data/lib/rhoconnect/server.rb +4 -3
  62. data/lib/rhoconnect/source.rb +33 -6
  63. data/lib/rhoconnect/source_adapter.rb +5 -9
  64. data/lib/rhoconnect/source_sync.rb +11 -5
  65. data/lib/rhoconnect/store.rb +7 -4
  66. data/lib/rhoconnect/tasks.rb +3 -3
  67. data/lib/rhoconnect/version.rb +1 -1
  68. data/lib/rhoconnect.rb +22 -8
  69. data/rhoconnect.gemspec +4 -22
  70. data/spec/api/application/rhoconnect_api_spec.rb +54 -8
  71. data/spec/api/source/get_source_params_spec.rb +2 -1
  72. data/spec/api/source/list_sources_spec.rb +3 -3
  73. data/spec/app_spec.rb +8 -1
  74. data/spec/apps/rhotestapp/settings/settings.yml +10 -5
  75. data/spec/apps/rhotestapp/sources/other_adapter.rb +7 -0
  76. data/spec/client_sync_spec.rb +5 -8
  77. data/spec/dynamic_adapter_spec.rb +8 -8
  78. data/spec/generator/generator_spec.rb +4 -2
  79. data/spec/jobs/ping_job_spec.rb +53 -0
  80. data/spec/model_spec.rb +2 -2
  81. data/spec/rhosync_spec.rb +1 -1
  82. data/spec/server/server_spec.rb +3 -14
  83. data/spec/source_sync_spec.rb +84 -2
  84. data/spec/support/shared_examples.rb +2 -2
  85. data/tasks/redis.rake +2 -2
  86. metadata +30 -41
  87. data/spec/api/rhosync_api_spec.rb.orig +0 -606
@@ -1,4 +1,11 @@
1
- <a href="javascript:void(0);" onclick="loadXMLDoc('<%=url_path('user/new')%>','main_box');" class='nav_button'>Create User</a>
1
+ <div class="panel">
2
+ <a href="javascript:void(0);" onclick="loadXMLDoc('<%=url_path('user/new')%>','main_box');" class='nav_button'>Create User</a>
3
+ </div>
4
+ <%if @users.size > 0%>
5
+ <div class="panel">
6
+ <a href="javascript:void(0);" onclick="loadXMLDoc('<%=url_path("user/ping?user_id=#{CGI.escape(@users.first(10).join(','))}")%>','main_box');" class='nav_button'>Ping Users</a>
7
+ </div>
8
+ <%end%>
2
9
 
3
10
  <h2>Registered users</h2>
4
11
  <%if is_errors?%>
@@ -6,9 +6,17 @@ module Rhoconnect
6
6
 
7
7
  # Perform a ping for all clients registered to a user
8
8
  def self.perform(params)
9
- user = User.load(params["user_id"])
10
9
  device_pins = []
11
- phone_ids = []
10
+ phone_ids = []
11
+ user_ids = params['user_id']
12
+ user_ids = [user_ids] unless user_ids.is_a? Array
13
+ user_ids.each do |user|
14
+ ping_by_user user, params, device_pins, phone_ids
15
+ end
16
+ end
17
+
18
+ def self.ping_by_user(user_id, params, device_pins, phone_ids)
19
+ user = User.load(user_id)
12
20
  user.clients.members.each do |client_id|
13
21
  client = Client.load(client_id,{:source_name => '*'})
14
22
  params.merge!('device_port' => client.device_port, 'device_pin' => client.device_pin, 'phone_id' => client.phone_id)
@@ -29,7 +37,7 @@ module Rhoconnect
29
37
  next
30
38
  end
31
39
  if send_push
32
- klass = Object.const_get(camelize(client.device_type.downcase))
40
+ klass = Object.const_get(camelize(client.device_type.downcase))
33
41
  if klass
34
42
  params['vibrate'] = params['vibrate'].to_s
35
43
  klass.ping(params)
@@ -33,14 +33,14 @@ module Rhoconnect
33
33
  # specified amount.
34
34
  def increment!(name,amount=1)
35
35
  raise ArgumentError, "Only integer fields can be incremented." unless self.class.fields.include?({:name => name.to_s, :type => :integer})
36
- redis.incr(field_key(name), amount)
36
+ redis.incrby(field_key(name), amount)
37
37
  end
38
38
 
39
39
  # Decrement the specified integer field by 1 or the
40
40
  # specified amount.
41
41
  def decrement!(name,amount=1)
42
42
  raise ArgumentError, "Only integer fields can be decremented." unless self.class.fields.include?({:name => name.to_s, :type => :integer})
43
- redis.decr(field_key(name), amount)
43
+ redis.decrby(field_key(name), amount)
44
44
  end
45
45
 
46
46
  def next_id #:nodoc:
@@ -1,6 +1,7 @@
1
1
  module Rhoconnect
2
2
  class ReadState < Model
3
3
  field :refresh_time, :integer
4
+ field :retry_counter, :integer
4
5
 
5
6
  def self.create(fields)
6
7
  fields[:id] = get_id(fields)
@@ -8,6 +9,7 @@ module Rhoconnect
8
9
  fields.delete(:user_id)
9
10
  fields.delete(:source_name)
10
11
  fields[:refresh_time] ||= Time.now.to_i
12
+ fields[:retry_counter] ||= 0
11
13
  super(fields,{})
12
14
  end
13
15
 
@@ -111,7 +111,8 @@ module Rhoconnect
111
111
 
112
112
  # if source does not exist create one for dynamic adapter
113
113
  unless @source
114
- @source = Source.create({:name => params[:source_name]},{:user_id => user.login, :app_id => APP_NAME})
114
+ sconfig = Rhoconnect.source_config(params[:source_name])
115
+ @source = Source.create(sconfig.merge!({:name => params[:source_name]}),{:user_id => user.login, :app_id => APP_NAME})
115
116
  current_app.sources << @source.name
116
117
  end
117
118
  @source
@@ -182,11 +183,11 @@ module Rhoconnect
182
183
  use Rhoconnect::Stats::Middleware
183
184
  Rhoconnect.stats = true
184
185
  end
185
- use Rack::Session::Cookie,
186
+ use XDomainSessionWrapper
187
+ use Rack::Session::Cookie,
186
188
  :key => 'rhoconnect_session',
187
189
  :expire_after => Rhoconnect.cookie_expire,
188
190
  :secret => @@secret
189
- use XDomainSessionWrapper
190
191
  use Rack::Cors do |cfg|
191
192
  cfg.allow do |allow|
192
193
  allow.origins /.*/
@@ -90,7 +90,7 @@ module Rhoconnect
90
90
 
91
91
  # source fields
92
92
  define_fields([:id, :rho__id, :name, :url, :login, :password, :callback_url, :partition_type, :sync_type,
93
- :queue, :query_queue, :cud_queue, :belongs_to, :has_many, :pass_through], [:source_id, :priority])
93
+ :queue, :query_queue, :cud_queue, :belongs_to, :has_many, :pass_through], [:source_id, :priority, :retry_limit])
94
94
 
95
95
  def initialize(fields)
96
96
  self.name = fields['name'] || fields[:name]
@@ -112,6 +112,7 @@ module Rhoconnect
112
112
  fields[:rho__id] = fields[:name]
113
113
  fields[:belongs_to] = fields[:belongs_to].to_json if fields[:belongs_to]
114
114
  fields[:schema] = fields[:schema].to_json if fields[:schema]
115
+ fields[:retry_limit] = fields[:retry_limit] ? fields[:retry_limit] : 0
115
116
  end
116
117
 
117
118
  def self.create(fields,params)
@@ -263,14 +264,40 @@ module Rhoconnect
263
264
  end
264
265
 
265
266
  def if_need_refresh(client_id=nil,params=nil)
266
- need_refresh = lock(:md) do |s|
267
- check = check_refresh_time
268
- s.read_state.refresh_time = Time.now.to_i + s.poll_interval if check
269
- check
270
- end
267
+ need_refresh = check_refresh_time
271
268
  yield client_id,params if need_refresh
272
269
  end
273
270
 
271
+ def update_refresh_time(query_failure = false)
272
+ if self.poll_interval == 0
273
+ self.read_state.refresh_time = Time.now.to_i + self.poll_interval
274
+ return
275
+ end
276
+
277
+ allowed_update = true
278
+ # reset number of retries on succesfull query
279
+ # or if last refresh was more than 'poll_interval' time ago
280
+ if not query_failure or (Time.now.to_i - self.read_state.refresh_time >= self.poll_interval)
281
+ self.read_state.retry_counter = 0
282
+ end
283
+
284
+ # do not reset the refresh time on failure
285
+ # if retry limit is not reached
286
+ if query_failure
287
+ if self.read_state.retry_counter < self.retry_limit
288
+ allowed_update = false
289
+ self.read_state.increment!(:retry_counter)
290
+ # we have reached the limit - update the refresh time
291
+ # and reset the counter
292
+ else
293
+ self.read_state.retry_counter = 0
294
+ end
295
+ end
296
+ if allowed_update
297
+ self.read_state.refresh_time = Time.now.to_i + self.poll_interval
298
+ end
299
+ end
300
+
274
301
  def is_pass_through?
275
302
  self.pass_through and self.pass_through == 'true'
276
303
  end
@@ -55,20 +55,16 @@ module Rhoconnect
55
55
 
56
56
  def sync
57
57
  if @result and @result.empty?
58
- @source.lock(:md) do |s|
59
- s.flash_data(:md)
60
- s.put_value(:md_size,0)
61
- end
58
+ @source.flash_data(:md)
59
+ @source.put_value(:md_size,0)
62
60
  else
63
61
  if @result
64
62
  Store.put_data(@tmp_docname,@result)
65
63
  @stash_size += @result.size
66
64
  end
67
- @source.lock(:md) do |s|
68
- s.flash_data(:md)
69
- Store.rename(@tmp_docname,s.docname(:md))
70
- s.put_value(:md_size,@stash_size)
71
- end
65
+ @source.flash_data(:md)
66
+ Store.rename(@tmp_docname,@source.docname(:md))
67
+ @source.put_value(:md_size,@stash_size)
72
68
  end
73
69
  end
74
70
 
@@ -90,11 +90,17 @@ module Rhoconnect
90
90
 
91
91
  def do_query(params=nil)
92
92
  result = nil
93
- @source.if_need_refresh do
94
- Stats::Record.update("source:query:#{@source.name}") do
95
- return if _auth_op('login') == false
96
- result = self.read(nil,params)
97
- _auth_op('logoff')
93
+ @source.lock(:md) do
94
+ @source.if_need_refresh do
95
+ Stats::Record.update("source:query:#{@source.name}") do
96
+ if _auth_op('login')
97
+ result = self.read(nil,params)
98
+ _auth_op('logoff')
99
+ end
100
+ # update refresh time
101
+ query_failure = Store.get_keys(@source.docname(:errors)).size > 0
102
+ @source.update_refresh_time(query_failure)
103
+ end
98
104
  end
99
105
  end
100
106
  result
@@ -51,8 +51,11 @@ module Rhoconnect
51
51
  # Adds a simple key/value pair
52
52
  def put_value(dockey,value)
53
53
  if dockey
54
- @@db.del(dockey)
55
- @@db.set(dockey,value.to_s) if value
54
+ if value
55
+ @@db.set(dockey,value.to_s)
56
+ else
57
+ @@db.del(dockey)
58
+ end
56
59
  end
57
60
  end
58
61
 
@@ -188,8 +191,8 @@ module Rhoconnect
188
191
  # Time.now.to_i+timeout+1
189
192
  # end
190
193
 
191
- def release_lock(dockey,lock)
192
- @@db.del(_lock_key(dockey)) if (lock >= Time.now.to_i)
194
+ def release_lock(dockey,lock,raise_on_expire=false)
195
+ @@db.del(_lock_key(dockey)) if raise_on_expire or Rhoconnect.raise_on_expired_lock or (lock >= Time.now.to_i)
193
196
  end
194
197
 
195
198
  # Create a copy of srckey in dstkey
@@ -253,10 +253,10 @@ namespace :rhoconnect do
253
253
  task :start => :dtach_installed do
254
254
  cmd = (jruby?) ? trinidad? : (thin? || mongrel? || report_missing_server)
255
255
  if windows?
256
- puts 'Starting server in new window...'
257
- system("start cmd.exe /c #{cmd} config.ru")
256
+ puts 'Starting rhoconnect...'
257
+ system("#{cmd} config.ru")
258
258
  elsif jruby?
259
- puts 'Starting server in jruby environment...'
259
+ puts 'Starting rhoconnect in jruby environment...'
260
260
  system("#{cmd}")
261
261
  else
262
262
  puts 'Detach with Ctrl+\ Re-attach with rake rhoconnect:attach'
@@ -1,3 +1,3 @@
1
1
  module Rhoconnect
2
- VERSION = '3.0.0.beta1'
2
+ VERSION = '3.0.0.beta3'
3
3
  end
data/lib/rhoconnect.rb CHANGED
@@ -63,7 +63,7 @@ module Rhoconnect
63
63
  Rhoconnect.blackberry_bulk_sync = get_setting(config,environment,:blackberry_bulk_sync,false)
64
64
  Rhoconnect.bulk_sync_poll_interval = get_setting(config,environment,:bulk_sync_poll_interval,3600)
65
65
  Rhoconnect.redis = get_setting(config,environment,:redis,false)
66
- Rhoconnect.appserver = get_setting(config,environment,:appserver,false)
66
+ Rhoconnect.appserver ||= get_setting(config,environment,:appserver,false)
67
67
  Rhoconnect.api_token = ENV['API_TOKEN'] || get_setting(config,environment,:api_token,false)
68
68
  Rhoconnect.log_disabled = get_setting(config,environment,:log_disabled,false)
69
69
  Rhoconnect.raise_on_expired_lock = get_setting(config,environment,:raise_on_expired_lock,false)
@@ -99,9 +99,10 @@ module Rhoconnect
99
99
  Source.delete_all
100
100
  app.delete_sources
101
101
  sources.each do |source_name,fields|
102
- check_for_schema_field!(fields)
103
- fields[:name] = source_name
104
- Source.create(fields,{:app_id => app.name})
102
+ source_config = source_config(source_name)
103
+ check_for_schema_field!(source_config)
104
+ source_config[:name] = source_name
105
+ Source.create(source_config,{:app_id => app.name})
105
106
  app.sources << source_name
106
107
  # load ruby file for source adapter to re-load class
107
108
  load under_score(source_name+'.rb')
@@ -130,13 +131,26 @@ module Rhoconnect
130
131
  settings_file = File.join(basedir,'settings','settings.yml') if basedir
131
132
  YAML.load_file(settings_file) if settings_file and File.exist?(settings_file)
132
133
  end
133
-
134
- def source_config
135
- { "sources" => Rhoconnect.get_config(Rhoconnect.base_directory)[:sources] }
134
+
135
+ def source_config(source_name)
136
+ source_config = {}
137
+ sources = Rhoconnect.get_config(Rhoconnect.base_directory)[:sources]
138
+ source_config = sources[source_name] unless (sources.nil? or sources[source_name].nil?)
139
+ env_config = Rhoconnect.get_config(Rhoconnect.base_directory)[Rhoconnect.environment]
140
+ force_default = source_config[:force_default]
141
+ # apply global env settings
142
+ [:poll_interval].each do |setting|
143
+ def_setting = env_config["#{setting.to_s}_default".to_sym]
144
+ next unless def_setting
145
+ if source_config[setting].nil? or force_default
146
+ source_config[setting] = def_setting
147
+ end
148
+ end
149
+ source_config
136
150
  end
151
+
137
152
  ### End Rhoconnect setup methods
138
153
 
139
-
140
154
  def check_default_secret!(secret)
141
155
  if secret == '<changeme>'
142
156
  log "*"*60+"\n\n"
data/rhoconnect.gemspec CHANGED
@@ -10,14 +10,11 @@ Gem::Specification.new do |s|
10
10
  s.date = Time.now.strftime('%Y-%m-%d')
11
11
  s.email = %q{dev@rhomobile.com}
12
12
  s.homepage = %q{http://rhomobile.com/products/rhoconnect}
13
- s.summary = %q{RhoConnect Server Framework}
14
- s.description = %q{RhoConnect Server Framework and related command-line utilities}
13
+ s.summary = %q{RhoConnect App Integration Server}
14
+ s.description = %q{RhoConnect App Integration Server and related command-line utilities}
15
15
 
16
16
  s.rubyforge_project = nil
17
-
18
- # s.files = `git ls-files`.split("\n")
19
- # s.test_files = `git ls-files -- {examples,spec,features}/*`.split("\n")
20
- # s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+
21
18
  s.files = %w(
22
19
  CHANGELOG CREDITS Gemfile Gemfile.lock install.sh README.md Rakefile LICENSE Rakefile rhoconnect.gemspec
23
20
  )
@@ -48,20 +45,5 @@ Gem::Specification.new do |s|
48
45
  s.add_dependency('redis', '>= 2.2.0')
49
46
  s.add_dependency('resque', '~> 1.17.0')
50
47
  s.add_dependency('rest-client', '~> 1.6.1')
51
- s.add_dependency('templater', '~> 1.0.0')
52
-
53
- # Platform specific gems
54
- if defined?(JRUBY_VERSION)
55
- s.add_dependency('jdbc-sqlite3', ">= 3.7.2")
56
- s.add_dependency('dbi', ">= 0.4.5")
57
- s.add_dependency('dbd-jdbc', ">= 0.1.4")
58
- s.add_dependency('jruby-openssl', ">= 0.7.4")
59
- else
60
- s.add_dependency('sqlite3', ">= 1.3.3")
61
- # Helps with some of the limitations of green threads, not needed in ruby 1.9.x
62
- if RUBY_VERSION =~ /1.8/
63
- s.add_dependency('SystemTimer', '~> 1.2.3')
64
- end
65
- end
66
-
48
+ s.add_dependency('templater', '~> 1.0.0')
67
49
  end
@@ -14,15 +14,15 @@ describe "RhoconnectApi" do
14
14
 
15
15
  it "should get adapter using direct api call" do
16
16
  RhoconnectApi::get_adapter('',@api_token)
17
- Rhoconnect.appserver.should == "http://test.rhoconnect.com"
17
+ Rhoconnect.appserver.should == "http://test.com"
18
18
  end
19
19
 
20
20
  it "should get adapter using rest call" do
21
21
  res = mock('HttpResponse')
22
- res.stub!(:body).and_return(["http://test.rhoconnect.com"].to_json)
22
+ res.stub!(:body).and_return(["http://test.com"].to_json)
23
23
  RestClient.stub(:post).and_return(res)
24
24
  RestClient.should_receive(:post).once
25
- RhoconnectApi::get_adapter('some_url',@api_token).should == ["http://test.rhoconnect.com"]
25
+ RhoconnectApi::get_adapter('some_url',@api_token).should == ["http://test.com"]
26
26
  end
27
27
 
28
28
  it "should save adapter using direct api call" do
@@ -149,12 +149,12 @@ describe "RhoconnectApi" do
149
149
 
150
150
  it "should list all application sources using direct api call" do
151
151
  RhoconnectApi::list_sources('',@api_token).sort.should ==
152
- ["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter"].sort
152
+ ["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter", "OtherAdapter"].sort
153
153
  end
154
154
 
155
155
  it "should list all application sources using rest call" do
156
156
  res = mock('HttpResponse')
157
- res.stub!(:body).and_return(["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter"].to_json)
157
+ res.stub!(:body).and_return(["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter", "OtherAdapter"].to_json)
158
158
  RestClient.stub(:post).and_return(res)
159
159
  RestClient.should_receive(:post).once
160
160
  RhoconnectApi::list_sources('some_url',@api_token)
@@ -172,7 +172,8 @@ describe "RhoconnectApi" do
172
172
  {"name"=>"password", "value"=>"testpass", "type"=>"string"},
173
173
  {"name"=>"priority", "value"=>3, "type"=>"integer"},
174
174
  {"name"=>"callback_url", "value"=>nil, "type"=>"string"},
175
- {"name"=>"poll_interval", "value"=>300, "type"=>"integer"},
175
+ {"name"=>"poll_interval", "value"=>300, "type"=>"integer"},
176
+ {"name"=>"retry_limit", "value"=>0, "type"=>"integer"},
176
177
  {"name"=>"partition_type", "value"=>"user", "type"=>"string"},
177
178
  {"name"=>"sync_type", "value"=>"incremental", "type"=>"string"},
178
179
  {"name"=>"belongs_to", "type"=>"string", "value"=>nil},
@@ -352,12 +353,12 @@ describe "RhoconnectApi" do
352
353
 
353
354
  it "should list all application sources using direct api call" do
354
355
  RhoconnectApi::list_sources('',@api_token).sort.should ==
355
- ["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter"].sort
356
+ ["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter", "OtherAdapter"].sort
356
357
  end
357
358
 
358
359
  it "should list all application sources using rest call" do
359
360
  res = mock('HttpResponse')
360
- res.stub!(:body).and_return(["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter"].to_json)
361
+ res.stub!(:body).and_return(["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter", "OtherAdapter"].to_json)
361
362
  RestClient.stub(:post).and_return(res)
362
363
  RestClient.should_receive(:post).once
363
364
  RhoconnectApi::list_sources('some_url',@api_token)
@@ -376,6 +377,7 @@ describe "RhoconnectApi" do
376
377
  {"name"=>"priority", "value"=>3, "type"=>"integer"},
377
378
  {"name"=>"callback_url", "value"=>nil, "type"=>"string"},
378
379
  {"name"=>"poll_interval", "value"=>300, "type"=>"integer"},
380
+ {"name"=>"retry_limit", "type"=>"integer", "value"=>0},
379
381
  {"name"=>"partition_type", "value"=>"user", "type"=>"string"},
380
382
  {"name"=>"sync_type", "value"=>"incremental", "type"=>"string"},
381
383
  {"name"=>"belongs_to", "type"=>"string", "value"=>nil},
@@ -386,6 +388,31 @@ describe "RhoconnectApi" do
386
388
  {"name"=>"cud_queue", "value"=>nil, "type"=>"string"},
387
389
  {"name"=>"pass_through", "value"=>nil, "type"=>"string"}].sort {|x,y| x["name"] <=> y["name"] }
388
390
  end
391
+
392
+ it "should list source attributes with default env poll_interval using direct api call" do
393
+ result = RhoconnectApi::get_source_params(
394
+ '',@api_token,"OtherAdapter").sort{|x,y| x['name']<=>y['name']}
395
+ result.should == [
396
+ {"name"=>"rho__id", "value"=>"OtherAdapter", "type"=>"string"},
397
+ {"name"=>"source_id", "value"=>nil, "type"=>"integer"},
398
+ {"name"=>"name", "value"=>"OtherAdapter", "type"=>"string"},
399
+ {"name"=>"url", "value"=>"", "type"=>"string"},
400
+ {"name"=>"login", "value"=>"", "type"=>"string"},
401
+ {"name"=>"password", "value"=>"", "type"=>"string"},
402
+ {"name"=>"priority", "value"=>3, "type"=>"integer"},
403
+ {"name"=>"callback_url", "value"=>nil, "type"=>"string"},
404
+ {"name"=>"poll_interval", "value"=>201, "type"=>"integer"},
405
+ {"name"=>"retry_limit", "value"=>0, "type"=>"integer"},
406
+ {"name"=>"partition_type", "value"=>"app", "type"=>"string"},
407
+ {"name"=>"sync_type", "value"=>"incremental", "type"=>"string"},
408
+ {"name"=>"belongs_to", "type"=>"string", "value"=>nil},
409
+ {"name"=>"has_many", "type"=>"string", "value"=>nil},
410
+ {"name"=>"id", "value"=>"OtherAdapter", "type"=>"string"},
411
+ {"name"=>"queue", "value"=>nil, "type"=>"string"},
412
+ {"name"=>"query_queue", "value"=>nil, "type"=>"string"},
413
+ {"name"=>"cud_queue", "value"=>nil, "type"=>"string"},
414
+ {"name"=>"pass_through", "value"=>nil, "type"=>"string"}].sort {|x,y| x["name"] <=> y["name"] }
415
+ end
389
416
 
390
417
  it "should list source attributes using rest call" do
391
418
  res = mock('HttpResponse')
@@ -512,6 +539,25 @@ describe "RhoconnectApi" do
512
539
  RestClient.should_receive(:post).once
513
540
  RhoconnectApi::ping('some_url',@api_token,@u.id,{})
514
541
  end
542
+
543
+ it "should do ping multiple users using rest call" do
544
+ @u1_fields = {:login => 'testuser1'}
545
+ @u1 = User.create(@u1_fields)
546
+ @u1.password = 'testpass'
547
+ @c1_fields = {
548
+ :device_type => 'Apple',
549
+ :device_pin => 'abcde',
550
+ :device_port => '3334',
551
+ :user_id => @u1.id,
552
+ :app_id => @a.id
553
+ }
554
+ @c1 = Client.create(@c1_fields,{:source_name => @s_fields[:name]})
555
+ @a.users << @u1.id
556
+
557
+ RestClient.stub(:post)
558
+ RestClient.should_receive(:post).once
559
+ RhoconnectApi::ping('some_url',@api_token,[@u.id, @u1.id],{})
560
+ end
515
561
 
516
562
  it "should get license info using direct api call" do
517
563
  RhoconnectApi::get_license_info('',@api_token).should == {
@@ -16,7 +16,8 @@ describe "RhoconnectApiGetSourceParams" do
16
16
  {"name"=>"password", "value"=>"testpass", "type"=>"string"},
17
17
  {"name"=>"priority", "value"=>3, "type"=>"integer"},
18
18
  {"name"=>"callback_url", "value"=>nil, "type"=>"string"},
19
- {"name"=>"poll_interval", "value"=>300, "type"=>"integer"},
19
+ {"name"=>"poll_interval", "value"=>300, "type"=>"integer"},
20
+ {"name"=>"retry_limit", "type"=>"integer", "value"=>0},
20
21
  {"name"=>"partition_type", "value"=>"user", "type"=>"string"},
21
22
  {"name"=>"sync_type", "value"=>"incremental", "type"=>"string"},
22
23
  {"name"=>"belongs_to", "type"=>"string", "value"=>nil},
@@ -4,18 +4,18 @@ describe "RhoconnectApiListSources" do
4
4
  it_should_behave_like "ApiHelper" do
5
5
  it "should list all application sources" do
6
6
  post "/api/source/list_sources", {:api_token => @api_token}
7
- JSON.parse(last_response.body).sort.should == ["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter"].sort
7
+ JSON.parse(last_response.body).sort.should == ["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter", "OtherAdapter"].sort
8
8
  end
9
9
 
10
10
  it "should list all application sources using partition_type param" do
11
11
  post "/api/source/list_sources",
12
12
  {:api_token => @api_token, :partition_type => 'all'}
13
- JSON.parse(last_response.body).sort.should == ["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter"].sort
13
+ JSON.parse(last_response.body).sort.should == ["SimpleAdapter", "SampleAdapter", "FixedSchemaAdapter", "OtherAdapter"].sort
14
14
  end
15
15
 
16
16
  it "should list app partition sources" do
17
17
  post "/api/source/list_sources", {:api_token => @api_token, :partition_type => :app}
18
- JSON.parse(last_response.body).should == ["SimpleAdapter"]
18
+ JSON.parse(last_response.body).sort.should == ["SimpleAdapter", "OtherAdapter"].sort
19
19
  end
20
20
 
21
21
  it "should list user partition sources" do
data/spec/app_spec.rb CHANGED
@@ -12,7 +12,14 @@ describe "App" do
12
12
 
13
13
  it "should add source adapters" do
14
14
  @a1 = App.load(@a_fields[:name])
15
- @a1.sources.sort.should == ["FixedSchemaAdapter", "SampleAdapter", "SimpleAdapter"]
15
+ @a1.sources.sort.should == ["FixedSchemaAdapter", "OtherAdapter", "SampleAdapter", "SimpleAdapter"]
16
+ end
17
+
18
+ it "should force environment default and override setting" do
19
+ poll_interval_default = Rhoconnect.source_config('OtherAdapter')[:poll_interval]
20
+ poll_interval_default.should == 201
21
+ poll_interval_override = Rhoconnect.source_config('SimpleAdapter')[:poll_interval]
22
+ poll_interval_override.should == 600
16
23
  end
17
24
  end
18
25
  end
@@ -1,21 +1,25 @@
1
1
  :sources:
2
2
  SampleAdapter:
3
- poll_interval: 300
3
+ :poll_interval: 300
4
4
  SimpleAdapter:
5
- poll_interval: 600
5
+ :poll_interval: 600
6
6
  partition_type: 'app'
7
7
  FixedSchemaAdapter:
8
- poll_interval: 300
8
+ :poll_interval: 300
9
9
  sync_type: 'incremental'
10
10
  belongs_to:
11
11
  - brand: 'SampleAdapter'
12
+ OtherAdapter:
13
+ partition_type: 'app'
14
+ :force_default: true
15
+ :poll_interval: 300
12
16
 
13
17
  :development:
14
18
  :licensefile: settings/license.key
15
19
  :bulk_sync_poll_interval: 3600
16
20
  :redis: localhost:6379
17
21
  :syncserver: http://localhost:9292/application/
18
- :appserver: http://test.rhoconnect.com
22
+ :appserver: http://test.com
19
23
  :api_token: b6f22608fa8b4acf84e844808845e2fe
20
24
  :test:
21
25
  :licensefile: settings/license.key
@@ -26,9 +30,10 @@
26
30
  :bulk_sync_poll_interval: 3600
27
31
  :redis: localhost:6379
28
32
  :syncserver: http://localhost:9292/application/
29
- :appserver: http://test.rhoconnect.com
33
+ :appserver: http://test.com
30
34
  :api_token: b6f22608fa8b4acf84e844808845e2fe
31
35
  :cookie_expire: 9999999
36
+ :poll_interval_default: 201
32
37
  :production:
33
38
  :licensefile: settings/license.key
34
39
  :bulk_sync_poll_interval: 3600
@@ -0,0 +1,7 @@
1
+ require 'base_adapter'
2
+
3
+ class OtherAdapter < BaseAdapter
4
+ def initialize(source)
5
+ super(source)
6
+ end
7
+ end
@@ -12,8 +12,8 @@ describe "ClientSync" do
12
12
  params = {'create'=>{'1'=>@product1}}
13
13
  @c.source_name = 'Product2'
14
14
  @cs1 = ClientSync.new(@s2,@c,2)
15
- stub_request(:post, "http://test.rhoconnect.com/rhoconnect/authenticate")
16
- stub_request(:post, "http://test.rhoconnect.com/rhoconnect/create").with(:headers => {'Content-Type' => 'application/json'}).to_return(:body => {:id => 5})
15
+ stub_request(:post, "http://test.com/rhoconnect/authenticate")
16
+ stub_request(:post, "http://test.com/rhoconnect/create").with(:headers => {'Content-Type' => 'application/json'}).to_return(:body => {:id => 5})
17
17
  @cs1.receive_cud(params)
18
18
  verify_result(@cs1.client.docname(:create) => {},
19
19
  @cs1.client.docname(:update) => {},
@@ -23,8 +23,8 @@ describe "ClientSync" do
23
23
  it "should handle send cud for dynamic adapter" do
24
24
  data = {'1'=>@product1}
25
25
  expected = {'insert'=>data}
26
- stub_request(:post, "http://test.rhoconnect.com/rhoconnect/authenticate")
27
- stub_request(:post, "http://test.rhoconnect.com/rhoconnect/query").with(:headers => {'Content-Type' => 'application/json'}).to_return(:status => 200, :body => data.to_json)
26
+ stub_request(:post, "http://test.com/rhoconnect/authenticate")
27
+ stub_request(:post, "http://test.com/rhoconnect/query").with(:headers => {'Content-Type' => 'application/json'}).to_return(:status => 200, :body => data.to_json)
28
28
 
29
29
  @c.source_name = 'Product'
30
30
  @cs1 = ClientSync.new(@s2,@c,2)
@@ -234,10 +234,6 @@ describe "ClientSync" do
234
234
  @c.docname(:cd) => {})
235
235
  end
236
236
 
237
- it "should handle blob upload in receive_cud" do
238
- pending
239
- end
240
-
241
237
  it "should handle send_cud with query_params" do
242
238
  expected = {'1'=>@product1}
243
239
  set_state('test_db_storage' => {'1'=>@product1,'2'=>@product2,'4'=>@product4})
@@ -677,6 +673,7 @@ describe "ClientSync" do
677
673
  it "should create bulk data job app partition if none exists and no partition sources" do
678
674
  @s2.delete
679
675
  @a.sources.delete("SimpleAdapter")
676
+ @a.sources.delete("OtherAdapter")
680
677
  ClientSync.bulk_data(:app,@c).should == {:result => :nop}
681
678
  Resque.peek(:bulk_data).should == nil
682
679
  end