rhoconnect 3.0.0.beta1 → 3.0.0.beta3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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