perfsonar-dev - [pS-dev] [GEANT/SA2/SA2T3-OPPD] r619 - in branches/perfsonar-oppd-new-architect: bin etc/oppd-mdm/oppd.d lib lib/perfSONAR lib/perfSONAR/DataStruct lib/perfSONAR/MP tools/perfSONAR-client
Subject: perfsonar development work
List archive
[pS-dev] [GEANT/SA2/SA2T3-OPPD] r619 - in branches/perfsonar-oppd-new-architect: bin etc/oppd-mdm/oppd.d lib lib/perfSONAR lib/perfSONAR/DataStruct lib/perfSONAR/MP tools/perfSONAR-client
Chronological Thread
- From:
- To:
- Subject: [pS-dev] [GEANT/SA2/SA2T3-OPPD] r619 - in branches/perfsonar-oppd-new-architect: bin etc/oppd-mdm/oppd.d lib lib/perfSONAR lib/perfSONAR/DataStruct lib/perfSONAR/MP tools/perfSONAR-client
- Date: Fri, 30 Jul 2010 08:13:26 +0100
Author: dfn.calim
Date: 2010-07-30 08:13:26 +0100 (Fri, 30 Jul 2010)
New Revision: 619
Added:
branches/perfsonar-oppd-new-architect/etc/oppd-mdm/oppd.d/owamp.conf
branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct.pm
branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct/
branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct/BWCTL.pm
branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct/NMWG.pm
Modified:
branches/perfsonar-oppd-new-architect/bin/oppd.pl
branches/perfsonar-oppd-new-architect/lib/perfSONAR.pm
branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP.pm
branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP/BWCTL.pm
branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP/OWAMP.pm
branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/bwctl-iperf-req2.xml
branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/bwctl-test
branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/owamp-ind2-req.xml
Log:
Add new files
Modified: branches/perfsonar-oppd-new-architect/bin/oppd.pl
===================================================================
--- branches/perfsonar-oppd-new-architect/bin/oppd.pl 2010-07-30 06:43:31
UTC (rev 618)
+++ branches/perfsonar-oppd-new-architect/bin/oppd.pl 2010-07-30 07:13:26
UTC (rev 619)
@@ -63,6 +63,12 @@
# }
#}
+
+#Added new
+use Log::Log4perl qw(:easy);
+
+
+
# Modules for this daemon:
use File::Spec;
use Socket;
@@ -77,6 +83,7 @@
use perfSONAR::Echo;
use perfSONAR::SOAP::Message;
use perfSONAR::Client::LS;
+use perfSONAR::DataStruct;
use vars qw($VERSION);
$VERSION = 0.51;
@@ -124,7 +131,7 @@
$ssl_verify_client, $ssl_trusted_webserver_cn,
);
-my %services;
+our %services;
my %messages;
my %lsKeys;
@@ -421,6 +428,19 @@
);
}
+
+#Add Log4perl
+my $logger;
+my %logger_opts = (
+ level => $DEBUG,
+ layout => '%d (%P) %p> %F{1}:%L %M - %m%n',
+);
+$logger_opts{file} = $logfile;
+Log::Log4perl->easy_init( \%logger_opts );
+$logger = get_logger( "perfsonar-oppd" );
+
+
+
# More flexible die:
# Put error into Log and afterwards die with same message.
# Also handy, because in the following code $@ is undef in die call:
@@ -468,7 +488,7 @@
foreach my $service (keys %services){
my $module = $services{$service}->{module};
- eval "require perfSONAR::$module";
+ eval "use perfSONAR::$module";
if ($@){
die "Error loading module perfSONAR::$module:
$@\n";
}
@@ -800,17 +820,30 @@
$conn->timeout(0) unless($ssl);
my $response = new HTTP::Response;
eval {
+ #TODO At the moment we only get NMWG messages
+ #but we need more undependency from it
my $soap_message =
perfSONAR::SOAP::Message->from_http_request($request);
-
+
+ #Use the new DataStruct
+ #At the moment NMWG parse to DS
my $nmwg_message = NMWG::Message->new( ($soap_message->body)[0] );
#TODO: Auth
if ($auth){
perfSONAR::Auth::authenticate($soap_message, $nmwg_message, $as_url);
}
- my $nmwg_response = perfSONAR->handle_request(
- $soap_message->uri, $nmwg_message
- );
+
+ #Create a DataStruct
+ my $ds = perfSONAR::DataStruct->new($soap_message->uri,
$nmwg_message);
+ if ($ds->{ERROROCCUR}){
+ #Do here response on error
+ $log->error("A error occured in creating data struct");
+ }
+
+ $ds->{SERVICES} = \%services;
+ #Run $ds
+ perfSONAR->handle_request($ds);
+ my $nmwg_response = $ds->{REQUESTMSG};
#TODO $nmwg_message <-> $nmwg_response? clone?
#TODO what about header?
$soap_message->body($nmwg_response->as_dom()->documentElement);
Added: branches/perfsonar-oppd-new-architect/etc/oppd-mdm/oppd.d/owamp.conf
===================================================================
--- branches/perfsonar-oppd-new-architect/etc/oppd-mdm/oppd.d/owamp.conf
(rev 0)
+++ branches/perfsonar-oppd-new-architect/etc/oppd-mdm/oppd.d/owamp.conf
2010-07-30 07:13:26 UTC (rev 619)
@@ -0,0 +1,45 @@
+#
+# OWAMP MP configuration for MDM client machines
+#
+
+<service MP/OWAMP>
+
+ #
+ # Necessary parameters for module initialisation
+ #
+ module MP::OWAMP # Name of module to load
+ servicetype MP # Service type: MP or MA
+
+ #
+ # Name, description, and keyword will be reported to Lookup Server
+ #
+ name "OWAMP Measurement Point"
+ description "Measurement Point for doing on-demand OWAMP tests"
+ keyword "MDM"
+
+ #
+ # Further parameters
+ #
+ metric "bandwidth"
+ # Measurement metric(s). More than one element definition possible.
+ tool "owping" # Tool name
+
+ #
+ # Module parameters
+ #
+ <module_param>
+
+ command "owping"
+ # Command to execute e.g. "/usr/bin/owping" or "/bin/owping".
+ # Omitting path searches $PATH.
+
+ #
+ # Store functionality
+ #
+ store off # Enable/disable store functionality
+ store_url "http://www.mySQL-MA:8090"
+ # URL of a MA service to sent the results of measurements to
+
+ </module_param>
+
+</service MP/OWAMP>
Added: branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct/BWCTL.pm
===================================================================
--- branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct/BWCTL.pm
(rev 0)
+++ branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct/BWCTL.pm
2010-07-30 07:13:26 UTC (rev 619)
@@ -0,0 +1,45 @@
+package perfSONAR::DataStruct::BWCTL;
+
+use strict;
+use warnings;
+
+
+#DEBUG
+use Data::Dumper;
+#DEBUG
+
+use version;
+our $VERSION = 0.52;
+
+use Log::Log4perl qw(get_logger);
+
+=head1 NAME
+
+perfSONAR::DataStruct::BWCTL
+
+=head1 DESCRIPTION
+
+This class is responsible to convert request parameters to a datastruct
format.
+This can be used to call bwctl from commandline. Measurement is not called
from this class.
+This class converts only data.
+
+=head1 Methods
+
+
+=head2 new({})
+
+The constructorneeds no parameter.
+
+=cut
+
+sub new{
+ my $class = shift;
+ my $self = {};
+ bless $self, $class;
+
+ $self->{LOGGER} = get_logger( "perfSONAR::DataStruct::BWCTL" );
+ return $self;
+}
+
+
+1;
Added: branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct/NMWG.pm
===================================================================
--- branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct/NMWG.pm
(rev 0)
+++ branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct/NMWG.pm
2010-07-30 07:13:26 UTC (rev 619)
@@ -0,0 +1,403 @@
+package perfSONAR::DataStruct::NMWG;
+
+=head1 NAME
+
+perfSONAR::DataStruct::NMWG
+
+=head1 DESCRIPTION
+
+This is the NMWG DataStruct. Use this to convert NMWG messages to the oppd
DataStruct format.To call this
+create a object calling the new constructor. For details look at the
description of the new method.
+=head1 Methods
+
+=cut
+
+#TODOS
+#$ds->{REQUESTMSG}->return_result_code check retrn lines
+
+use strict;
+use warnings;
+
+
+#DEBUG
+use Data::Dumper;
+#DEBUG
+
+use version;
+our $VERSION = 0.52;
+
+#Here are everything to use
+use Readonly;
+use Log::Log4perl qw(get_logger);
+use Carp;
+
+Readonly::Scalar our $CLASSPATH => "perfSONAR::DataStruct::NMWG";
+
+=head2 new({})
+
+The constructor.
+
+=cut
+
+sub new{
+ my ($class) = @_;
+ my $self = {};
+ $self->{LOGGER} = get_logger( $CLASSPATH );
+
+ push @{$self->{"supportedEventtypes"}},
+
+ ("bwctl",
+ "http://ggf.org/ns/nmwg/tools/bwctl/2.0/",
+ "http://ggf.org/ns/nmwg/tools/iperf/2.0/",
+ "owamp",
+ "bwctl"
+ );
+
+ $self->{"known_parameters"} = {
+ src => 1,
+ dst => 1,
+ interval => 1,
+ duration => 1,
+ windowSize => 1,
+ protocol => 1,
+ bufferSize => 1,
+ bandwidth => 1,
+ login => 1,
+ password => 1,
+ TOS => 1,
+
+ #more owamp
+ count => 1,
+ timeout => 1,
+ size => 1,
+ units => 1,
+ send_schedule => 1,
+ percentile => 1,
+ one_way => 1,
+ DSCP => 1,
+ PHB => 1,
+ enddelay => 1,
+ startdelay => 1,
+ bucket_width => 1,
+ intermediates => 1,
+ output => 1,
+ port => 1,
+ portrange => 1,
+ individual => 1, #TODO check this parameter
+ };
+
+ $self->{"unsupported_parameters"} = {
+ advisoryWindowsize => 1,
+ scheduleInterval => 1,
+ numberOfTests => 1,
+ latest => 1,
+ alpha => 1,
+
+ #owamp specific
+ save_summary => 1,
+ directory => 1,
+ no_summary => 1,
+ };
+
+
+ bless $self, $class;
+ return $self;
+}
+
+=head2 nmwg2ds({})
+
+Converts a nmwg message to a data struct. As parameter is a NMWG::Message is
needed.
+
+=cut
+sub nmwg2ds{
+ my ($self, $nmwg,$ds) = @_;
+ my $messagetype = $nmwg->get_message_type();
+
+ $ds->{DSTYPE} = 'NMWG';
+ $ds->{REQUESTMSG} = $nmwg;
+
+ #Check messagetype
+ if (!$self->NMWGcheckMessagetype($messagetype,$ds)){
+ $ds->{ERROROCCUR} = 1;
+ return;
+ }
+
+ ($ds->{SERVICE} = $ds->{URI}) =~ s/^.*\/services\///;
+ $ds->{SERVICE} =~ s/\/$//;
+ $self->{LOGGER}->info("Requested service: $ds->{SERVICE}");
+ if (!$ds->{SERVICE}){
+ croak "Service $self->{SERVICE} not known!";
+ }
+
+ my @module_ets = @{$self->{"supportedEventtypes"}};
+
+ #create {"dataIDs"} and {"metadataIDs"}
+ #hashes from document
+ my ($errorstring, $metaid) = $ds->{REQUESTMSG}->parse_all;
+ if($errorstring){
+ $self->{LOGGER}->info($errorstring);
+ $ds->{REQUESTMSG}->return_result_code("error.common.parse_error",
"$errorstring", $metaid);
+ $self->{ERROROCCUR} = 1;
+ return;
+ }
+
+ #check if at least one metadata and one data element is in message
+ if(!($ds->{REQUESTMSG}->{"metadataIDs"})){
+ $errorstring = "No metadata definition in message.";
+ $self->{LOGGER}->info($errorstring);
+ $ds->{REQUESTMSG}->return_result_code("error.common.message",
"$errorstring", "message");
+ $ds->{ERROROCCUR} = 1;
+ return;
+ }
+ if(!(defined $ds->{REQUESTMSG}->{"dataIDs"})){
+ $errorstring = "No data trigger in message.";
+ $self->{LOGGER}->info($errorstring);
+ $ds->{REQUESTMSG}->return_result_code("error.common.message",
"$errorstring", "message");
+ $ds->{ERROROCCUR} = 1;
+ return;
+ }
+
+ #do some checks on metadata content
+ foreach my $meta (keys %{$ds->{REQUESTMSG}->{"metadataIDs"}}){
+ #check for unknown eventTypes
+ my $et = $ds->{REQUESTMSG}->{"metadataIDs"}{$meta}{"eventType"};
+ if ($et =~ /admin/){ #dispatch to Echo module
+ $ds->{RETURNMSG} =
perfSONAR::Echo::handle_echo_request($ds->{REQUESTMSG}, $ds->{SERVICE});
+ $ds->{ERROROCCUR} = 1;
+ return;
+ #return $reqmsg;
+ }
+
+ my $found = undef;
+ #foreach my $sup_et (@{$services{$service}{"eventtype"}}){
+ foreach my $sup_et (@module_ets){
+ next unless ($sup_et =~ /$et/);
+ $found = 1;
+ }
+ #TODO check of evebttypes
+ if (!defined $found){
+ my $errorstring = "Unknown eventType: $et";
+ $self->{LOGGER}->info($errorstring);
+
$ds->{REQUESTMSG}->return_result_code("error.common.parse_error",
$errorstring, $meta);
+ }
+ #check times
+ my $startTime =
$ds->{REQUESTMSG}->{"metadataIDs"}{$meta}{"startTime"};
+ my $endTime = $ds->{REQUESTMSG}->{"metadataIDs"}{$meta}{"endTime"};
+ if ($endTime && $startTime && ($endTime < $startTime)){
+ my $errorstring = "Illegal time duration specified: " .
+ "$endTime is later than $startTime!";
+ $self->{LOGGER}->info($errorstring);
+
$ds->{REQUESTMSG}->return_result_code("error.common.parse_error",
$errorstring, $meta);
+ $ds->{ERROROCCUR} = 1;
+ return;
+ }
+ } #End forech
+
+ #TODO This is a big block. Split it in more functions
+ #add metadata parameters to data hashes
+ ($errorstring, $metaid) = $ds->{REQUESTMSG}->concatenate_params;
+ if ($errorstring){
+ $self->{LOGGER}->info($errorstring);
+ $ds->{REQUESTMSG}->return_result_code("error.common.parse_error",
"$errorstring", $metaid);
+ $ds->{ERROROCCUR} = 1;
+ return;
+ }
+
+ #Prepare for each dataID a measurement
+ #Getparameters
+ my %parameters;
+ my $params = {};
+ foreach my $dataid (keys %{$ds->{REQUESTMSG}->{"dataIDs"}}){
+ my $datablock = $ds->{REQUESTMSG}->{"dataIDs"}{$dataid};
+ foreach my $key (keys %{$datablock}){ #get eventtypes
+ next if ($key eq "node" || $key eq "metaref" ); #Get only evebttypes
+ foreach my $k (keys %{$datablock->{$key}}){
+ if (!defined $parameters{$k}){
+ if ($k eq "src" || $k eq "dst"){
+ $parameters{$k} = $datablock->{$key}{$k}{"value"};
+ } else {
+ $parameters{$k} = $datablock->{$key}->{$k};
+ }
+ }# End if (!defined $parameters
+ }#End foreach my $k
+ }# End foreach my $key
+
+ my $error = $self->checkParams(%parameters);
+ if ($error){
+ $self->{LOGGER}->info($error);
+ $ds->{REQUESTMSG}->return_result_code("ERROR",
$ds->{SERVICE},$error, $ds->{REQUESTMSG}->{"dataIDs"}{$dataid}{"metaref"});
+ $ds->{ERROROCCUR} = 1;
+ return;
+ }#Endf ($error)
+
+ #Checks for parameters ok add to parameterlist
+ #push @paramlist,%parameters;
+ $params->{$dataid} = \%parameters;
+
+ #do selftests
+ #TODO test this part
+ if($messagetype =~ /EchoResponse/){
+ my @tests = ("bwctl_command_test",
+ "bwctl_exec_test",
+ "bwctld_running_test",
+ "ntpd_running_test");
+ foreach my $test (@tests){
+ $self->{LOGGER}->debug("Perform test: $test");
+ my ($message, $status) = $self->$test; #TODO what means
self->$test
+ my $et =
"http://schemas.perfsonar.net/tools/admin/selftest/MP/BWCTL/$test/$status/1.0";
+ $ds->return_result_code(
+ $et, $message,
$ds->{REQUESTMSG}->{"dataIDs"}{$dataid}{"metaref"}, $test);
+ }# Emd foreach my $test
+ return #TODO what should here returned
+ }#End if($messagetype =~
+
+ #TODO test this part
+ my @datalines;
+ if ($messagetype eq "MetadataKeyResponse") {
+ my %data_hash;
+ my $key;
+ $key .= "src,$parameters{src}" if $parameters{"src"};
+ $key .= ",dst,$parameters{dst}" if $parameters{"dst"};
+ $key .= ",int,$parameters{interval}" if $parameters{"interval"};
+ $key .= ",dur,$parameters{duration}" if $parameters{"duration"};
+ $key .= ",win,$parameters{windowSize}" if
$parameters{"windowSize"};
+ $key .= ",pro,$parameters{protocol}" if $parameters{"protocol"};
+ $key .= ",buf,$parameters{bufferSize}" if
$parameters{"bufferSize"};
+ $key .= ",ban,$parameters{bandwidth}" if
$parameters{"bandwidth"};
+ $key .= ",tos,$parameters{TOS}" if $parameters{"TOS"};
+
+ $data_hash{"MetadataKey"} = "$key";
+ push @datalines, \%data_hash;
+ $ds->{REQUESTMSG}->set_data($dataid, @datalines);
+ return 1; #TODO What should here returned
+ }#End if ($messagetype eq "Metad
+
+ }# End foreach my $dataid
+
+ $ds->{PARAMS} = $params;
+
+}
+
+
+
+
+=head2 NMWGcheckMessagetype({})
+
+Checks the message type of a NMWG message. As parameter give the messagetype
attribute of the NMWG message.
+
+=cut
+sub NMWGcheckMessagetype{
+
+ my ($self,$messagetype,$ds) = @_;
+ if ($messagetype eq "ErrorResponse"){ #error from authentication!
+ $ds->{RETURNMSG} = $ds->{REQUESTMSG};
+ return -1;
+ }
+ if ($messagetype eq "AuthNEERequest"){ #authorization rquest to dummy AS
+ require perfSONAR::AS;
+ $ds->{RETURNMSG} = perfSONAR::AS::dummy();
+ return -1;
+ }
+ if ($messagetype eq "SetupDataRequest"){
+ $ds->{REQUESTMSG}->set_message_type("SetupDataResponse");
+ return 1;
+ }
+ elsif ($messagetype eq "MeasurementRequest"){
+ $ds->{REQUESTMSG}->set_message_type("MeasurementResponse");
+ return 1;
+ }
+ elsif ($messagetype eq "MetadataKeyRequest"){
+ $ds->{REQUESTMSG}->set_message_type("MetadataKeyResponse");
+ return 1;
+ }
+ elsif ($messagetype =~ /EchoRequest/){
+ $ds->{REQUESTMSG}->set_message_type("EchoResponse");
+ return 1;
+ }
+ else {
+ my $errorstring = "Unknown messagetype: $messagetype";
+ $self->{LOGGER}->info($errorstring);
+ $ds->{REQUESTMSG}->set_message_type("ErrorResponse");
+
$self->{REQUESTMSG}->return_result_code("error.common.action_not_supported",
"$errorstring", "message");
+ $ds->{RETURNMSG} = $ds->{REQUESTMSG};
+ return 1;
+ }
+}
+
+=head2 checkParams()
+
+Checks the nmwg parameters.As value the method needs a hash of parameters
which are defined by the dataIds. On success it do nothing.
+Otherwise it returns an error string
+
+=cut
+#TODO return error message if unknown parameters to client
+sub checkParams{
+ my ($self,%parameters) = @_;
+ my (@unknown,@unsupported, $error);
+ #$self->{LOGGER}->info(Dumper(%parameters));
+ foreach my $par (keys %parameters){
+ next if ($par eq "ns_prefix" ||
+ $par eq "param_ns_prefix" ||
+ $par eq "subject_ns_prefix" ||
+ $par eq "subject_ns_uri" ||
+ $par eq "param_ns_uri" ||
+ $par eq "parameter_ID" ||
+ $par eq "metaID" ||
+ $par eq "address" ||
+ $par eq "metadatakey");
+ next if exists $self->{"known_parameters"}{$par};
+ if (exists $self->{"unsupported_parameters"}->{$par}){
+ push @unsupported, $par;
+ } else {
+ push @unknown, $par;
+ $self->{LOGGER}->info(Dumper($par));
+ }
+ #more owamp
+ if ($parameters{"output"} && !($parameters{"output"} eq "per_packet"
||
+ $parameters{"output"} eq "machine_readable" ||
+ $parameters{"output"} eq "raw") ){
+ $error = "Unknown output parameter: $parameters{output}";
+ return $error;
+ }
+ }# End foreach my $par
+ #TODO
+ if ($#unknown >= 0){
+ $error = "Unknown parameter(s): " . join (", ", @unknown);
+ return $error;
+ }
+
+ if ($#unsupported >= 0){
+ my $error = "Unsupported parameters(s): " . join (", ",
@unsupported);
+ return $error;
+ }
+}
+
+
+=head2 ds2nmwg()
+
+After a measurement the result data should be transformed
+from a data struct to a nmwg. The data in MRESULT will be used.
+The send message will be set in $ds->{RESULT}. Use this field to send
+the result.
+=cut
+
+sub parseResult{
+ my ($self, $ds) = @_;
+ $self->{LOGGER}->info("Started....");
+ #$self->{LOGGER}->info(Dumper($ds));
+ #TODO place this on a more specific place
+ my $ns = "http://ggf.org/ns/nmwg/tools/iperf/2.0/";
+
+ my $params = $$ds->{PARAMS};
+ foreach my $id (keys %{$params}){
+ my $datalines_ref = $$ds->{PARAMS}->{$id}->{MRESULT}; #Returns a
ref to array
+ $$ds->{REQUESTMSG}->set_data_ns ($id, $ns, @$datalines_ref);
+ #$self->{LOGGER}->debug(Dumper(@$datalines_ref));
+ }
+
+}
+
+
+
+
+1;
\ No newline at end of file
Added: branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct.pm
===================================================================
--- branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct.pm
(rev 0)
+++ branches/perfsonar-oppd-new-architect/lib/perfSONAR/DataStruct.pm
2010-07-30 07:13:26 UTC (rev 619)
@@ -0,0 +1,91 @@
+package perfSONAR::DataStruct;
+
+use strict;
+use warnings;
+
+
+#DEBUG
+use Data::Dumper;
+#DEBUG
+
+use version;
+our $VERSION = 0.52;
+
+=head1 NAME
+
+perfSONAR::DataStruct
+
+=head1 DESCRIPTION
+
+All servuces need this data struct to handle request and response. So the
services dont depend on a
+special datatype or protocol like NMWG. So it is possible to bind oppd on
different protocolls. If you want
+to use NMWG, use the method nmwg2DS to convert the NMWG type in this main
data struct.
+
+The structure is defined as follow:
+
+$self ERROROCCUR If error occur set to 1
+ SERVICE The called service
+ SERVICES The availible services as Reference
+ RETURNMSG
+ PARAMS The measurement structure
+ |-$id
+ |-%meaurement result The result of a measurement
+ |-%parameters The parameters for a measurement
+
+
+=head1 Methods
+
+=cut
+
+#Here are everything to use
+use Readonly;
+use Log::Log4perl qw(get_logger);
+use Carp;
+
+use perfSONAR::DataStruct::BWCTL;
+
+Readonly::Scalar our $CLASSPATH => "perfSONAR::DataStruct";
+#our %services = ();
+
+=head2 new({})
+
+Creates a new object, accepts at the moment a perfSONAR::SOAP::Message.
+
+=cut
+
+sub new {
+ my ( $class, $uri, $msg ) = @_;
+ my $self = {};
+ $self->{LOGGER} = get_logger( $CLASSPATH );
+ $self->{ERROROCCUR} = -1; #If error occur set to 1
+ $self->{SERVICE} = undef; #The request message
+ $self->{SERVICES} = ();
+ $self->{RETURNMSG} = undef;
+ $self->{PARAMS} = {}; #The measurement parameters defined by a ID
+ #$self->{BWCTL} = perfSONAR::DataStruct::BWCTL->new();
+
+ #Check if uri is given
+ if (!$uri){
+ croak "No service specified!";
+ }
+ else{
+ $self->{URI} = $uri;
+ }
+
+ bless $self, $class;
+
+ #Look if message is nmwg message
+ if ( $msg && ref( $msg ) eq 'NMWG::Message') {
+ $self->{LOGGER}->info("Get a NMWG message request");
+ use perfSONAR::DataStruct::NMWG;
+ my $nmwgds = perfSONAR::DataStruct::NMWG->new();
+ $nmwgds->nmwg2ds($msg,$self);
+ $self->{$self->{DSTYPE}} = $nmwgds;
+ }
+
+ return $self;
+}
+
+
+
+1;
Modified: branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP/BWCTL.pm
===================================================================
--- branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP/BWCTL.pm
2010-07-30 06:43:31 UTC (rev 618)
+++ branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP/BWCTL.pm
2010-07-30 07:13:26 UTC (rev 619)
@@ -1,277 +1,186 @@
package perfSONAR::MP::BWCTL;
-#
-# Copyright 2010 Verein zur Foerderung eines Deutschen Forschungsnetzes e.
V.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-#
-use vars qw(@ISA);
-@ISA
= qw(perfSONAR::MP);
-#DEBUG
-use Data::Dumper;
-#/DEBUG
+=head1 NAME
-use strict;
-use warnings;
+perfSONAR::MP::BWCTL
-use Carp;
+=head1 DESCRIPTION
-use perfSONAR::BWCTL;
-use perfSONAR::MP;
+This class runs measurementds for BWCTL. It use as base class the MP class.
All BWCTL specific
+definitions done here. This class has no concstructor defined. Ituse the new
method from MP class
-BEGIN {
- use vars qw($VERSION);
- $VERSION = 0.51;
-}
+=cut
-my $ns_store = "http://ggf.org/ns/nmwg/ops/store/2.0/";
-sub new {
- my $this = shift;
+use strict;
+use warnings;
- my $self = perfSONAR::MP->new (@_);
- push @{$self->{"supportedEventtypes"}},
- ("bwctl",
- "http://ggf.org/ns/nmwg/tools/bwctl/2.0/",
- "http://ggf.org/ns/nmwg/tools/iperf/2.0/");
-
- $self->{"known_parameters"} = {
+#DEBUG
+use Data::Dumper;
+#DEBUG
- src => 1,
- dst => 1,
- interval => 1,
- duration => 1,
- windowSize => 1,
- protocol => 1,
- bufferSize => 1,
- bandwidth => 1,
- login => 1,
- password => 1,
- TOS => 1,
- };
+use version;
+our $VERSION = 0.52;
- $self->{"unsupported_parameters"} = {
+use Log::Log4perl qw(get_logger);
+use base qw(perfSONAR::MP);
- advisoryWindowsize => 1,
- scheduleInterval => 1,
- numberOfTests => 1,
- latest => 1,
- alpha => 1,
- };
- bless $self, qw(perfSONAR::MP::BWCTL);
- return $self;
-}
+=head2 run()
-sub parse_key {
+The run method starts a bwctl measurement and use the runMeasurement()
+method from perfSONAR::MP. To start the measurement a data struct as
+input is needed. For example to start a bwctl measurement:
- my $self = shift;
- my %parameters = shift;
- my %key = split (',', $parameters{"metadatakey"});
- $parameters{"src"} = $key{"src"}{"value"} if $key{"src"}{"value"};
- $parameters{"dst"} = $key{"dst"}{"value"} if $key{"dst"}{"value"};
- $parameters{"interval"} = $key{"int"} if $key{"int"};
- $parameters{"duration"} = $key{"dur"} if $key{"dur"};
- $parameters{"windowSize"} = $key{"win"} if $key{"win"};
- $parameters{"protocol"} = $key{"pro"} if $key{"pro"};
- $parameters{"bufferSize"} = $key{"buf"} if $key{"buf"};
- $parameters{"bandwidth"} = $key{"ban"} if $key{"ban"};
- $parameters{"TOS"} = $key{"tos"} if $key{"tos"};
-}
+1. $bwctl = perfSONAR::MP::BWCTL->new();
+2.$ds = perfSONAR::DataStruct->new($uri, $message);
+3. $bwctl->run();
-
-sub selftest {
- my $self = shift;
- return {
- bwctl_command_test => \&bwctl_command_test,
- bwctl_exec_test => \&bwctl_exec_test,
- bwctld_running_test => \&bwctld_running_test,
- ntpd_running_test => \&ntpd_running_test,
- };
+=cut
+sub run{
+ my ($self, $ds) = @_;
+ $self->{LOGGER}->info("RUN method!!!");
+ $self->{DS} = $ds;
+ $self->runMeasurement();
}
-sub bwctl_command_test{
- my $self = shift;
- my $message;
- my $status = "error";
- my $command = $self->{"command"};
- my $commandpath = `which $command`;
- chomp ($commandpath);
- if (!(-e "$commandpath")){
- $message = "BWCTL tool $command not found!";
- #die "BWCTL tool $commandpath not found!\n";
- } else {
- $message = "BWCTL tool $command found ";
- $status = "success";
- }
- return ($message, $status);
-}
+=head2 createCommandLine({})
-sub bwctl_exec_test{
- my $self = shift;
- my $message;
- my $status = "error";
- my $command = $self->{"command"};
- my $commandpath = `which $command`;
- chomp ($commandpath);
- if (!( -x "$commandpath")){
- $message = "BWCTL tool $command not executable!";
- #die "No executable $commandpath found!\n";
- } else {
- $message = "BWCTL tool $command executable.";
- $status = "success";
- }
- return ($message, $status);
-}
+To start a measurement with bwctl a commandline expression is needed.
+This expression will be created here. As input a hash parameter of bwctl
options are needed.
+On success it will return a array with bwctl options and parameters. On
errpr it
+will return an array with ("ERROR,error message as string).
-sub bwctld_running_test{
- my $self = shift;
- my $message;
- my $status = "error";
- my @ps_output = `ps auxw |grep bwctld`;
- my $bwctld = undef;
- while (my $elem = pop @ps_output){
- next if $elem =~ /grep/;
- $bwctld = 1;
- }
- if ($bwctld){
- $message = "bwctld running.";
- $status = "success";
- } else {
- $message = "bwctld not running! ";
- $self->print_log_id ("warning", "bwctld not running!");
- }
- return ($message, $status);
-}
+=cut
+sub createCommandLine{
+ my ($self,%parameters) = @_;
+ my @commandline;
+ my $errormsg;
+
+ unless ($parameters{"src"} || $parameters{"dst"}) {
+ $errormsg = "Neither source nor destination ip address specified.";
+ $self->{LOGGER}->error($errormsg);
+ return "ERROR", $errormsg;
+ }
+
+ if ($parameters{"src"} eq $parameters{"dst"}) {
+ $errormsg = "Source ip address equal to destination ip address.";
+ $self->{LOGGER}->error($errormsg);
+ return "ERROR", $errormsg;
+ }
-sub ntpd_running_test{
- my $self = shift;
- my $message;
- my $status = "error";
- my @ps_output = `ps auxw |grep ntpd`;
- my $ntpd = undef;
- while (my $elem = pop @ps_output){
- next if $elem =~ /grep/;
- $ntpd = 1;
- }
- if ($ntpd){
- $message = "ntpd running.";
- $status = "success";
- } else {
- $message .= "ntpd not running!";
- $self->print_log_id ("warning", "ntpd not running!");
- }
- return ($message, $status);
+ #check parameters to be correct input:
+ #TODO test this condition
+ foreach my $param (keys %parameters){
+ next if ($param eq "param_ns_prefix" ||
+ $param eq "metaID" ||
+ $param eq "subject_ns_prefix" ||
+ $param eq "parameter_ID" ||
+ $param eq "param_ns_uri" ||
+ $param eq "subject_ns_uri");
+ next if ($param eq "src" || $param eq "dst");
+ if ($param eq "login" || $param eq "password"){
+ unless ($parameters{$param} =~ /^\w+$/){
+ $errormsg = "Invalid login/password string specified.";
+ $self->{LOGGER}->error($errormsg);
+ return "ERROR", $errormsg;
+ }
+ next;
+ }#End if ($param eq "login
+ if ($param eq "TOS"){
+ unless ($parameters{$param} =~ /^\d+|0x\d+$/){
+ $errormsg = "Invalid TOS string specified.";
+ $self->{LOGGER}->error($errormsg);
+ return "ERROR", $errormsg;
+ }
+ next;
+ }#End if ($param eq "TOS
+ if ($param eq "protocol"){
+ unless ($parameters{$param} =~ /^udp$/i || $parameters{$param}
=~ /^tcp$/i){
+ $errormsg = "Unknown protocol: $parameters{protocol}";
+ $self->{LOGGER}->error($errormsg);
+ return "ERROR", $errormsg;
+ }
+ next;
+ }#End if ($param eq "protocol
+ unless ($parameters{$param} =~ /^\d+$/){
+ $errormsg = "Invalid value specified for $param.";
+ $self->{LOGGER}->error($errormsg);
+ return "ERROR",
+ }
+ }#End foreach my $param
+ #End parameter check
+
+ #Now create Command
+ push @commandline , "-s" , $parameters{"src"};
+ push @commandline , "AE", "AESKEY" if($parameters{"login"});
+ push @commandline , $parameters{login} if($parameters{"login"});
+ push @commandline , "-c", $parameters{dst};
+ push @commandline , "AE", "AESKEY" if($parameters{"login"});
+ push @commandline , $parameters{login} if($parameters{"login"});
+ push @commandline , "-i", $parameters{interval}
if($parameters{"interval"});
+ push @commandline , "-t", $parameters{duration}
if($parameters{"duration"});
+ push @commandline , "-w", $parameters{windowSize}
if($parameters{"windowSize"});
+ push @commandline , "-u" if ($parameters{"protocol"} &&
$parameters{"protocol"} =~ /^udp$/i);
+ push @commandline , "-l", $parameters{bufferSize}
if($parameters{"bufferSize"});
+ push @commandline , "-b", $parameters{bandwidth}
if($parameters{"bandwidth"});
+ push @commandline , "-S", $parameters{TOS} if($parameters{"TOS"});
+
+ return @commandline;
+
}
-sub start_action {
- my $self = shift;
- my $msg = shift;
- my $dataid = shift;
- my $service_id = shift;
+=head2 parse_result({})
- $self->{"service_id"} = shift;
+After a measurement call the result message of the tool should be parsed.
+This method will be called from the MP class. The measurement result
+ub $$ds->{PARAMS}->{$id}->{MEASRESULT}will be used. On success it returns
+a array. The elements of the array are hashes. On error the
$$ds->{ERROROCCUR}
+will be set to 1. For this $$ds->{RETURNMSG} will be set to the error string.
- my %parameters;
- my $ns = "http://ggf.org/ns/nmwg/tools/iperf/2.0/";
-
- %parameters = $self->get_parameters($msg->{"dataIDs"}{$dataid});
-
- my $error = $self->check_parameters(%parameters);
-
- if ($error){
- $self->print_log_id ("info", $error);
- return $msg->return_result_code("error.mp.bwctl", $error,
$msg->{"dataIDs"}{$dataid}{"metaref"});
- }
-
+=cut
+sub parse_result {
+
+ my ($self, $ds, $id) = @_;
+ my $result = $$ds->{PARAMS}->{$id}->{MEASRESULT};
+ my @result = split(/\n/, $result);
my @datalines;
+ my $time = time;
- my $messagetype = $msg->get_message_type();
-
- if ($messagetype =~ /EchoResponse/){
- #do selftests
- my @tests = ("bwctl_command_test",
- "bwctl_exec_test",
- "bwctld_running_test",
- "ntpd_running_test");
- foreach my $test (@tests){
- $self->print_log_id("debug", "Perform test: $test");
- my ($message, $status) = $self->$test;
- my $et =
"http://schemas.perfsonar.net/tools/admin/selftest/MP/BWCTL/$test/$status/1.0";
- $msg->return_result_code(
- $et, $message, $msg->{"dataIDs"}{$dataid}{"metaref"}, $test);
- }
- return 1;
- }
-
- if ($messagetype eq "MetadataKeyResponse") {
- my %data_hash;
- my $key;
- $key .= "src,$parameters{src}" if $parameters{"src"};
- $key .= ",dst,$parameters{dst}" if $parameters{"dst"};
- $key .= ",int,$parameters{interval}" if $parameters{"interval"};
- $key .= ",dur,$parameters{duration}" if $parameters{"duration"};
- $key .= ",win,$parameters{windowSize}" if $parameters{"windowSize"};
- $key .= ",pro,$parameters{protocol}" if $parameters{"protocol"};
- $key .= ",buf,$parameters{bufferSize}" if $parameters{"bufferSize"};
- $key .= ",ban,$parameters{bandwidth}" if $parameters{"bandwidth"};
- $key .= ",tos,$parameters{TOS}" if $parameters{"TOS"};
+ foreach my $resultline (@result){
+ next unless ($resultline =~
+
/(\d+\.\d+\s*\-\s*\d+\.\d+)\s+sec\s+(\d+\.?\d*)\s+(\w+)\s+(\d+\.?\d*)\s+(\w+\/\w+)/);
- $data_hash{"MetadataKey"} = "$key";
+ my %data_hash;
+ $data_hash{"timeType"} = "unix";
+ $data_hash{"timeValue"} = $time;
+ $data_hash{"interval"} = $1;
+ $data_hash{"numBytes"} = $2;
+ $data_hash{"numBytesUnits"} = $3;
+ $data_hash{"value"} = $4;
+ $data_hash{"valueUnits"} = $5;
push @datalines, \%data_hash;
- $msg->set_data($dataid, @datalines);
- return 1;
}
-
- my $unixtime = time;
- my @commandline = perfSONAR::BWCTL::commandline(%parameters);
- if ($commandline[0] eq "ERROR") {
- return $msg->return_result_code("error.mp.bwctl", $commandline[1],
$msg->{"dataIDs"}{$dataid}{"metaref"});
- }
- $self->print_log_id("info", "BWCTL commandline: @commandline");
- my @result = perfSONAR::BWCTL::do_bwctl($self->{"command"},
$parameters{"password"}, @commandline);
- @datalines = perfSONAR::BWCTL::parse_result($unixtime, @result);
+ if($#datalines < 0){
+ #no data -> something wrong, write result as error description:
+ $datalines[0]="BWCTL Error:";
+ foreach my $resultline (@result){
+ push @datalines, $resultline;
+ }
+ }
+
if ($datalines[0] eq "BWCTL Error:"){
my $errorstring = join(" ", @datalines);
$errorstring =~ s/usage.*$//;
- return $msg->return_result_code("error.mp.bwctl", $errorstring,
$msg->{"dataIDs"}{$dataid}{"metaref"});
- }
+ $$ds->{ERROROCCUR} = 1;
+ $$ds->{RETURNMSG} = $errorstring;
+ }
+ return @datalines;
+}
- $msg->set_data_ns ($dataid, $ns, @datalines);
-=cut
- my $datanode = $msg->{"dataIDs"}{$dataid}{"node"};
- my $timenode = $msg->add_attribute(parent => $datanode, nodename =>
"commonTime",
- type => "unix", value => $unixtime);
- foreach my $data_hash (@datalines){
-
- $msg->add_attribute(parent => $timenode, nodename => "datum",
- namespace => $ns, %{$data_hash});
- }
-=cut
-
- if ($self->{"store"} == 1){
- $self->store($msg);
- }
-
-
- return 1;
-
-}
-
-1;
+1;
\ No newline at end of file
Modified: branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP/OWAMP.pm
===================================================================
--- branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP/OWAMP.pm
2010-07-30 06:43:31 UTC (rev 618)
+++ branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP/OWAMP.pm
2010-07-30 07:13:26 UTC (rev 619)
@@ -1,159 +1,126 @@
package perfSONAR::MP::OWAMP;
-#
-# Copyright 2010 Verein zur Foerderung eines Deutschen Forschungsnetzes e.
V.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-#
-use vars qw(@ISA);
-#@ISA
= qw(SOAP::Server::Parameters);
-#DEBUG
-use Data::Dumper;
-#/DEBUG
+=head1 NAME
+perfSONAR::MP::OWAMP
+
+=head1 DESCRIPTION
+
+This class runs measurementds for OWAMP. It use as base class the MP class.
All OWAMP specific
+definitions done here. This class has no concstructor defined. Ituse the new
method from MP class
+
+=cut
+
+
use strict;
use warnings;
-use Carp;
-use perfSONAR::OWAMP;
-use perfSONAR qw(print_log %services);
+#DEBUG
+use Data::Dumper;
+#DEBUG
-use NMWG;
-use NMWG::Message;
+use version;
+our $VERSION = 0.52;
+use Log::Log4perl qw(get_logger);
+use base qw(perfSONAR::MP);
-sub new {
- my $this = shift;
- my $class = ref($this) || $this;
- my %param = (@_); # IGNORED !!!
- # Generate object
- my $self = {
- };
- bless $self, $class;
- return $self;
-}
+=head2 run()
-sub open_request {
- #initialize whatever you have to initiliaze
-}
+The run method starts a OWAMP measurement and use the runMeasurement()
+method from perfSONAR::MP. To start the measurement a data struct as
+input is needed. For example to start a OWAMP measurement:
-sub close_request{
- #close request if necessary
+1. $owamp = perfSONAR::MP::OWAMP->new();
+2.$ds = perfSONAR::DataStruct->new($uri, $message);
+3. $owamp->run();
+
+=cut
+sub run{
+ my ($self, $ds) = @_;
+ $self->{LOGGER}->info("RUN method!!!");
+ $self->{DS} = $ds;
+ $self->runMeasurement();
}
-sub start_action {
- my $self = shift;
- my $msg = shift;
- my $dataid = shift;
- my $service_id = shift;
+=head2 createCommandLine({})
- my $eventType;
- foreach my $key (keys %{$msg->{"dataIDs"}{$dataid}}){
- next if ($key eq "node" || $key eq "metaref" );
- $eventType = $key;
- }
+To start a measurement with owamp a commandline expression is needed.
+This expression will be created here. As input a hash parameter of owamp
options is needed.
+On success it will return a array with owamp options and parameters. On
errpr it
+will return an array with ("ERROR,error message as string).
- my %parameters = %{$msg->{"dataIDs"}{$dataid}{$eventType}};
- my $metaref = $msg->{"dataIDs"}{$dataid}{"metaref"};
-
- if ($eventType =~ /store/){ #store data
- my $metaID = $parameters{"metaID"};
- my $dataref;
- if (!defined $parameters{"dataref"}){
- return $msg->return_result_code("error.mp.bwctl",
- "No data given for storage!", $metaID);
- } else {
- $dataref = $parameters{"dataref"};
+=cut
+sub createCommandLine{
+ my ($self,%parameters) = @_;
+ my @commandline;
+ my $errormsg;
+
+
+ push @commandline, "-S" , $parameters{src} if($parameters{"src"});
+ push @commandline, "-c" , $parameters{count} if $parameters{count};
+ push @commandline, "-L" , $parameters{timeout} if $parameters{timeout};
+ #TODO HOW to
+ #push @commandline, "-s" , $parameters{"siz"} if parameters{"size"};
+ push @commandline, "-H" , $parameters{PHB} if $parameters{PHB};
+ push @commandline, "-D", $parameters{DSCP} if $parameters{DSCP};
+ push @commandline, "-i", $parameters{send_schedule} if
$parameters{send_schedule};
+ push @commandline, "-E", $parameters{enddelay} if $parameters{enddelay};
+ push @commandline, "-z", $parameters{startdelay} if
$parameters{startdelay};
+ push @commandline, "-b", $parameters{bucket_width} if
$parameters{bucket_width};
+ push @commandline, "-N", $parameters{intermediates} if
$parameters{intermediates};
+
+ #TODO which output type should be take if no defined
+ push @commandline, "-v", "" if ($parameters{"output"} &&
$parameters{"output"} eq "per_packet");
+ push @commandline, "-M", "" if ($parameters{"output"} &&
($parameters{"output"} eq "machine_readable"));
+ push @commandline, "-R", "" if ($parameters{"output"} &&
($parameters{"output"} eq "raw"));
+
+ push @commandline, "-P", $parameters{portrange} if
$parameters{portrange};
+
+ push @commandline, "-a", "" if($parameters{"percentile"});
+ push @commandline, "-f", "" if($parameters{"one_way"} &&
($parameters{"one_way"} eq "from"));
+ push @commandline, "-t", "" if($parameters{"one_way"} &&
($parameters{"one_way"} eq "to"));
+
+ #Append destination
+ if ($parameters{"dst"} && $parameters{"port"}){
+ my $dst = "$parameters{dst}:$parameters{port}";
+ push @commandline, $dst, "";
}
- if (!defined $parameters{"uri"}){
- return $msg->return_result_code("error.mp.bwctl",
- "No MA server address given. Data cannot be stored.",
- $metaID);
+ else{
+ $errormsg = "No destination ip address or port specified.";
+ $self->{LOGGER}->error($errormsg);
+ return "ERROR", $errormsg;
}
- $msg->set_data_string($dataid, "Store action not supported.");
- return 1;
- }
+
+ #$self->{LOGGER}->info(Dumper(@commandline));
+
+ return @commandline;
+
+}
- my @unknown;
- my @unsupported;
- foreach my $par (keys %parameters){
- next if $par eq "metaID";
- if ($par eq "metadatakey"){
- parse_key(\%parameters);
- } elsif ($par eq "save_summary" ||
- $par eq "directory" ||
- $par eq "no_summary" ){
- push @unsupported, $par;
- } elsif ($par ne "src" &&
- $par ne "dst" &&
- $par ne "count" &&
- $par ne "timeout" &&
- $par ne "size" &&
- $par ne "units" &&
- $par ne "send_schedule" &&
- $par ne "percentile" &&
- $par ne "one_way" &&
- $par ne "DSCP" &&
- $par ne "PHB" &&
- $par ne "enddelay" &&
- $par ne "startdelay" &&
- $par ne "bucket_width" &&
- $par ne "intermediates" &&
- $par ne "output" &&
- $par ne "port" &&
- $par ne "portrange"){
- push @unknown, $par;
- }
- }
+=head2 parse_result({})
- if ($parameters{"output"} && !($parameters{"output"} eq "per_packet" ||
- $parameters{"output"} eq "machine_readable" ||
- $parameters{"output"} eq "raw") ){
- my $errorstring = "Unknown output parameter: $parameters{output}";
- return $msg->return_result_code("error.mp.owping", $errorstring,
$metaref);
- }
+After a measurement call the result message of the tool should be parsed.
+This method will be called from the MP class. The measurement result
+in $$ds->{PARAMS}->{$id}->{MEASRESULT}will be used. On success it returns
+a array. The elements of the array are hashes. On error the
$$ds->{ERROROCCUR}
+will be set to 1. For this $$ds->{RETURNMSG} will be set to the error string.
+=cut
+sub parse_result {
+
+ my ($self, $ds, $id) = @_;
+ my $result = $$ds->{PARAMS}->{$id}->{MEASRESULT};
+ my @result = split(/\n/, $result);
my @datalines;
- my $commandline = Hades::perfSONAR::OWAMP::commandline(%parameters);
- $commandline .= " -R" if $eventType eq "ippm";
- my $tool = $services{owamp}{command} || "/usr/local/bin/owping";
- my @result = `$tool $commandline 2>&1`; #TODO (authentifizierung)
(fehlerrueckgabe abfangen)
- my $type="default"; #TODO (machinereadable)
- $type = "per_packet" if $parameters{"output"} eq "per_packet";
- $type = "machine_readable" if $parameters{"output"} eq "machine_readable";
- $type = "ippm" if $parameters{"output"} eq "raw";
- $type = $eventType if $eventType eq "ippm";
- #$type = $parameters{"individual"} if $parameters{"individual"}; #TODO
IPPM output extra behandeln!
- @datalines = Hades::perfSONAR::OWAMP::parse_result($type, @result);
+ my $time = time;
+
+ $self->{LOGGER}->info(Dumper(@result));
- if ($datalines[0] eq "OWPING Error:"){
- my $errorstring = join(" ", @datalines);
- $errorstring =~ s/usage.*$//;
- return $msg->return_result_code("error.mp.owping", $errorstring,
$metaref);
- }
-
-
- $msg->set_data($dataid, @datalines);
- return 1;
-
-
}
-
-1;
-
+1;
\ No newline at end of file
Modified: branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP.pm
===================================================================
--- branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP.pm 2010-07-30
06:43:31 UTC (rev 618)
+++ branches/perfsonar-oppd-new-architect/lib/perfSONAR/MP.pm 2010-07-30
07:13:26 UTC (rev 619)
@@ -1,189 +1,124 @@
package perfSONAR::MP;
-#
-# Copyright 2010 Verein zur Foerderung eines Deutschen Forschungsnetzes e.
V.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-#
-BEGIN {
- use vars qw(@ISA);
-
#@ISA
= qw(SOAP::Server::Parameters);
- @ISA = qw(Exporter);
- @EXPORT = qw(store check_parameters get_parameters);
-}
+=head1 NAME
+perfSONAR::MP
+=head1 DESCRIPTION
-#DEBUG
-use Data::Dumper;
-#/DEBUG
+This is the base class for all measurement point classes like
+bwctl or owamp. It holds all main methods to start a measurement
+use the runMeasuremt method. For detail information see below.It
+is important that all measurement point classes like BWCTL, which
+uses this class as base class, should have this 3 methods:
+run() - to start the measurement point
+createCommand() - to create a command from the parameters
+parse_result() - to parse the measurement result data
+for details see the examples BWCTL and OWAMP
+
+=cut
+
use strict;
use warnings;
-use Carp;
-use perfSONAR qw(print_log);
-use NMWG;
-use NMWG::Message;
+#DEBUG
+use Data::Dumper;
+#DEBUG
-sub new {
- my $this = shift;
- my $class = ref($this) || $this;
- my %param = (@_);
+use version;
+our $VERSION = 0.52;
- my $self = {
- };
- $self->{"supportedEventtypes"} = [
- "http://ggf.org/ns/nmwg/ops/store/2.0",
- ];
- $self->{"command"} = $param{"command"};
- $self->{"store"} = $param{"store"};
- $self->{"store_url"} = $param{"store_url"};
+use Log::Log4perl qw(get_logger);
+use IPC::Run qw( run timeout start finish pump);
+use IO::Pty;
- bless $self, $class;
- return $self;
-}
+=head2 new()
-sub open_request {
- #initialize whatever you have to initiliaze
+The constructor is called withoud a parameter.
+=cut
+sub new{
+ my ($class) = @_;
+ my $self = {};
+ $self->{LOGGER} = get_logger("perfSONAR::MP");
+ bless $self, $class;
}
-sub close_request{
- #close request if necessary
-}
+=head2 runMeasurement({})
+This function can be used to start a measurement point (MP). It use a data
struct.
+The PARAMS field should be set. The result of the measurement is stored
+in the MPRESULT field of data struct. The type is array. On error
+occurnes the field is set to "ERROR".
-#obsolete!
-sub set_command {
- my $self = shift;
- my $c = shift;
- $self->{"command"} = $c;
-}
-
-sub selftest {
- my $self = shift;
- return undef;
-}
-
-
-sub start_action {
-
-}
-
-
-sub store {
-
- my $self = shift;
- my $msg = shift;
-
- if (!$self->{"store_url"}){
- $self->print_log_id("error", "Store to MA failed: no url to SQL MA
given!");
- } else {
- my $store_msg = $msg->clone;
- if (!$store_msg){
- $self->print_log_id("error", "Store to MA failed: Could not clone
storage message.");
- return;
- }
- $store_msg->set_message_type("MeasurementArchiveStoreRequest");
-
- #my $store_string = $store_msg->as_string(1);
- #print "$store_string\n";
-
- my $response = perfSONAR::sendReceive( message => $store_msg,
- uri => $self->{"store_url"},
- );
-
- if ($response){
- my $result = $response->as_string(2);
- $self->print_log_id("info", "Answer from SQL MA:\n$result");
- #print "$result\n"; #TODO parse response?
- } else {
- $self->print_log_id("error", "Store to MA failed: No response from SQL
MA!");
- }
- }
-}
-
-
-sub get_parameters {
-
- my $self = shift;
- my $datablock = shift;
-
- my %parameters;
-
- foreach my $key (keys %{$datablock}){ #get eventtypes
- next if ($key eq "node" || $key eq "metaref" ); #no eventtype
- foreach my $k (keys %{$datablock->{$key}}){
- if (!defined $parameters{$k}){
- if ($k eq "src" || $k eq "dst"){
- $parameters{$k} = $datablock->{$key}{$k}{"value"};
- } else {
- $parameters{$k} = $datablock->{$key}{$k};
+=cut
+sub runMeasurement{
+ my ($self) = @_;
+ my $logger = get_logger("perfSONAR::MP" );
+ my $ds = $self->{DS};
+ my $pass;
+
+ $logger->info("Starting...");
+ my $params = $$ds->{PARAMS};
+ foreach my $id (keys %{$params}){
+ my @commandline = $self->createCommandLine(
+ %{$$ds->{PARAMS}->{$id}});
+
+ if ($commandline[0] eq "ERROR") {
+ #TODO RETURN ERROR MSG
}
- }
- }
- }
-
- return %parameters;
+ #Start commandline
+ #Get tool for commandline
+ my $tool = $$ds->{SERVICES}->{$$ds->{SERVICE}}->{tool};
+
+ $self->{LOGGER}->info("Service: $$ds->{SERVICE} called with command:
$tool @commandline");
+
+ #Define pipes
+ my ($in, $out, $err);
+
+ #Define call
+ my @call = @commandline;
+ unshift @call, $tool;
+
+ my $h = start
(\@call,
'<pty<', \$in, '>pty>', \$out, '2>', \$err);
+ while (1){
+ pump $h;
+ if ($err =~ /passphrase/){
+ $in = "$pass\n";
+ $err = "";
+ }
+ elsif ($err ne "\n"){
+ last;
+ }
+ }#End while (1)
+ my $out_tmp = $out;
+ my $err_tmp = $err;
+ finish $h;
+
+ if (!$out){
+ $$ds->{PARAMS}->{$id}->{MEASRESULT} = "$err_tmp" . "$err";
+ }
+ else{
+ $$ds->{PARAMS}->{$id}->{MEASRESULT} = "$out_tmp" . "$out";
+ }
+
+ #parse the result
+ my @mresult = $self->parse_result($ds,$id);
+ $$ds->{PARAMS}->{$id}->{MRESULT} =
\@mresult;
+ #$logger->info(Dumper(@datalines));
+ }#End foreach my $id
+ #$logger->info(Dumper($params));
+
+ #On success write to log
+ if ($$ds->{ERROROCCUR}){
+ $logger->info("Measurement point was successfull for service:
$$ds->{SERVICE}");
+ }
+ else{
+ $logger->info("Measurement point was NOT successfull for
service: $$ds->{SERVICE}");
+ }
+
}
-sub check_parameters {
-
- my $self = shift;
- my %params = @_;
-
- my @unknown;
- my @unsupported;
-
-
- foreach my $par (keys %params){
- next if ($par eq "ns_prefix" ||
- $par eq "param_ns_prefix" ||
- $par eq "subject_ns_prefix" ||
- $par eq "subject_ns_uri" ||
- $par eq "param_ns_uri" ||
- $par eq "parameter_ID" ||
- $par eq "metaID" ||
- $par eq "address" ||
- $par eq "metadatakey"
- );
- next if exists $self->{"known_parameters"}{$par};
- if (exists $self->{"unsupported_parameters"}->{$par}){
- push @unsupported, $par;
- } else {
- push @unknown, $par;
- }
-
- }
-#TODO
- if ($#unknown >= 0){
- my $error = "Unknown parameter(s): " . join (", ", @unknown);
- return $error;
- }
-
- if ($#unsupported >= 0){
- my $error = "Unsupported parameters(s): " . join (", ", @unsupported);
- return $error;
- }
-}
-
-
-sub print_log_id {
- my ($self, $level,$message) = @_;
- print_log($level,$message,$self->{"service_id"});
-}
-
1;
Modified: branches/perfsonar-oppd-new-architect/lib/perfSONAR.pm
===================================================================
--- branches/perfsonar-oppd-new-architect/lib/perfSONAR.pm 2010-07-30
06:43:31 UTC (rev 618)
+++ branches/perfsonar-oppd-new-architect/lib/perfSONAR.pm 2010-07-30
07:13:26 UTC (rev 619)
@@ -41,229 +41,56 @@
use Carp;
-use perfSONAR::SOAP::HTTP::Request;
-use perfSONAR::SOAP::HTTP::Response;
-use perfSONAR::SOAP::HTTP::UserAgent;
-#use perfSONAR::Echo;
-use NMWG;
-use NMWG::Message;
+use Log::Log4perl qw(get_logger);
-our $log = undef;
-our %services = ();
+=head1 NAME
-my $echo_et = "http://schemas.perfsonar.net/tools/admin/echo/2.0";
+perfSONAR
-sub handle_request {
- my $class = shift; # TODO
- my ($uri,$reqmsg) = (@_);
- my $xmlmsg = $reqmsg->as_string;
- print_log("info","Received message");
- print_log("debug","Raw Message:\n$xmlmsg");
- #print_log("debug","Parsed Message:\n" . Dumper($reqmsg));
- # How to print DOM tree? Useful???
+=head1 DESCRIPTION
- my $service = undef;
+Use this to have a starting point to use all availible services.
- #if no accesspoint is given we do not know what service is meant!
- if (!$uri){
- croak "No service specified!";
- } else {
- ($service = $uri) =~ s/^.*\/services\///;
- $service =~ s/\/$//;
- my $serviceurl = $service;
- print_log("info", "Service: $service");
- if (!$services{$service}){
- croak "Service $serviceurl not known!";
- }
- }
+=head1 Methods
- my @module_ets =
@{$services{$service}->{"handler"}->{"supportedEventtypes"}};
- push @module_ets, $echo_et;
+=cut
+#This are the globals
+our $log = undef;
+our %services = ();
+my $echo_et = "http://schemas.perfsonar.net/tools/admin/echo/2.0";
- my $messagetype = $reqmsg->get_message_type();
- if ($messagetype eq "ErrorResponse"){ #error from authentication!
- return $reqmsg;
- }
- if ($messagetype eq "AuthNEERequest"){ #authorization rquest to dummy AS
- require perfSONAR::AS;
- return perfSONAR::AS::dummy();
- }
- if ($messagetype eq "SetupDataRequest"){
- $reqmsg->set_message_type("SetupDataResponse");
- }
- elsif ($messagetype eq "MeasurementRequest"){
- $reqmsg->set_message_type("MeasurementResponse");
- }
- elsif ($messagetype eq "MetadataKeyRequest"){
- $reqmsg->set_message_type("MetadataKeyResponse");
- }
- elsif ($messagetype =~ /EchoRequest/){
- $reqmsg->set_message_type("EchoResponse");
- }
- else {
- my $errorstring = "Unknown messagetype: $messagetype";
- print_log("info",$errorstring);
- $reqmsg->set_message_type("ErrorResponse");
- $reqmsg->return_result_code("error.common.action_not_supported",
"$errorstring", "message");
- return $reqmsg;
- }
+#TODO
+#Replace complete NMWG from this handler
+#to make it more flexible
+#replace by DataStruct
- #create $reqmsg->{"dataIDs"} and
- # $reqmsg->{"metadataIDs"} hashes from document
- my ($errorstring, $metaid) = $reqmsg->parse_all;
- if($errorstring){
- print_log("info",$errorstring);
- $reqmsg->return_result_code("error.common.parse_error", "$errorstring",
$metaid);
- return $reqmsg;
- }
+=head2 handle_request(uri,requestMessage)
- #check if at least one metadata and one data element is in message
- if(!($reqmsg->{"metadataIDs"})){
- $errorstring = "No metadata definition in message.";
- print_log("info",$errorstring);
- $reqmsg->return_result_code("error.common.message", "$errorstring",
"message");
- return $reqmsg;
- }
-
- if(!(defined $reqmsg->{"dataIDs"})){
- $errorstring = "No data trigger in message.";
- print_log("info",$errorstring);
- $reqmsg->return_result_code("error.common.message", "$errorstring",
"message");
- return $reqmsg;
- }
-
- #do some checks on metadata content
- foreach my $meta (keys %{$reqmsg->{"metadataIDs"}}){
- #check for unknown eventTypes
- my $et = $reqmsg->{"metadataIDs"}{$meta}{"eventType"};
- if ($et =~ /admin/){ #dispatch to Echo module
- return perfSONAR::Echo::handle_echo_request($reqmsg, $service);
- return $reqmsg;
- }
-
- my $found = undef;
- #foreach my $sup_et (@{$services{$service}{"eventtype"}}){
- foreach my $sup_et (@module_ets){
- next unless ($sup_et =~ /$et/);
- $found = 1;
- }
- if (!defined $found){
- my $errorstring = "Unknown eventType: $et";
- print_log("info",$errorstring);
- $reqmsg->return_result_code("error.common.parse_error", $errorstring,
$meta);
- return $reqmsg;
- }
- #check times
- my $startTime = $reqmsg->{"metadataIDs"}{$meta}{"startTime"};
- my $endTime = $reqmsg->{"metadataIDs"}{$meta}{"endTime"};
- if ($endTime && $startTime && ($endTime < $startTime)){
- my $errorstring = "Illegal time duration specified: " .
- "$endTime is later than $startTime!";
- print_log("info",$errorstring);
- $reqmsg->return_result_code("error.common.parse_error", $errorstring,
$meta);
- return $reqmsg;
- }
- }
-
- #add metadata parameters to data hashes
- ($errorstring, $metaid) = $reqmsg->concatenate_params;
- if ($errorstring){
- print_log("info", $errorstring);
- $reqmsg->return_result_code("error.common.parse_error", "$errorstring",
$metaid);
- return $reqmsg;
- }
-
- #DEBUG output:
- print Dumper ($reqmsg->{"dataIDs"});
- #print Dumper ($reqmsg->{"metadataIDs"});
-
-
- #initialize data module
- $services{$service}->{handler}->open_request();
-
- #start action for each data block
- foreach my $dataid (keys %{$reqmsg->{"dataIDs"}}){
- $services{$service}->{handler}->start_action($reqmsg, $dataid, $service);
- }
-
- $services{$service}->{handler}->close_request();
-
- return $reqmsg;
-}
-
-
-sub sendReceive {
- my %p = (
- message => undef,
- host => "localhost",
- port => "8090",
- endpoint => "/",
- uri => "",
- soapheader => "", #TODO TODO noch nicht fertig und kein String!
- @_
- );
-
- my $uri = $p{uri} || "http://$p{host}:$p{port}$p{endpoint}";
- my $body = $p{message}->as_dom;
+ starts all requested EventTypes included in the request.
+ Need two parameters which are uri and requestMessage.
+ The parameters should have the following types:
- # Message is NMWG::Message
- my $message = perfSONAR::SOAP::Message->new(
- body => $body,
- uri => $uri
- );
- # Modify SOAP header using $message or set via "new" call directly
-
- my $userAgent = perfSONAR::SOAP::HTTP::UserAgent->new;
- my $request = perfSONAR::SOAP::HTTP::Request->new(message => $message);
-
- my $response = $userAgent->request($request);
- unless ($response->is_success) {
- # HTTP error
- #my $code = $response->code();
- #my $message = $response->message();
- carp $response->status_line if $^W; # "<code> <message>"
- return;
- }
+ uri STRING => complette link for the service
- my $soap_message = $response->soap_message;
- if ($soap_message->is_fault) {
- carp "TODO" if $^W;
- return;
- }
+ requestMessage
+
+ returns t
+=back
- my $nmwg_message = NMWG::Message->new( ($soap_message->body)[0] );
- #TODO This should perhaps be
NMWG::Message->from_soap_message($soap_message);
+=cut
+sub handle_request {
- return $nmwg_message;
+ my ($self, $ds) = @_;
+
+ my $logger = get_logger("perfSONAR" );
+ $logger->debug("Running perfsonar->request_handler");
+ $ds->{SERVICES}->{$ds->{SERVICE}}->{handler}->run(\$ds);
+ $ds->{$ds->{DSTYPE}}->parseResult(\$ds);
+
}
-
-sub print_log_old {
- my ($level,$message) = @_;
-
- if (defined $log) {
- $level = "debug" unless $log->level_is_valid($level);
- $log->log(level => $level, message => $message);
- } else {
- print STDERR "$level: $message\n";
- }
- return 1;
-}
-
-sub print_log {
- my ($level,$message,$service) = @_;
-
- if (defined $log) {
- $level = "debug" unless $log->level_is_valid($level);
- $log->log(level => $level, service => $service, message => $message);
- } else {
- print STDERR ($service ? "$service: " : "unknown service: ") .
- "$level: $message\n";
- }
- return 1;
-}
-1;
+1;
\ No newline at end of file
Modified:
branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/bwctl-iperf-req2.xml
===================================================================
---
branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/bwctl-iperf-req2.xml
2010-07-30 06:43:31 UTC (rev 618)
+++
branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/bwctl-iperf-req2.xml
2010-07-30 07:13:26 UTC (rev 619)
@@ -12,7 +12,7 @@
<nmwg:metadata id="bwctl-metadata">
<bwctl:subject id="bwctl-subject">
- <nmwgt:endPoint type="ipv4" value="131.188.81.12"/>
+ <nmwgt:endPoint type="ipv4" value="130.59.35.142"/>
</bwctl:subject>
<nmwg:eventType>http://ggf.org/ns/nmwg/tools/bwctl/2.0</nmwg:eventType>
@@ -24,8 +24,8 @@
<nmwg:metadata id="iperf-metadata">
<iperf:subject id="iperf-subject" metadataIdRef="bwctl-metadata">
<nmwgt:endPointPair>
- <nmwgt:src type="ipv4" value="131.188.81.12"/>
- <nmwgt:dst type="ipv4" value="131.188.81.90"/>
+ <nmwgt:src type="ipv4" value="130.59.35.142"/>
+ <nmwgt:dst type="ipv4" value="195.111.107.114"/>
</nmwgt:endPointPair>
</iperf:subject>
<iperf:parameters id="iperf-parameters">
Modified:
branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/bwctl-test
===================================================================
--- branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/bwctl-test
2010-07-30 06:43:31 UTC (rev 618)
+++ branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/bwctl-test
2010-07-30 07:13:26 UTC (rev 619)
@@ -1 +1 @@
-./perfsonar-client.pl --reqfile=bwctl-iperf-req2.xml
--uri=http://radagast.rrze.uni-erlangen.de:3070/services/MP/BWCTL
--host=radagast.rrze.uni-erlangen.de --port=3070
+./perfsonar-client.pl --reqfile=bwctl-iperf-req2.xml
--uri=http://calim.rrze.uni-erlangen.de:8090/services/MP/BWCTL
--host=calim.rrze.uni-erlangen.de --port=80900
Modified:
branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/owamp-ind2-req.xml
===================================================================
---
branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/owamp-ind2-req.xml
2010-07-30 06:43:31 UTC (rev 618)
+++
branches/perfsonar-oppd-new-architect/tools/perfSONAR-client/owamp-ind2-req.xml
2010-07-30 07:13:26 UTC (rev 619)
@@ -12,15 +12,15 @@
<nmwg:metadata id="meta1">
<perfsonar:subject id="subj1">
<nmwgt:endPointPair>
- <nmwgt:src type="ipv4" value="131.188.81.61"/>
- <nmwgt:dst type="ipv4" value="131.188.81.14"/>
+ <nmwgt:src type="ipv4" value="198.129.254.74"/>
+ <nmwgt:dst type="ipv4" value="198.129.254.102"/>
</nmwgt:endPointPair>
</perfsonar:subject>
<nmwg:eventType>owamp</nmwg:eventType>
<nmwg:parameters id="param1">
<nmwg:parameter name="individual" value="timestamps"/>
- <nmwg:parameter name="port" value="6767"/>
+ <nmwg:parameter name="port" value="861"/>
</nmwg:parameters>
</nmwg:metadata>
- [pS-dev] [GEANT/SA2/SA2T3-OPPD] r619 - in branches/perfsonar-oppd-new-architect: bin etc/oppd-mdm/oppd.d lib lib/perfSONAR lib/perfSONAR/DataStruct lib/perfSONAR/MP tools/perfSONAR-client, svn-noreply, 07/30/2010
Archive powered by MHonArc 2.6.16.