rhoconnect 3.3.1.beta4 → 3.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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