wiki:GENIFIRE/Labwiki/Part2a/DesignSetup

Version 1 (modified by divyashri.bhat@gmail.com, 10 years ago) (diff)

--

Part 2 Design and Setup

1 Write Application for OpenFlow Statistics Measurement

1.1 Get Flow Statistics you want to measure

Define stats_reply in /root/learning-switch-copy.rb as follows

def stats_reply (dpid, message)
    puts "[flow stats_reply #{@my_switch}]---------------------------------"
    byte_count = 0
    packet_count = 0
    flow_count = 0
    throughput = 0
    inst_throughput =0
    total_flow_count = message.stats.length
    if(total_flow_count != 0)
      message.stats.each do | flow_msg |
        # WARNING: This only works for the EXACT case of two actions. If we add more than two actions the flow monitoring
        # will break.
        flow_ip = flow_msg.match
          puts "This is the message #{flow_ip.nw_src}"
            flow_count = flow_count + 1
            byte_count += flow_msg.byte_count
            packet_count += flow_msg.packet_count
            if flow_msg.duration_sec + flow_msg.duration_nsec/1000000000 != 0
              throughput += flow_msg.byte_count/(flow_msg.duration_sec + flow_msg.duration_nsec/1000000000)
              file = File.open("/tmp/flowstats.out", "a")
                  file.puts "#{flow_ip.nw_src} #{flow_count.to_s} #{byte_count} #{packet_count} #{throughput} Bps"
                   file.close
            end
      end
      end
    @prev_byte_count = byte_count
  end

1.2 Define Flow Statistics measurement points

class MPThroughput < OML4R::MPBase
   name :ofthroughput
   param :srcaddr, :type => :string
   param :numflows, :type => :int64
   param :numbytes, :type => :int64
   param :numpacket, :type => :int64
   param :throughput, :type => :int64
   param :units,      :type => :string
end

1.3 Parse Measurement Fields

def processOutput(output)
  column = output.split(" ")
      puts "Each line process"
      # Inject the measurements into OML
      MPThroughput.inject("#{column[0]}", column[1], column[2], column[3], column[4], "#{column[5]}")
end

1.4 Write application Script

!/usr/bin/env ruby
require 'rubygems'
require 'oml4r'
require 'file-tail'
APPNAME = "ofstats"
class MPThroughput < OML4R::MPBase
   name :ofthroughput
   param :srcaddr, :type => :string
   param :numflows, :type => :int64
   param :numbytes, :type => :int64
   param :numpacket, :type => :int64
   param :throughput, :type => :int64
   param :units,      :type => :string
end
class OFStatsWrapper
  def initialize(args)
     @addr = nil
     @if_num = ' '
     @trema_port = ' '
     @trema_path = ' '
     @verbose = true
     @numeric = ' '
     OML4R::init(args, :appName => "#{APPNAME}_wrapper", :domain => 'foo', :collect => 'file:-') {  |argParser|
       argParser.banner = "Reports OpenFlow stat measurements via OML\n\n"
       argParser.on("-f" , "--file_path ADDRESS", "Path where output is saved"){ |address| @addr = address }
       argParser.on("-i","--interface IFNUM","Interface number"){ |if_num| @if_num ="#{if_num.to_i()}" }
       argParser.on("-q", "--no-quiet ","Don't show of stats output on console"){ @verbose = false }
       argParser.on("-n", "--[no]-numeric ", "No attempt twill be made to look up symbolic names for host addresses"){ @numeric ='-n' }
    }
     unless @addr !=nil
      raise "You did not specify path of file (-p option)"
    end
end
class MyFile < File
  include File::Tail
end
def start()
                log = MyFile.new("#{@addr}")
                log.interval = @if_num
                log.backward(3)
                puts "#{@if_num}"
                log.tail { |line| print line
                processOutput(line)
                }
end
def processOutput(output)
  column = output.split(" ")
      puts "Each line process"
      # Inject the measurements into OML
      MPThroughput.inject("#{column[0]}", column[1], column[2], column[3], column[4], "#{column[5]}")
end
end
begin
  app = OFStatsWrapper.new(ARGV)
  app.start()
  rescue SystemExit
  rescue SignalException
     puts "OFWrapper stopped."
  rescue Exception => ex
  puts "Error - When executing the wrapper application!"
  puts "Error - Type: #{ex.class}"
  puts "Error - Message: #{ex}\n\n"
  # Uncomment the next line to get more info on errors
  # puts "Trace - #{ex.backtrace.join("\n\t")}"
end
OML4R::close()
# Local Variables:
# mode:ruby
# End:
# vim: ft=ruby:sw=2

2. Write OEDL Script to run in LabWiki

2.1 Define Resource name

Here you will identify the nodes you used for the tutorial as a combination of the <node-slicename>

defProperty('source1', "switch1-rspecforMax", "ID of a resource")
defProperty('source2', "switch2-rspecforMax", "ID of a resource")
defProperty('source3', "switch1-rspecforMax", "ID of a resource")
defProperty('theSender1', "nodeb-rspecforMax", "ID of a resource")
defProperty('theSender2', "nodec-rspecforMax", "ID of a resource")
defProperty('theSender3', "noded-rspecforMax", "ID of a resource")
defProperty('theSender4', "nodec-rspecforMax", "ID of a resource")
defProperty('theSender5', "nodee-rspecforMax", "ID of a resource")
defProperty('theReceiver', "nodef-rspecforMax", "ID of a resource")

2.2 Specify the location where Flow Statistics will be stored

defProperty('pathfile', "/tmp/flowstats.out", "Path to file")

2.3 Define the Application created in Step 1) in OEDL

defApplication('ofstats') do |app|
  app.description = 'Simple Definition for the of-collect application'
  # Define the path to the binary executable for this application
  app.binary_path = '/usr/local/bin/learn_ofcollect.rb'
  app.defProperty('target', 'Address to output file', '-f', {:type => :string})
  app.defProperty("interval","Interval",'-i', {:type => :string})
  app.defMeasurement('wrapper_ofthroughput') do |m|
    m.defMetric(':srcaddr', :string)
    m.defMetric('throughput',:int64)
  end
end

2.4 Create Node Group with Application

defGroup('Source3', property.source1) do |node|
  node.addApplication("ofstats") do |app|
    app.setProperty('target', property.pathfile)
    app.setProperty('interval', property.intervalcol)
    app.measure('wrapper_ofthroughput', :samples => 1)
  end
end

2.5 Define parameters for graphs

defGraph 'Throughput' do |g|
  g.ms('wrapper_ofthroughput').select(:oml_ts_client, :throughput, :srcaddr) 
  g.caption "Throughput of Flows"
  g.type 'line_chart3'
  g.mapping :x_axis => :oml_ts_client, :y_axis => :throughput, :group_by => :srcaddr
  g.xaxis :legend => 'oml_ts'
  g.yaxis :legend => 'Throughput', :ticks => {:format => 's'}
end

Next: Run Experiment