Changes between Initial Version and Version 1 of GEC22Agenda/LabWiki/ModuleE/DesignSetup


Ignore:
Timestamp:
03/09/15 11:41:35 (9 years ago)
Author:
divyashri.bhat@gmail.com
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • GEC22Agenda/LabWiki/ModuleE/DesignSetup

    v1 v1  
     1= Module E Design and Setup =
     2
     3== 1 Write Application for !OpenFlow Statistics Measurement ==
     4
     5=== 1.1 Get Flow Statistics you want to measure ===
     6
     7Define stats_reply in /root/learning-switch-copy.rb as follows. This file is the Trema controller script which we ran in ModuleC. For the purpose of this tutorial, the modified script has been downloaded into switch1 prior to this tutorial. [[BR]]
     8You can find this file in the node called switch1. If you need help with logging in to your nodes, please refer [http://groups.geni.net/geni/wiki/HowTo/LoginToNodes How To Login]. [[BR]]
     9
     10
     11{{{
     12#!ruby
     13def stats_reply (dpid, message)
     14    puts "[flow stats_reply #{@my_switch}]---------------------------------"
     15    byte_count = 0
     16    packet_count = 0
     17    flow_count = 0
     18    throughput = 0
     19    inst_throughput =0
     20    total_flow_count = message.stats.length
     21    if(total_flow_count != 0)
     22      message.stats.each do | flow_msg |
     23        # WARNING: This only works for the EXACT case of two actions. If we add more than two actions the flow monitoring
     24        # will break.
     25        flow_ip = flow_msg.match
     26          puts "This is the message #{flow_ip.nw_src}"
     27            flow_count = flow_count + 1
     28            byte_count += flow_msg.byte_count
     29            packet_count += flow_msg.packet_count
     30            if flow_msg.duration_sec + flow_msg.duration_nsec/1000000000 != 0
     31              throughput += flow_msg.byte_count/(flow_msg.duration_sec + flow_msg.duration_nsec/1000000000)
     32              file = File.open("/tmp/flowstats.out", "a")
     33                  file.puts "#{flow_ip.nw_src} #{flow_count.to_s} #{byte_count} #{packet_count} #{throughput} Bps"
     34                   file.close
     35            end
     36      end
     37      end
     38    @prev_byte_count = byte_count
     39  end
     40
     41}}}
     42
     43=== 1.2 Define Flow Statistics measurement points ===
     44
     45We now proceed to write the application which collects the measurement points defined in the controller code above. [[BR]]
     46The complete script is already pre-loaded into the node switch1 at /usr/local/bin/learn_ofcollect.rb. The steps provided here are for your reference.
     47
     48{{{
     49#!ruby
     50class MPThroughput < OML4R::MPBase
     51   name :ofthroughput
     52   param :srcaddr, :type => :string
     53   param :numflows, :type => :int64
     54   param :numbytes, :type => :int64
     55   param :numpacket, :type => :int64
     56   param :throughput, :type => :int64
     57   param :units,      :type => :string
     58end
     59}}}
     60
     61=== 1.3 Parse Measurement Fields ===
     62
     63{{{
     64#!ruby
     65def processOutput(output)
     66  column = output.split(" ")
     67      puts "Each line process"
     68      # Inject the measurements into OML
     69      MPThroughput.inject("#{column[0]}", column[1], column[2], column[3], column[4], "#{column[5]}")
     70end
     71}}}
     72
     73=== 1.4 Write application Script ===
     74{{{
     75#!ruby
     76!/usr/bin/env ruby
     77require 'rubygems'
     78require 'oml4r'
     79require 'file-tail'
     80APPNAME = "ofstats"
     81class MPThroughput < OML4R::MPBase
     82   name :ofthroughput
     83   param :srcaddr, :type => :string
     84   param :numflows, :type => :int64
     85   param :numbytes, :type => :int64
     86   param :numpacket, :type => :int64
     87   param :throughput, :type => :int64
     88   param :units,      :type => :string
     89end
     90class OFStatsWrapper
     91  def initialize(args)
     92     @addr = nil
     93     @if_num = ' '
     94     @trema_port = ' '
     95     @trema_path = ' '
     96     @verbose = true
     97     @numeric = ' '
     98     OML4R::init(args, :appName => "#{APPNAME}_wrapper", :domain => 'foo', :collect => 'file:-') {  |argParser|
     99       argParser.banner = "Reports OpenFlow stat measurements via OML\n\n"
     100       argParser.on("-f" , "--file_path ADDRESS", "Path where output is saved"){ |address| @addr = address }
     101       argParser.on("-i","--interface IFNUM","Interface number"){ |if_num| @if_num ="#{if_num.to_i()}" }
     102       argParser.on("-q", "--no-quiet ","Don't show of stats output on console"){ @verbose = false }
     103       argParser.on("-n", "--[no]-numeric ", "No attempt twill be made to look up symbolic names for host addresses"){ @numeric ='-n' }
     104    }
     105     unless @addr !=nil
     106      raise "You did not specify path of file (-p option)"
     107    end
     108end
     109class MyFile < File
     110  include File::Tail
     111end
     112def start()
     113                log = MyFile.new("#{@addr}")
     114                log.interval = @if_num
     115                log.backward(3)
     116                puts "#{@if_num}"
     117                log.tail { |line| print line
     118                processOutput(line)
     119                }
     120end
     121def processOutput(output)
     122  column = output.split(" ")
     123      puts "Each line process"
     124      # Inject the measurements into OML
     125      MPThroughput.inject("#{column[0]}", column[1], column[2], column[3], column[4], "#{column[5]}")
     126end
     127end
     128begin
     129  app = OFStatsWrapper.new(ARGV)
     130  app.start()
     131  rescue SystemExit
     132  rescue SignalException
     133     puts "OFWrapper stopped."
     134  rescue Exception => ex
     135  puts "Error - When executing the wrapper application!"
     136  puts "Error - Type: #{ex.class}"
     137  puts "Error - Message: #{ex}\n\n"
     138  # Uncomment the next line to get more info on errors
     139  # puts "Trace - #{ex.backtrace.join("\n\t")}"
     140end
     141OML4R::close()
     142# Local Variables:
     143# mode:ruby
     144# End:
     145# vim: ft=ruby:sw=2
     146}}}
     147
     148== 2. Write OEDL Script to run in !LabWiki ==
     149
     150This script is used to orchestrate the OML application we just wrote. It is pre-loaded into your !LabWiki directory as GEC20_flowstatistics.oedl. [[BR]]
     151The steps provided here are for your reference.
     152
     153=== 2.1 Define Resource name ===
     154
     155Here you will identify the nodes you used for the tutorial as a combination of the <node-slicename>
     156
     157
     158{{{
     159#!ruby
     160defProperty('source1', "switch1-rspecforMax", "ID of a resource")
     161defProperty('source2', "switch2-rspecforMax", "ID of a resource")
     162defProperty('source3', "switch1-rspecforMax", "ID of a resource")
     163defProperty('theSender1', "nodeb-rspecforMax", "ID of a resource")
     164defProperty('theSender2', "nodec-rspecforMax", "ID of a resource")
     165defProperty('theSender3', "noded-rspecforMax", "ID of a resource")
     166defProperty('theSender4', "nodec-rspecforMax", "ID of a resource")
     167defProperty('theSender5', "nodee-rspecforMax", "ID of a resource")
     168defProperty('theReceiver', "nodef-rspecforMax", "ID of a resource")
     169}}}
     170
     171=== 2.2 Specify the location where Flow Statistics will be stored ===
     172
     173{{{
     174#!ruby
     175defProperty('pathfile', "/tmp/flowstats.out", "Path to file")
     176}}}
     177
     178=== 2.3 Define the Application created in Step 1) in OEDL ===
     179
     180
     181{{{
     182#!ruby
     183defApplication('ofstats') do |app|
     184  app.description = 'Simple Definition for the of-collect application'
     185  # Define the path to the binary executable for this application
     186  app.binary_path = '/usr/local/bin/learn_ofcollect.rb'
     187  app.defProperty('target', 'Address to output file', '-f', {:type => :string})
     188  app.defProperty("interval","Interval",'-i', {:type => :string})
     189  app.defMeasurement('wrapper_ofthroughput') do |m|
     190    m.defMetric(':srcaddr', :string)
     191    m.defMetric('throughput',:int64)
     192  end
     193end
     194}}}
     195
     196=== 2.4 Create Node Group with Application ===
     197
     198
     199{{{
     200#!ruby
     201defGroup('Source3', property.source1) do |node|
     202  node.addApplication("ofstats") do |app|
     203    app.setProperty('target', property.pathfile)
     204    app.setProperty('interval', property.intervalcol)
     205    app.measure('wrapper_ofthroughput', :samples => 1)
     206  end
     207end
     208}}}
     209
     210=== 2.5 Define parameters for graphs ===
     211
     212{{{
     213#!ruby
     214defGraph 'Throughput' do |g|
     215  g.ms('wrapper_ofthroughput').select(:oml_ts_client, :throughput, :srcaddr)
     216  g.caption "Throughput of Flows"
     217  g.type 'line_chart3'
     218  g.mapping :x_axis => :oml_ts_client, :y_axis => :throughput, :group_by => :srcaddr
     219  g.xaxis :legend => 'oml_ts'
     220  g.yaxis :legend => 'Throughput', :ticks => {:format => 's'}
     221end
     222
     223}}}
     224
     225
     226
     227= [wiki:GEC21Agenda/LabWiki/ModuleE/Execute Next: Run Experiment] =
     228= [wiki:GEC21Agenda/LabWiki/ModuleE Module E Introduction] =