From: martyntaylor <[email protected]>

---
 src/app/controllers/dashboard_controller.rb |   18 +-
 src/app/models/graph.rb                     |   28 +++
 src/app/services/graph_service.rb           |  320 +++++++++++++++++----------
 src/app/views/dashboard/summary.haml        |    8 +-
 4 files changed, 255 insertions(+), 119 deletions(-)

diff --git a/src/app/controllers/dashboard_controller.rb 
b/src/app/controllers/dashboard_controller.rb
index bcd2073..757598d 100644
--- a/src/app/controllers/dashboard_controller.rb
+++ b/src/app/controllers/dashboard_controller.rb
@@ -31,17 +31,25 @@ class DashboardController < ApplicationController
     return params[:ajax] == "true"
   end
 
-  def provider_qos_graph
+  def provider_qos_avg_time_to_submit_graph
     params[:provider] = Provider.find(params[:id])
-    graph = GraphService.dashboard_qos(current_user, 
params)[params[:provider]][Graph::QOS_AVG_TIME_TO_SUBMIT]
+    graph = GraphService.dashboard_qos_avg_time_to_submit_graph(current_user, 
params)[params[:provider]][Graph::QOS_AVG_TIME_TO_SUBMIT]
     respond_to do |format|
       format.svg  { render :xml => graph.svg}
     end
   end
 
-  def account_quota_graph
-    params[:account] = CloudAccount.find(params[:id])
-    graph = GraphService.dashboard_quota(current_user, 
params)[params[:account]][Graph::QUOTA_INSTANCES_IN_USE]
+  def quota_usage_graph
+    if params[:cloud_account_id]
+      params[:parent] = CloudAccount.find(params[:cloud_account_id])
+    elsif params[:pool_id]
+      params[:parent] = Pool.find(params[:pool_id])
+    else
+      return nil
+    end
+
+    graphs = GraphService.dashboard_quota_usage(current_user, params)
+    graph = 
graphs[params[:parent]][Graph.get_quota_usage_graph_name(params[:resource_name])]
     respond_to do |format|
       format.svg  { render :xml => graph.svg}
     end
diff --git a/src/app/models/graph.rb b/src/app/models/graph.rb
index 1c20dc3..cf1b498 100644
--- a/src/app/models/graph.rb
+++ b/src/app/models/graph.rb
@@ -4,7 +4,35 @@ class Graph
   QOS_AVG_TIME_TO_SUBMIT = "qos_avg_time_to_submit"
   QUOTA_INSTANCES_IN_USE = "quota_instances_in_use"
   INSTANCES_BY_PROVIDER_PIE = "instances_by_provider_pie"
+
+  # Quota Usage Graphs
+  QUOTA_USAGE_RUNNING_INSTANCES = "quota_utilization_running_instances"
+  QUOTA_USAGE_RUNNING_MEMORY = "quota_utilization_running_memory"
+  QUOTA_USAGE_RUNNING_CPUS = "quota_utilization_running_cpus"
+  QUOTA_USAGE_TOTAL_INSTANCES = "quota_utilization_total_instances"
+  QUOTA_USAGE_TOTAL_STORAGE = "quota_utilization_total_storage"
+  QUOTA_USAGE_OVERALL = "quota_utilization_overall"
+
   def initialize
     @svg = ""
   end
+
+  def self.get_quota_usage_graph_name(resource_name)
+    case resource_name
+      when Quota::RESOURCE_RUNNING_INSTANCES
+        return QUOTA_USAGE_RUNNING_INSTANCES
+      when Quota::RESOURCE_RUNNING_MEMORY
+        return QUOTA_USAGE_RUNNING_MEMORY
+      when  Quota::RESOURCE_RUNNING_CPUS
+        return QUOTA_USAGE_RUNNING_CPUS
+      when Quota::RESOURCE_TOTAL_INSTANCES
+        return QUOTA_USAGE_TOTAL_INSTANCES
+      when Quota::RESOURCE_TOTAL_STORAGE
+        return QUOTA_USAGE_TOTAL_STORAGE
+      when Quota::RESOURCE_OVERALL
+        return QUOTA_USAGE_OVERALL
+      else
+        return nil
+    end
+  end
 end
diff --git a/src/app/services/graph_service.rb 
b/src/app/services/graph_service.rb
index 11da01c..6c17743 100644
--- a/src/app/services/graph_service.rb
+++ b/src/app/services/graph_service.rb
@@ -3,6 +3,8 @@ class GraphService
   require 'nokogiri'
   require 'scruffy'
 
+  DATA_SERVICE = DataServiceActiveRecord
+
   def self.dashboard_quota (user,opts = {})
     #FIXME add permission checks to filter what graphs user can get
     graphs = Hash.new
@@ -12,7 +14,7 @@ class GraphService
     if opts[:cloud_account]
       cloud_account = opts[:cloud_account]
       cloud_account_graphs = Hash.new
-      cloud_account_graphs[Graph::QUOTA_INSTANCES_IN_USE] = 
quota_instances_in_use_graph(cloud_account,opts)
+      cloud_account_graphs[Graph::QUOTA_INSTANCES_IN_USE] = 
qos_failure_rate_graph(parent, opts = {})
       graphs[cloud_account] = cloud_account_graphs
     else
       CloudAccount.all.each do |cloud_account|
@@ -24,7 +26,16 @@ class GraphService
     graphs
   end
 
-  def self.dashboard_qos (user,opts = {})
+  def self.dashboard_quota_usage(user, opts = {})
+    parent = opts[:parent]
+
+    graphs = Hash.new
+    graphs[parent] = quota_usage_graph(parent, opts)
+
+    return graphs
+  end
+
+  def self.dashboard_qos_avg_time_to_submit_graph(user, opts = {})
     #FIXME add permission checks to filter what graphs user can get
     graphs = Hash.new
 
@@ -58,7 +69,198 @@ class GraphService
     output_stream = IO::popen( cmd, "r+")
   end
 
-  def self.quota_instances_in_use_graph (cloud_account, opts = {})
+  def self.quota_usage_graph (parent, opts = {})
+    x = [1,2]
+
+    #we'll just have zero values for the unexpected case where cloud_account 
has no quota
+    y = x.collect { |v| 0 }
+    if parent.quota
+      quota = parent.quota
+      data_point = DataServiceActiveRecord.quota_usage(parent, 
opts[:resource_name])
+      #Handle No Limit case
+      if data_point.max == Quota::NO_LIMIT
+        y = [data_point.used, nil]
+      else
+        y = [data_point.used, data_point.max]
+      end
+    end
+
+    chart_opts = {:x => x, :y => y}
+
+    graphs = Hash.new
+    graphs[Graph.get_quota_usage_graph_name(opts[:resource_name])] = 
draw_bar_chart(opts, chart_opts)
+    return graphs
+  end
+
+  def self.qos_avg_time_to_submit_graph(parent, opts = {})
+    start_time = Time.parse(opts[:start_time])
+    end_time = Time.parse(opts[:end_time])
+    interval_length = opts[:interval_length].to_f
+    action = opts[:task_action]
+
+    stats = DATA_SERVICE.qos_task_submission_stats(parent, start_time, 
end_time, interval_length, action)
+    data = get_data_from_stats(stats, "average")
+    draw_line_graph(opts, data)
+  end
+
+  def self.qos_failure_rate_graph(parent, opts = {})
+    start_time = Time.parse(opts[:start_time])
+    end_time = Time.parse(opts[:end_time])
+    interval_length = opts[:interval_length].to_f
+    failure_code = opts[:failure_code]
+
+    stats = DATA_SERVICE.qos_failure_rate_stats(parent, start_time, end_time, 
interval_length, failure_code)
+    data = get_data_from_stats(stats, "failure_rate")
+    data[:y_range] = "[0:100]"
+    draw_line_graph(opts, data)
+  end
+
+  def self.qos_avg_time_to_complete_life_cycle_event(parent, opts = {})
+    start_time = Time.parse(opts[:start_time])
+    end_time = Time.parse(opts[:end_time])
+    interval_length = opts[:interval_length].to_f
+    action = opts[:task_action]
+
+    stats = DATA_SERVICE.qos_task_completion_stats(parent, start_time, 
end_time, interval_length, action)
+    data = get_data_from_stats(stats, "average")
+    draw_line_graph(opts, data)
+  end
+
+  def self.instances_by_provider_pie (opts = {})
+    pie_opts = {}
+    providers = Provider.all
+    providers.each do |provider|
+      running_instances = 0
+      provider.cloud_accounts.each do |account|
+        running_instances = running_instances + 
account.quota.running_instances if account.quota
+      end
+      if running_instances > 0
+        pie_opts[:"#{provider.name}"] = running_instances
+      end
+    end
+
+    return draw_pie_chart(opts, pie_opts)
+  end
+
+  def self.get_data_from_stats(stats, type)
+    x = []
+    y = []
+    y_max = 0
+    for i in 0...stats.length do
+      x << i
+      y_value = stats[i][type]
+      if y_value
+        y << y_value
+        if y_value > y_max
+          y_max = y_value
+        end
+      else
+        y << 0
+      end
+    end
+
+    if y_max == 0
+      y_max = 1
+    else
+      y_max = y_max * 1.1
+    end
+
+    y_range = "[0:" + y_max.to_s + "]"
+    return { :x => x, :y => y, :y_range => y_range }
+  end
+
+  def self.draw_pie_chart(opts, pie_opts)
+    #things we're checking for in opts: :height, :width
+    height = 200 unless opts[:height].nil? ? nil : height = opts[:height].to_i
+    width =  300 unless  opts[:width].nil? ? nil : width  = opts[:width].to_i
+
+    graph = Graph.new
+
+    mytheme = Scruffy::Themes::Keynote.new
+    mytheme.background = :white
+    mytheme.marker = :black #sets the label text color
+    mytheme.colors = %w(#00689a #00b0e0)
+
+    scruffy_graph = Scruffy::Graph.new({:theme => mytheme})
+    scruffy_graph.renderer = Scruffy::Renderers::Pie.new
+    scruffy_graph.add :pie, '', pie_opts
+
+    raw_svg = scruffy_graph.render :width => width, :height => height
+
+    xml = Nokogiri::XML(raw_svg)
+    svg = xml.css 'svg'
+    svg.each do |node|
+      node.set_attribute 'viewBox',"0 0 #{width} #{height}"
+    end
+
+    xml.root.traverse do |node|
+      if node.name == 'text'
+        if node.has_attribute? 'font-family'
+          node.set_attribute 'font-family','sans-serif'
+        end
+        if (node.has_attribute? 'font-size') && 
node.get_attribute('font-size').length > 0
+          size = node.get_attribute('font-size').to_f
+          size = size * 1.5
+          node.set_attribute 'font-size',size.to_s
+        end
+      end
+    end
+
+    graph.svg = xml.to_s
+    graph
+  end
+
+  def self.draw_line_graph(opts, data)
+    #things we're checking for in opts: :height, :width
+
+    height = 60 unless opts[:height].nil? ? nil : height = opts[:height].to_i
+    width = 100 unless  opts[:width].nil? ? nil : width  = opts[:width].to_i
+
+    graph = Graph.new
+    gp = gnuplot_open
+
+    Gnuplot::Plot.new( gp ) do |plot|
+      plot.terminal "svg size #{width},#{height}"
+      plot.arbitrary_lines << "unset xtics"
+      plot.arbitrary_lines << "unset x2tics"
+      plot.arbitrary_lines << "unset ytics"
+      plot.arbitrary_lines << "unset y2tics"
+      plot.set "bmargin","0"
+      plot.set "lmargin","1"
+      plot.set "rmargin","0"
+      plot.set "tmargin","0"
+
+      #FIXME: get data from DataService for the provider.
+      #For demo, plot a random walk for demo of graph display until we hook 
into DataService
+      #First build two equal-length arrays
+      #x = (0..500).collect { |v| v.to_f }
+
+      #walk = 0
+      #y = x.collect { |v| rand > 0.5 ? walk = walk + 1 : walk = walk - 1 }
+
+      x = data[:x]
+      y = data[:y]
+      y_range = data[:y_range]
+
+      #plot.set "yrange [-50:50]"
+      plot.set "yrange " + y_range
+
+      #This type of plot takes two equal length arrays of numbers as input.
+      plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds|
+        ds.using = "1:2"
+        ds.with = "lines"
+        ds.notitle
+      end
+    end
+    gp.flush
+    gp.close_write
+    gp.read(nil,graph.svg)
+    gp.close_read
+    graph
+  end
+
+  def self.draw_bar_chart(opts, chart_opts)
+
     #things we're checking for in opts: :max_value, :height, :width
 
     unless max_value = opts[:max_value]
@@ -67,7 +269,6 @@ class GraphService
     height = 80 unless opts[:height].nil? ? nil : height = opts[:height].to_i
     width = 150 unless  opts[:width].nil? ? nil : width  = opts[:width].to_i
 
-
     raw_svg = ""
     gp = gnuplot_open
     Gnuplot::Plot.new( gp ) do |plot|
@@ -87,14 +288,8 @@ class GraphService
       plot.set "xrange [.25:2.75]"
       plot.set "yrange [0:#{max_value * 1.5}]" #we want to scale maxvalue 50% 
larger to leave room for label
 
-      x = [1,2]
-      #we'll just have zero values for the unexpected case where cloud_account 
has no quota
-      y = x.collect { |v| 0 }
-      if cloud_account.quota
-        quota = cloud_account.quota
-        y = [quota.running_instances,quota.maximum_running_instances]
-      end
-
+      x = chart_opts[:x]
+      y = chart_opts[:y]
 
       #The two arrays above are three columns of data for gnuplot.
       plot.data << Gnuplot::DataSet.new( [[x[0]], [y[0]]] ) do |ds|
@@ -155,105 +350,6 @@ class GraphService
     graph = Graph.new
     graph.svg = modified_svg
     graph
-
-  end
-
-  def self.qos_avg_time_to_submit_graph (provider, opts = {})
-    #things we're checking for in opts: :height, :width
-
-    height = 60 unless opts[:height].nil? ? nil : height = opts[:height].to_i
-    width = 100 unless  opts[:width].nil? ? nil : width  = opts[:width].to_i
-
-    graph = Graph.new
-    gp = gnuplot_open
-
-    Gnuplot::Plot.new( gp ) do |plot|
-      plot.terminal "svg size #{width},#{height}"
-      plot.arbitrary_lines << "unset xtics"
-      plot.arbitrary_lines << "unset x2tics"
-      plot.arbitrary_lines << "unset ytics"
-      plot.arbitrary_lines << "unset y2tics"
-      plot.set "bmargin","0"
-      plot.set "lmargin","1"
-      plot.set "rmargin","0"
-      plot.set "tmargin","0"
-
-      #FIXME: get data from DataService for the provider.
-      #For demo, plot a random walk for demo of graph display until we hook 
into DataService
-      #First build two equal-length arrays
-      x = (0..500).collect { |v| v.to_f }
-
-      walk = 0
-      y = x.collect { |v| rand > 0.5 ? walk = walk + 1 : walk = walk - 1 }
-      plot.set "yrange [-50:50]"
-
-      #This type of plot takes two equal length arrays of numbers as input.
-      plot.data << Gnuplot::DataSet.new( [x, y] ) do |ds|
-        ds.using = "1:2"
-        ds.with = "lines"
-        ds.notitle
-      end
-    end
-    gp.flush
-    gp.close_write
-    gp.read(nil,graph.svg)
-    gp.close_read
-    graph
-  end
-
-  def self.instances_by_provider_pie (opts = {})
-    #things we're checking for in opts: :height, :width
-
-    height = 200 unless opts[:height].nil? ? nil : height = opts[:height].to_i
-    width =  300 unless  opts[:width].nil? ? nil : width  = opts[:width].to_i
-
-    graph = Graph.new
-
-    mytheme = Scruffy::Themes::Keynote.new
-    mytheme.background = :white
-    mytheme.marker = :black #sets the label text color
-    mytheme.colors = %w(#00689a #00b0e0)
-
-    scruffy_graph = Scruffy::Graph.new({:theme => mytheme})
-    scruffy_graph.renderer = Scruffy::Renderers::Pie.new
-
-    pie_opts = {}
-    providers = Provider.all
-    providers.each do |provider|
-      running_instances = 0
-      provider.cloud_accounts.each do |account|
-        running_instances = running_instances + 
account.quota.running_instances if account.quota
-      end
-      if running_instances > 0
-        pie_opts[:"#{provider.name}"] = running_instances
-      end
-    end
-
-    scruffy_graph.add :pie, '', pie_opts
-
-    raw_svg = scruffy_graph.render :width => width, :height => height
-
-    xml = Nokogiri::XML(raw_svg)
-    svg = xml.css 'svg'
-    svg.each do |node|
-      node.set_attribute 'viewBox',"0 0 #{width} #{height}"
-    end
-
-    xml.root.traverse do |node|
-      if node.name == 'text'
-        if node.has_attribute? 'font-family'
-          node.set_attribute 'font-family','sans-serif'
-        end
-        if (node.has_attribute? 'font-size') && 
node.get_attribute('font-size').length > 0
-          size = node.get_attribute('font-size').to_f
-          size = size * 1.5
-          node.set_attribute 'font-size',size.to_s
-        end
-      end
-    end
-
-    graph.svg = xml.to_s
-    graph
   end
 
-end
+end
\ No newline at end of file
diff --git a/src/app/views/dashboard/summary.haml 
b/src/app/views/dashboard/summary.haml
index 66aedde..f3a21d3 100644
--- a/src/app/views/dashboard/summary.haml
+++ b/src/app/views/dashboard/summary.haml
@@ -60,7 +60,11 @@
         %div{ :style => "clear:both"}
       - @providers.each do |provider|
         .provider_service_quality_graph
-          = "<object data='" + url_for(:action => :provider_qos_graph, :id => 
provider.id, :width => 100, :height => 50) + "' type='image/svg+xml' />"
+          -end_time = Time.now
+          -start_time = end_time - (24 * 60 * 60)
+          -interval_length = 3600
+          -task_action = "create"
+          = "<object data='" + url_for(:action => 
:provider_qos_avg_time_to_submit_graph, :id => provider.id, :start_time => 
start_time, :end_time => end_time, :interval_length => interval_length, 
:task_action => task_action, :width => 100, :height => 50) + "' 
type='image/svg+xml' />"
         .provider_service_quality_graph_summary
           = provider.name
           <!-- FIXME 'good/poor/average service... -->
@@ -109,7 +113,7 @@
       .account_quota_usage_graph_summary
         = account.provider.name + ": " + account.name
       .account_quota_usage_current_graph
-        %object{ :data => url_for(:action => :account_quota_graph, :id => 
account.id, :width => 100, :height => 50), :type => 'image/svg+xml'}
+        %object{ :data => url_for(:action => :quota_usage_graph, 
:cloud_account_id => account.id, :resource_name => 
Quota::RESOURCE_RUNNING_INSTANCES, :width => 100, :height => 50), :type => 
'image/svg+xml'}
       <div style="clear: both;" />
 
 :javascript
-- 
1.7.1.1

_______________________________________________
deltacloud-devel mailing list
[email protected]
https://fedorahosted.org/mailman/listinfo/deltacloud-devel

Reply via email to