rhoconnect 3.3.1.beta4 → 3.3.1

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.
@@ -33,7 +33,6 @@ module RhoconnectConsole
33
33
  @domain += "/application" if @domain
34
34
  erb :index
35
35
  end
36
-
37
36
 
38
37
  post "/get_user_graph" do
39
38
  count_graph('timing/usercount', "User Count", "Users", "users")
@@ -46,10 +45,36 @@ module RhoconnectConsole
46
45
  post '/http_timing' do
47
46
  http_timing(params)
48
47
  end
48
+
49
+ post '/http_timing_key' do
50
+ http_timing_key(params)
51
+ end
49
52
 
50
53
  post '/device_count' do
51
54
  count_graph('timing/devicecount', "Device Count", "Devices", "clients")
52
55
  end
53
56
 
57
+ get '/get_sources' do
58
+ sources = App.load(APP_NAME).sources
59
+ sources.to_json
60
+ end
61
+
62
+ get '/get_http_routes' do
63
+ keys = get_user_count("http:*:*")
64
+ sources = get_sources('all')
65
+
66
+ #loop through arrays and remove any regex matches
67
+ keysf = keys.inject([]) do |keys_final, element|
68
+ found = true
69
+ sources.each do |s|
70
+ found = false if element.match(s)
71
+ end
72
+ keys_final << element.strip if found
73
+ keys_final
74
+ end
75
+
76
+ keysf.to_json
77
+ end
78
+
54
79
  end
55
80
  end
@@ -28,7 +28,7 @@
28
28
  <script language="javascript" type="text/javascript" src='views/show_user.js'></script>
29
29
  <script language="javascript" type="text/javascript" src='views/show_device.js'></script>
30
30
  <script language="javascript" type="text/javascript" src='views/new_ping.js'></script>
31
- <script language="javascript" type="text/javascript" src='views/stats.js'></script>
31
+ <script language="javascript" type="text/javascript" src='views/stats.js'></script>
32
32
  <script language="javascript" type="text/javascript" src='models/session.js'></script>
33
33
  <script language="javascript" type="text/javascript" src='models/source.js'></script>
34
34
  <script language="javascript" type="text/javascript" src='models/doc.js'></script>
@@ -36,6 +36,7 @@
36
36
  <script language="javascript" type="text/javascript" src='models/user.js'></script>
37
37
  <script language="javascript" type="text/javascript" src='models/client.js'></script>
38
38
  <script language="javascript" type="text/javascript" src='models/stats.js'></script>
39
+ <script language="javascript" type="text/javascript" src='public/bootstrap-collapse.js'></script>
39
40
  </head>
40
41
  <body>
41
42
  <input id='token' type='hidden' value='<%=@token%>'>
@@ -44,7 +45,8 @@
44
45
  <div id='nav_menu' class="navbar navbar-fixed-top" style="<%@heroku ? 'display:none' : 'display:block'%>">
45
46
  <div class='navbar-inner'>
46
47
  <div class='container'>
47
- <div class="brand">
48
+ <div class="brand" style='padding-bottom:8px'>
49
+ <!--<img src='public/logo.png' alt='image' height='40' width='40'/>-->
48
50
  RhoConnect
49
51
  </div>
50
52
  <ul class='nav pull-right'>
@@ -24,7 +24,7 @@
24
24
  <% if s.nil? or s['data'].length < 1 %>
25
25
  <center>No data for <b><%= s.nil? ? "" : s['name'] %></b></center><br/><br/>
26
26
  <% else %>
27
- <div id="chartdiv" style="height:295px;width:670px; display:none;"></div>
27
+ <div id="chartdiv" style="height:295px;width:570px; display:none;"></div>
28
28
  <%end%>
29
29
  <%
30
30
  def fix_json(instring)
@@ -35,26 +35,26 @@ end
35
35
 
36
36
  %>
37
37
 
38
- <% if @displayname.nil? %>
38
+
39
39
  <script type="text/javascript">
40
- document.getElementById('chartdiv').style.display = '';plot = $.jqplot('chartdiv',<%=@sources[0]['data'].to_json.gsub(/"/,"'")%>,<%=fix_json(@sources[0]['options'].to_json)%>); plot.redraw();
40
+ var doc = document.getElementById('chartdiv');
41
+ if(doc){
42
+ doc.style.display = '';
43
+ plot = $.jqplot('chartdiv',<%=@sources[0]['data'].to_json.gsub(/"/,"'")%>,<%=fix_json(@sources[0]['options'].to_json)%>);
44
+ plot.redraw();
45
+ }
41
46
  </script>
42
- <%end%>
47
+
43
48
 
44
49
  <br/>
45
50
 
46
51
 
47
52
 
48
- <% if @sources.length > 1%>
53
+ <% if @keys and @keys.length > 1%>
49
54
  <ul id='source-list' class='nav nav-pills' style='margin-left:35px'>
50
- <% @sources.each do |source| %>
51
- <% if @displayname == source['name'] %>
52
- <script type="text/javascript">
53
- document.getElementById('chartdiv').style.display = '';plot = $.jqplot('chartdiv',<%=source['data'].to_json.gsub(/"/,"'")%>,<%=fix_json(source['options'].to_json)%>); plot.redraw();
54
- </script>
55
- <% end %>
56
- <li class="<%=source['name'] == @displayname ? 'active' : ''%>">
57
- <a id='<%=@graph_t == 'http' ? "http_timing" : "source_timing_display"%>' style="margin-right:5px"><%= source['name'] %></a></li>
55
+ <% @keys.each do |key| %>
56
+ <li class="<%=key == @keyname ? 'active' : ''%>">
57
+ <a class='source_timing_key' style="margin-right:5px" id='<%=@sources[0]['name']%>'><%= key %></a></li>
58
58
  <% end%>
59
59
  </ul>
60
60
  <% end %>
@@ -24,7 +24,14 @@ App.Views.NewPing = Backbone.View.extend({
24
24
  $.ajax({
25
25
  type: 'POST',
26
26
  url: '/rc/v1/users/ping',
27
- data: {user_id : users, message : message, vibrate : vibrate, badge : badge, sources : sources},
27
+ data: {
28
+ user_id : users,
29
+ message : message,
30
+ vibrate : vibrate,
31
+ sound : sound,
32
+ badge : badge,
33
+ sources : sources
34
+ },
28
35
  beforeSend: function (HttpRequest) {
29
36
  HttpRequest.setRequestHeader("X-RhoConnect-API-TOKEN", token);
30
37
  },
@@ -51,7 +58,7 @@ App.Views.NewPing = Backbone.View.extend({
51
58
  out += "<td>Message to be displayed in push notification</td></tr>"
52
59
  out += "<tr><td>Sources</td><td><input type='text' name='sources' id='sources' value='' class='input-xlarge'/></td>";
53
60
  out += "<td>List of sources to be synchronized</td></tr>"
54
- out += "<tr><td>Sound</td><td><input id='pingsound' type='text' name='badge' value='welcome.mp3' class='input-medium'/></td>";
61
+ out += "<tr><td>Sound</td><td><input id='pingsound' type='text' name='sound' value='welcome.mp3' class='input-medium'/></td>";
55
62
  out += "<td>allows you to play audio file if it exists on client</td></tr>"
56
63
  out += "<tr><td>Badge</td><td><input id='pingbadge' type='text' name='badge' value='1' class='input-small'/></td>";
57
64
  out += "<td>Number displayed on device next to app when push notification arrives. Available for iPhone</td></tr>"
@@ -3,62 +3,106 @@ App.Views.Stats = Backbone.View.extend({
3
3
  events: {
4
4
  "click a#user_count" : "user_count",
5
5
  "click a#device_count" : "device_count",
6
- "click a#http_timing" : "http_timing",
7
- "click a#source_timing" : "source_timing",
8
- "click a#source_timing_display" : "source_timing_display",
6
+ "click a.http_timing" : "http_timing",
7
+ "click a.http_timing_key" : "http_timing_key",
8
+ "click a.source_timing_display" : "source_timing_display",
9
+ "click a.source_timing_key" : "source_timing_key",
9
10
 
10
11
  },
11
12
 
12
13
  initialize: function(){
13
14
  this.render();
14
15
  this.user_count();
16
+ this.model.get_sources();
17
+ this.model.get_http_routes();
15
18
  },
16
19
 
17
20
  user_count: function(){
18
- this.change_tab('user_count');
21
+ $("#device_count").attr('class','');
22
+ $('#user_count').attr('class','label label-info');
19
23
  this.model.user_stats();
20
24
  },
21
25
 
22
26
  device_count: function(){
23
- this.change_tab('device_count');
27
+ $("#user_count").attr('class','');
28
+ $('#device_count').attr('class','label label-info');
24
29
  this.model.device_count();
25
30
  },
26
31
 
27
32
  http_timing: function(ev){
28
- var display_name = ev.currentTarget.innerHTML;
29
- this.change_tab('http_timing');
33
+ var display_name = ev.currentTarget.id;
34
+ $('.http_timing').attr('class','http_timing');
35
+ ev.currentTarget.className = "http_timing label label-info"
30
36
  this.model.http_timing(display_name);
31
37
  },
32
38
 
33
- source_timing: function(){
34
- this.change_tab('source_timing');
35
- this.model.source_timing();
39
+ http_timing_key: function(ev){
40
+ var display_name = ev.currentTarget.id;
41
+ $('.http_timing_key').attr('class','http_timing_key');
42
+ ev.currentTarget.className = "http_timing_key label label-info"
43
+ this.model.http_timing_key(display_name);
36
44
  },
37
45
 
38
46
  source_timing_display: function(ev){
39
- var display_name = ev.currentTarget.innerHTML;
40
- this.change_tab('source_timing');
41
- this.model.source_timing(display_name);
47
+ var display_name = ev.currentTarget.id;
48
+
49
+ $(".source_timing_display").attr('class','source_timing_display');
50
+ $('#'+display_name).attr('class','label label-info source_timing_display');
51
+ this.model.source_timing(display_name.substr(0,display_name.length - 1));
52
+ },
53
+
54
+ source_timing_key: function(ev){
55
+ var display_name = ev.currentTarget.id;
56
+ var key = ev.currentTarget.innerHTML;
57
+
58
+ $(".source_timing_key").attr('class','source_timing_key');
59
+ $('#'+key).attr('class','label label-info source_timing_key');
60
+ this.model.source_timing(display_name,key);
42
61
  },
43
62
 
44
63
  change_tab: function(tab){
45
- $('#user_count').parent().attr('class','');
46
- $('#device_count').parent().attr('class','');
47
- $('#http_timing').parent().attr('class','');
48
- $('#source_timing').parent().attr('class','');
49
- $('#'+tab).parent().attr('class','active');
64
+ // $(".label").attr('class','');
65
+ // $('#'+tab).attr('class','label label-info');
50
66
  },
51
67
 
52
68
  render: function(){
53
69
  $('#secondary-nav').css('display','block');
54
70
  out = "<div id='stats-alert' class='alert alert-error' style='display:none'></div>"
55
- out += "<div class='tabs-left'><ul class='nav nav-tabs'>"
56
- out += "<li class='active'><a id='user_count'>User Count</a></li>"
57
- out += "<li><a id='device_count'>Device Count</a></li>"
58
- out += "<li><a id='http_timing'>HTTP Timing</a></li>"
59
- out += "<li><a id='source_timing'>Source Timing</a></li>"
60
- out += "</ul>"
61
- out += "<div id='stats_main' style='margin-left:200px'>"
71
+ out += "<div class='span4'>"
72
+ out += "<div class='accordion' id='accordion2'>"
73
+ out += "<div class='accordion-group'><div class='accordion-heading' style='font-weight:bold'>"
74
+ out += "<a class='accordion-toggle' data-toggle='collapse' data-parent='#accordion2' href='#collapseOne'>Count</a></div>"
75
+ out += "<div id='collapseOne' class='accordion-body in collapse'>";
76
+ out += "<div class='accordion-inner'><a id='device_count'>- Device Count</a></div>"
77
+ out += "<div class='accordion-inner'><a class='label label-info' id='user_count'>- User Count</a></div>"
78
+ out += "</div></div>"
79
+
80
+ out += "<div class='accordion-group'>"
81
+ out += "<div class='accordion-heading' style='font-weight:bold'>"
82
+ out += "<a class='accordion-toggle' data-toggle='collapse' data-parent='#accordion2' href='#collapseTwo'>HTTP Adapter Timing</a></div>"
83
+ out += "<div id='collapseTwo' class='accordion-body collapse'>";
84
+ out += "</div></div>"
85
+
86
+ // out += "<div class='accordion-group'>"
87
+ // out += "<div class='accordion-heading' style='font-weight:bold'>"
88
+ // out += "<a class='accordion-toggle' data-toggle='collapse' data-parent='#accordion2' href='#collapseFour'>HTTP Route Timing</a></div>"
89
+ // out += "<div id='collapseFour' class='accordion-body collapse'>";
90
+ // out += "</div></div>"
91
+
92
+ out += "<div class='accordion-group'>"
93
+ out += "<div class='accordion-heading' style='font-weight:bold'>"
94
+ out += "<a class='accordion-toggle' data-toggle='collapse' data-parent='#accordion2' href='#collapseThree'>Source Timing</a></div>"
95
+ out += "<div id='collapseThree' class='accordion-body collapse'>";
96
+ out += "</div></div>"
97
+
98
+ out += "</div></div>"
99
+
100
+ //out += "<li id='http_timing_header' class='nav nav-header'>Adapter HTTP Timing</li>"
101
+ //out += "<li><a id='http_timing'>HTTP Timing</a></li>"
102
+ //out += "<li class='nav nav-header'>Source Timing</li>"
103
+ //out += "<li><a id='source_timing'>Source Timing</a></li>"
104
+ //out += "</ul>"
105
+ out += "<div id='stats_main' style='margin-left:365px'>"
62
106
  out += "</div>"
63
107
  //out += "<ul id='source-list' class='nav nav-pills' style='margin-left:200px'></ul>"
64
108
  out += "</div></div>"
data/spec/async_spec.rb CHANGED
@@ -1,7 +1,7 @@
1
1
  require File.join(File.dirname(__FILE__),'api','api_helper')
2
2
 
3
3
  # these specs are executed only with Async support
4
- if RUBY_VERSION =~ /1.9/
4
+ if RUBY_VERSION =~ /1.9/ and not defined?(JRUBY_VERSION)
5
5
  describe "BasicEventMachineTest with Threads" do
6
6
  it_should_behave_like "ApiHelper" do
7
7
  it "should run EventMachine gracefully and schedule callback execution in thread" do
@@ -4,6 +4,7 @@ describe "BulkData" do
4
4
  it_behaves_like "SharedRhoconnectHelper", :rhoconnect_data => true do
5
5
  before(:each) do
6
6
  @s = Source.load(@s_fields[:name],@s_params)
7
+ @s1 = Source.load(@s1_fields[:name], @s_params)
7
8
  end
8
9
 
9
10
  after(:each) do
@@ -79,9 +80,23 @@ describe "BulkData" do
79
80
  :state => :inprogress,
80
81
  :app_id => @a.id,
81
82
  :user_id => @u.id,
82
- :sources => [@s_fields[:name]])
83
+ :sources => [@s_fields[:name], @s1_fields[:name]])
84
+ data.process_sources
85
+ @s.read_state.refresh_time.should > current + @s_fields[:poll_interval].to_i
86
+ @s1.read_state.refresh_time.should > current + @s1_fields[:poll_interval].to_i
87
+ end
88
+
89
+ it "should process specific sources for bulk data" do
90
+ current = Time.now.to_i
91
+ @s.read_state.refresh_time = current
92
+ data = BulkData.create(:name => bulk_data_docname(@a.id,@u.id),
93
+ :state => :inprogress,
94
+ :app_id => @a.id,
95
+ :user_id => @u.id,
96
+ :sources => [@s1_fields[:name]])
83
97
  data.process_sources
84
- @s.read_state.refresh_time.should >= current + @s_fields[:poll_interval].to_i
98
+ @s.read_state.refresh_time.should <= current
99
+ @s1.read_state.refresh_time.should > current + @s1_fields[:poll_interval].to_i
85
100
  end
86
101
 
87
102
  it "should delete source masterdoc copy on delete" do
@@ -22,6 +22,7 @@ describe "BulkDataJob" do
22
22
  :state => :inprogress,
23
23
  :app_id => @a.id,
24
24
  :user_id => @u.id,
25
+ :partition_sources => [@s_fields[:name],'FixedSchemaAdapter'],
25
26
  :sources => [@s_fields[:name], 'FixedSchemaAdapter'])
26
27
  do_bulk_data_job("data_name" => data.name)
27
28
  data = BulkData.load(docname)
@@ -40,7 +41,37 @@ describe "BulkDataJob" do
40
41
  data.dbfile = File.join(path,File.basename(data.dbfile))
41
42
  validate_db(data,expected).should == true
42
43
  end
43
-
44
+
45
+ it "should create bulk data files from master document for specific sources" do
46
+ set_state('test_db_storage' => @data)
47
+ docname = bulk_data_docname(@a.id,@u.id)
48
+ expected = { @s_fields[:name] => {},
49
+ 'FixedSchemaAdapter' => @data
50
+ }
51
+ data = BulkData.create(:name => docname,
52
+ :state => :inprogress,
53
+ :app_id => @a.id,
54
+ :user_id => @u.id,
55
+ :partition_sources => [@s_fields[:name],'FixedSchemaAdapter'],
56
+ :sources => ['FixedSchemaAdapter'])
57
+ do_bulk_data_job("data_name" => data.name)
58
+ data = BulkData.load(docname)
59
+ data.completed?.should == true
60
+ verify_result(@s.docname(:md) => {},@s.docname(:md_copy) => {})
61
+ validate_db_file(data.dbfile,[@s_fields[:name], 'FixedSchemaAdapter'], expected).should == true
62
+ File.exists?(data.dbfile+'.rzip').should == true
63
+ File.exists?(data.dbfile+'.gzip').should == true
64
+ File.exists?(data.dbfile+'.hsqldb.data').should == true
65
+ File.exists?(data.dbfile+'.hsqldb.data.gzip').should == true
66
+ File.exists?(data.dbfile+'.hsqldb.script').should == true
67
+ File.exists?(data.dbfile+'.hsqldb.properties').should == true
68
+ path = File.join(File.dirname(data.dbfile),'tmp')
69
+ FileUtils.mkdir_p path
70
+ unzip_file("#{data.dbfile}.rzip",path)
71
+ data.dbfile = File.join(path,File.basename(data.dbfile))
72
+ validate_db_file(data.dbfile,[@s_fields[:name], 'FixedSchemaAdapter'], expected).should == true
73
+ end
74
+
44
75
  it "should not create hsql db files if blackberry_bulk_sync is disabled" do
45
76
  Rhoconnect.blackberry_bulk_sync = false
46
77
  set_state('test_db_storage' => @data)
@@ -49,6 +80,7 @@ describe "BulkDataJob" do
49
80
  :state => :inprogress,
50
81
  :app_id => @a.id,
51
82
  :user_id => @u.id,
83
+ :partition_sources => [@s_fields[:name]],
52
84
  :sources => [@s_fields[:name]])
53
85
  do_bulk_data_job("data_name" => data.name)
54
86
  data = BulkData.load(docname)
@@ -67,6 +99,7 @@ describe "BulkDataJob" do
67
99
  :state => :inprogress,
68
100
  :app_id => @a.id,
69
101
  :user_id => @u.id,
102
+ :partition_sources => [@s_fields[:name]],
70
103
  :sources => [@s_fields[:name]])
71
104
  do_bulk_data_job("data_name" => data.name)
72
105
  data = BulkData.load(docname)
@@ -86,6 +119,7 @@ describe "BulkDataJob" do
86
119
  :state => :inprogress,
87
120
  :app_id => @a.id,
88
121
  :user_id => @u.id,
122
+ :partition_sources => [@s_fields[:name]],
89
123
  :sources => [@s_fields[:name]])
90
124
  do_bulk_data_job("data_name" => data.name)
91
125
  data = BulkData.load(docname)
@@ -101,6 +135,7 @@ describe "BulkDataJob" do
101
135
  :state => :inprogress,
102
136
  :app_id => @a.id,
103
137
  :user_id => @u.id,
138
+ :partition_sources => [@s_fields[:name]],
104
139
  :sources => [@s_fields[:name]])
105
140
  lambda { BulkDataJob.create_hsql_data_file(data,Time.now.to_i.to_s)
106
141
  }.should raise_error(Exception,"Error running hsqldata")
@@ -118,6 +153,7 @@ describe "BulkDataJob" do
118
153
  :state => :inprogress,
119
154
  :app_id => 'broken',
120
155
  :user_id => @u.id,
156
+ :partition_sources => [@s_fields[:name]],
121
157
  :sources => [@s_fields[:name]])
122
158
  lambda {
123
159
  do_bulk_data_job("data_name" => data.name)
data/spec/spec_helper.rb CHANGED
@@ -8,7 +8,7 @@ if RUBY_VERSION =~ /1.9/ || defined?(JRUBY_VERSION)
8
8
  end
9
9
 
10
10
  # all specs are Async'd in new ruby
11
- if RUBY_VERSION =~ /1.9/
11
+ if RUBY_VERSION =~ /1.9/ and not defined?(JRUBY_VERSION)
12
12
  require 'eventmachine'
13
13
  require 'fiber'
14
14
 
@@ -201,7 +201,7 @@ module TestHelpers
201
201
  db.execute("select source_id,name,sync_priority,partition,sync_type,source_attribs,
202
202
  metadata,schema,blob_attribs,associations,last_inserted_size, backend_refresh_time
203
203
  from sources where name='#{s.name}'").each do |row|
204
-
204
+
205
205
  return false if row[0].to_s != s.source_id.to_s
206
206
  return false if row[1] != s.name
207
207
  return false if row[2].to_s != s.priority.to_s