#===============================================================#
#                                                               #
# $ID$                                                          #
#                                                               #
# perf_vol_latency.pl                                           #
#                                                               #
# Copyright (c) 2009 NetApp, Inc. All rights reserved.          #
# Specifications subject to change without notice.              #
#                                                               #
# This Sample code is supported from DataFabric Manager 3.7.1   #
# onwards.                                                      #
# However few of the functionalities of the sample code may     #
# work on older versions of DataFabric Manager.                 #
#===============================================================#

require 5.6.1;
use strict;
use warnings;

use lib '../../../../../../../lib/perl/NetApp';
use NaServer;
use NaElement;

# Command line arguments
my $args = scalar @ARGV;
my $dfm = shift;
my $user = shift;
my $pw  = shift;
my $aggr_name = shift;

my @time_arr;
my @data_arr;
my @vol_arr;

sub main() {
	# check for valid number of parameters
	if ($args != 4)	{
		die print_help();
	}

	my $perf_out = invoke_perf_zapi();
	extract_perf_counter_data($perf_out);
	print_output();

	exit 0;
}

sub invoke_perf_zapi() {
	# Initialize server context
	my $server_ctx = NaServer->new ($dfm, 1, 0);
	$server_ctx->set_transport_type("HTTP");
	$server_ctx->set_style("LOGIN");
	$server_ctx->set_admin_user($user, $pw);
	$server_ctx->set_server_type("DFM");
	$server_ctx->set_port(8088);

	# Create API request
	my $perf_in = NaElement->new("perf-get-counter-data");
	$perf_in->child_add_string("duration", 6000);
	$perf_in->child_add_string("number-samples", 50);
	$perf_in->child_add_string("time-consolidation-method", "average");

	my $instance_info = NaElement->new("instance-counter-info");
	$instance_info->child_add_string("object-name-or-id", $aggr_name);

	my $counter_info = NaElement->new("counter-info");
	my $perf_obj_ctr = NaElement->new("perf-object-counter");
	$perf_obj_ctr->child_add_string("object-type", "volume");
	$perf_obj_ctr->child_add_string("counter-name", "avg_latency");

	$counter_info->child_add($perf_obj_ctr);
	$instance_info->child_add($counter_info);
	$perf_in->child_add($instance_info);

	# Invoke API
	my $perf_out = $server_ctx->invoke_elem($perf_in);
	if($perf_out->results_status() eq "failed") {
		print($perf_out->results_reason() ."\n");
		exit(-2);
	}

	return $perf_out;
}

sub extract_perf_counter_data() {
	my $perf_out = $_[0];

	my @counter_arr;
	my $gen_time_arr = 1;
	my $rec;
	my $i = 0;

	my $instance = $perf_out->child_get("perf-instances");
	my @instances = $instance->children_get("perf-instance-counter-data");
	foreach $rec (@instances){
		my $vol_name = $rec->child_get_string("instance-name");
		if (defined $vol_name) {
			push (@vol_arr, $vol_name);
		}

		my $counters = $rec->child_get("counters");
		my @perf_cnt_data = $counters->children_get("perf-counter-data");
		my $rec1;

		foreach $rec1 (@perf_cnt_data) {
			my $counter_str = $rec1->child_get_string("counter-data");
			# counter-data is in time1:val1,time2:val2,..,timen:valn format.
			# Extract data from this format.
			@counter_arr = split (/,/, $counter_str);
			my $time_val;

			foreach $time_val (@counter_arr) {
				my @time_val_arr = split(/:/, $time_val);
				if($gen_time_arr) {
					$time_arr[$i] = localtime($time_val_arr[0]);
				}
				$data_arr[$i++] = $time_val_arr[1];
			}
			$gen_time_arr = 0;
		}
	}
}

sub print_output() {
	my $vol_name;
	my $j = 0;
	my $k = 0;
	my $iter = 0;
	my $nsamples = scalar(@time_arr);
	my $data_arr_len = scalar(@data_arr);

	print "Time\t";
	foreach $vol_name (@vol_arr) {
		print $vol_name . "\t";
	}
	print "\n";

	for($iter=0; $iter<$nsamples; $iter++) {
		print $time_arr[$iter] . "\t";
		for($k=$iter; $k<$data_arr_len; $k=$k+$nsamples) {
			print $data_arr[$k] . "\t";
		}
		print "\n";
	}
}

sub print_help() {
	print "\nCommand:\n";
	print "perf_vol_latency.pl <dfm> <user> <password> <aggr-name>\n";
	print "<dfm>       -- DFM Server name\n";
	print "<user>      -- User name\n";
	print "<password>  -- Password\n";
	print "<aggr-name> -- Name of the aggregate in format storage:aggrName\n";
	print "-" x 80 . "\n";

	print "This sample code prints average latency of all the volumes \n";
	print "present in the given aggregate. This data can be used to \n";
	print "generate distribution chart for volume average latency. \n";
	print "To generate the graph, redirect output of this sample code to\n";
	print "an Excel sheet.\n";

	exit (-1);
}

#Invoke routine
main();

#=========================== POD ============================#

=head1 NAME

  perf_vol_latency.pl - Get average latency of all volumes present in an
	aggregate.


=head1 SYNOPSIS

  perf_vol_latency.pl <dfm> <user> <password> <aggr-name>

=head1 ARGUMENTS

  <dfm>
  DFM Server name.

  <user>
  User name.

  <password>
  Password.

  <aggr-name>
  Name of the aggregate in format storage:aggrName.

=head1 SEE ALSO

  NaElement.pm, NaServer.pm

=head1 COPYRIGHT

 Copyright (c) 2009 NetApp, Inc. All rights reserved.
 Specifications subject to change without notice.

=cut
