IMF-GEC11-QSR: ezclient.pl

File ezclient.pl, 11.3 KB (added by Rudra Dutta, 8 years ago)

Easy command-line perfSONAR client for accessing IMF data

Line 
1#!/usr/bin/perl -w
2
3use strict;
4use warnings;
5
6our $VERSION = 3.2;
7
8=head1 NAME
9
10dump.pl - Dumps the contents of an XMLDB.
11
12=head1 DESCRIPTION
13
14Given the information on an XMLDB, connect and dump all metadata and data
15elements.
16
17=head1 SYNOPSIS
18
19    # this will send the xml file echo-req.xml to srv4.dir.garr.it on port 8080
20    # and endpoint /axis/services/MeasurementArchiveService
21    $ client.pl \
22           http://srv4.dir.garr.it:8080/axis/services/MeasurementArchiveService \
23           echo-req.xml
24
25    # ditto
26    $ client.pl \
27           --server=srv4.dir.garr.it \
28           --port=8080 \
29           --endpoint=/axis/services/MeasurementArchiveService \
30           echo-req.xml
31               
32    # this will override the port 8080 with the specified port 80
33    $ client.pl \
34           --port=80
35           http://srv4.dir.garr.it:8080/axis/services/MeasurementArchiveService \
36           echo-req.xml
37
38    # this will override the endpoint with
39    # /perfsonar-RRDMA/services/MeasurementArchiveService
40    $ client.pl \
41           --endpoint=/perfsonar-RRDMA/services/MeasurementArchiveService
42           http://srv4.dir.garr.it:8080/axis/services/MeasurementArchiveService \
43           echo-req.xml
44               
45    # this will filter the output of the returned xml to only show the elements
46    # that have qname nmwg:data
47    $ client.pl \
48           --filter='//nmwg:data' \
49           http://srv4.dir.garr.it:8080/axis/services/MeasurementArchiveService \
50           echo-req.xml
51           
52=cut
53
54use Getopt::Long;
55use Log::Log4perl qw(:easy);
56use XML::LibXML;
57use File::Basename;
58use Carp;
59use Params::Validate qw(:all);
60use English qw( -no_match_vars );
61
62use Time::Local;
63
64my $dirname;
65my $libdir;
66
67# we need to figure out what the library is at compile time so that "use lib"
68# doesn't fail. To do this, we enclose the calculation of it in a BEGIN block.
69BEGIN {
70    $dirname = dirname( $PROGRAM_NAME );
71    $libdir  = $dirname . "/../lib";
72}
73
74use lib "$libdir";
75
76use perfSONAR_PS::Transport;
77use perfSONAR_PS::Common qw( readXML );
78use perfSONAR_PS::Utils::ParameterValidation;
79
80our $DEBUGFLAG;
81our %opts = ();
82our $help_needed;
83
84my $ok = GetOptions(
85    'filter=s'   => \$opts{FILTER},
86        'device=s'               => \$opts{DEVICE},
87        'start=s'                => \$opts{START},
88        'end=s'          => \$opts{END},
89        'type=s'                 => \$opts{TYPE},
90        'interface=s'            => \$opts{INTERFACE},
91        'plot'           => \$opts{PLOT},
92    'help'       => \$help_needed
93);
94
95if ( not $ok or $help_needed ) {
96    print_help();
97    exit( 1 );
98}
99
100our $level = $INFO;
101$level = $DEBUG if $DEBUGFLAG;
102
103Log::Log4perl->easy_init( $level );
104my $logger = get_logger( "perfSONAR_PS" );
105
106my $host     = q{};
107my $port     = q{};
108my $endpoint = q{};
109my $filter   = '/';
110my $file     = q{};
111my $starttime= q{};
112my $endtime= q{};
113my $montype= q{};
114my $interface= q{};
115my $device= q{};
116my $devhost= q{};
117if ( scalar @ARGV == 1 ) {
118    ( $host, $port, $endpoint ) = &perfSONAR_PS::Transport::splitURI( $ARGV[0] );
119
120    unless ( $host and $port and $endpoint ) {
121        print_help();
122        croak "Argument 1 must be a URI if more than one parameter used.\n";
123    }
124
125}
126else {
127    print_help();
128    croak "Invalid number of parameters: must be 1 for a uri";
129}
130
131my $syear = q {};
132my $smon = q {};
133my $sday = q {};
134my $shour = q {};
135my $smin = q {};
136my $ssec = q {};
137my $eyear = q {};
138my $emon = q {};
139my $eday = q {};
140my $ehour = q {};
141my $emin = q {};
142my $esec = q {};
143
144if ( defined $opts{HOST} ) {
145    $host = $opts{HOST};
146}
147if ( defined $opts{PORT} ) {
148    $port = $opts{PORT};
149}
150if ( defined $opts{ENDPOINT} ) {
151    $endpoint = $opts{ENDPOINT};
152}
153if ( defined $opts{FILTER} ) {
154    $filter = $opts{FILTER};
155}
156if ( defined $opts{START} ) {
157        ($syear,$smon,$sday,$shour,$smin,$ssec)=split(":",$opts{START});
158        $shour=0 if not defined $shour;
159        $smin=0 if not defined $smin;
160        $ssec=0 if not defined $ssec;
161        $starttime = timegm($ssec,$smin,$shour,$sday,($smon-1),$syear);
162    #$starttime= $opts{START};
163}
164if ( defined $opts{END} ) {
165        ($eyear,$emon,$eday,$ehour,$emin,$esec)=split(":",$opts{END});
166        $ehour=0 if not defined $ehour;
167        $emin=0 if not defined $emin;
168        $esec=0 if not defined $esec;
169        $endtime = timegm($esec,$emin,$ehour,$eday,($emon-1),$eyear);
170    #$endtime= $opts{END};
171}
172if ( defined $opts{TYPE} ) {
173    $montype= $opts{TYPE};
174}
175if ( defined $opts{INTERFACE} ) {
176    $interface= $opts{INTERFACE};
177}
178if ( defined $opts{DEVICE} ) {
179    ($device,$devhost)= split(':',$opts{DEVICE});
180}
181
182unless ( $host and $port and $endpoint ) {
183    print_help();
184    croak "You must specify the host, port and endpoint as either a URI or via the command line switches";
185}
186my $id=0;
187
188my $xmlf;
189if (uc $device eq 'INFINERA') {
190        if (uc $montype eq 'BER'){
191                $montype="PREFEC-".$montype ;
192        #       $id=8;
193        }
194        elsif (uc $montype eq 'POWER'){
195        #       $id=7
196        }
197        else {
198                print "Currently only BER and POWER measurements are supported.\n";
199        }
200        my ($port1,$port2,$port3)=split(':',$interface);
201        $xmlf="<nmwgt:device>INFINERA</nmwgt:device>
202                                <nmwgt:montype>$montype</nmwgt:montype>
203                                <nmwgt:hostName>$devhost</nmwgt:hostName>
204                                <nmwgt:hostPort>9090</nmwgt:hostPort>
205                 <layer0:port>
206                         <layer0:chassis>$port1</layer0:chassis>
207                         <layer0:DLMslot>$port2</layer0:DLMslot>
208                         <layer0:opticalChannel>$port3</layer0:opticalChannel>
209                 </layer0:port>\n";
210        }
211elsif (uc $device eq 'POLATIS'){
212        $xmlf="<nmwgt:device>POLATIS</nmwgt:device>
213                                <nmwgt:montype>$montype</nmwgt:montype>
214                                <nmwgt:hostName>$devhost</nmwgt:hostName>
215                                <nmwgt:hostPort>3082</nmwgt:hostPort>
216                 <layer0:port>
217                         <layer0:opticalPort>$interface</layer0:opticalPort>
218                 </layer0:port>\n";
219        }
220else {
221        print "Currently only INFINERA and POLATIS devices are supported.\n";
222        }
223
224my $xmlf_header="<nmwg:message xmlns:nmwg=\"http://ggf.org/ns/nmwg/base/2.0/\"
225     xmlns:ber=\"http://ggf.org/ns/nmwg/characteristic/BER/2.0\"
226     xmlns:power=\"http://ggf.org/ns/nmwg/characteristic/POWER/2.0\"
227     xmlns:nmwgt=\"http://ggf.org/ns/nmwg/topology/2.0/\"
228     xmlns:unis=\"http://ogf.org/schema/network/topology/unis/20100528/\"
229     xmlns:layer0=\"http://ggf.org/ns/nmwg/topology/layer0/2.0/\"
230         type=\"SetupDataRequest\"
231         id=\"setupDataRequest1\" >
232  <nmwg:metadata id=\"m-$id\" xmlns:nmwg=\"http://ggf.org/ns/nmwg/base/2.0/\">
233    <nmwg:subject id=\"sub1\">
234                <nmwgt:interface xmlns:nmwgt=\"http://ggf.org/ns/nmwg/topology/2.0/\">
235                        <nmwgt:node>\n";
236my $xmlf_tail="</nmwgt:node>
237                </nmwgt:interface>
238    </nmwg:subject>
239        <nmwg:eventType>http://ggf.org/ns/nmwg/characteristic/$montype/2.0</nmwg:eventType>
240  </nmwg:metadata>
241  <nmwg:metadata id=\"m-${id}c\" xmlns:nmwg=\"http://ggf.org/ns/nmwg/base/2.0/\">
242    <select:subject id=\"sub1c\" metadataIdRef=\"m-$id\" xmlns:select=\"http://ggf.org/ns/nmwg/ops/select/2.0/\"/>
243    <select:parameters id=\"param2c\" xmlns:select=\"http://ggf.org/ns/nmwg/ops/select/2.0/\">     
244      <nmwg:parameter name=\"startTime\">$starttime</nmwg:parameter>
245      <nmwg:parameter name=\"endTime\">$endtime</nmwg:parameter>
246    </select:parameters>
247    <nmwg:eventType>http://ggf.org/ns/nmwg/ops/select/2.0</nmwg:eventType>
248  </nmwg:metadata>
249  <nmwg:data id=\"d-$id\" metadataIdRef=\"m-${id}c\" xmlns:nmwg=\"http://ggf.org/ns/nmwg/base/2.0/\"/>
250
251</nmwg:message>\n ";
252
253# start a transport agent
254my $sender = new perfSONAR_PS::Transport( $host, $port, $endpoint );
255
256# Make a SOAP envelope, use the XML file as the body.
257my $envelope = &perfSONAR_PS::Common::makeEnvelope( $xmlf_header.$xmlf.$xmlf_tail );
258my $error;
259
260# Send/receive to the server, store the response for later processing
261my $responseContent = $sender->sendReceive( $envelope, q{}, \$error );
262
263croak "Error sending request to service: $error" if $error;
264
265# dump the content to screen, using the xpath statement if necessary
266&dump( { response => $responseContent, find => $filter } );
267
268exit( 0 );
269
270=head2 dump( { response, find } )
271
272Print out results of service message. 
273
274=cut
275
276sub dump {
277    my ( @args ) = @_;
278    my $parameters = validateParams( @args, { response => 1, find => 1 } );
279    my $xp = q{};
280
281    if ( ( UNIVERSAL::can( $parameters->{response}, "isa" ) ? 1 : 0 == 1 ) and ( $xmlf->isa( 'XML::LibXML' ) ) ) {
282        $xp = $parameters->{response};
283    }
284    else {
285        my $parser = XML::LibXML->new();
286        $xp = $parser->parse_string( $parameters->{response} );
287    }
288    my @res = $xp->findnodes( $parameters->{find} );
289        my @s;
290    foreach my $n ( @res ) {
291                $_=$n->toString();
292                 @s=  m/Value="(.*?)".*startTime="(.*?)"/g;
293        #print $n->toString() . "\n";
294    }
295        my $v=undef;
296        if (defined $opts{PLOT}){
297                open FILE, ">temp" or die $!;
298        }
299        foreach (@s){
300                if ( not defined $v ) {
301                        $v=$_;
302                        #print $_."\n";
303                }
304                else {
305                        if (defined $opts{PLOT}){
306                                if (uc $montype eq 'POWER'){
307                                $_=$_." : ".$v;
308                                        s/.*?\s(.*?)\s(.*?)\s(.*?)\s.*?:(.*?)dB/$1-$2-$3 $4/;   
309                                }
310                                elsif (uc $montype eq 'PREFEC-BER'){
311                                $_=$_." : ".log($v);
312                                        s/.*?\s(.*?)\s(.*?)\s(.*?)\s.*?:(.*?)/$1-$2-$3 $4/;     
313                                }
314                                print FILE $_."\n";
315                        }
316                        else {
317                                print $_." : ".$v."\n";
318                        }
319                        $v=undef;
320                }
321        }
322if (defined $opts{PLOT}){
323close FILE;
324my %months = (1=>"Jan",2=>"Feb",3=>"Mar",4=>"Apr",5=>"May",6=>"Jun",7=>"Jul",8=>"Aug",9=>"Sep",10=>"Oct",11=>"Nov",12=>"Dec");
325#print "$months{$smon}-$sday-$shour:$smin:00"."$months{$emon}-$eday-$ehour:$emin:00";
326        open (GNUPLOT, "|gnuplot");
327        if (uc $montype eq 'POWER'){
328        print GNUPLOT<<EOF;
329set term x11
330set xdata time
331set timefmt "%b-%d-%H:%M:%S"
332set output "load.png"
333set xrange ["$months{$smon}-$sday-$shour:$smin:00":"$months{$emon}-$eday-$ehour:$emin:00"]
334set yrange [0:-50]
335set grid
336set xlabel "Date\\nTime"
337set ylabel "$montype"
338set title "$device-$devhost"
339plot "temp" using 1:2 index 0 title "port: $interface" with lines
340 pause 30
341EOF
342}
343        elsif (uc $montype eq 'PREFEC-BER'){
344        print GNUPLOT<<EOF;
345set term x11
346set xdata time
347set timefmt "%b-%d-%H:%M:%S"
348set output "load.png"
349set xrange ["$months{$smon}-$sday-$shour:$smin:00":"$months{$emon}-$eday-$ehour:$emin:00"]
350set yrange [0:-30]
351set grid
352set xlabel "Date\\nTime"
353set ylabel "$montype (BER=2^y)"
354set title "$device-$devhost"
355plot "temp" using 1:2 index 0 title "port: $interface" with lines
356 pause 30
357EOF
358}
359close(GNUPLOT);
360}
361    return;
362}
363
364=head2 help()
365
366Print a help message
367
368=cut
369
370sub print_help {
371    print "$PROGRAM_NAME: sends an xml file to the server on specified port.\n";
372    print "    ./client.pl  http://xxx.yyy.zzz:9989/perfSONAR_PS/services/IMFRealTime --device=infinera:dtn-1.renci.ben --start=year:mon:day:hour:sec --end=year:mon:day:hour:sec --type=BER --interface=1:4:9 \n";
373    return;
374}
375
376__END__
377
378=head1 SEE ALSO
379
380L<use Getopt::Long>, L<perfSONAR_PS::DB::XMLDB>
381
382To join the 'perfSONAR Users' mailing list, please visit:
383
384  https://lists.internet2.edu/sympa/info/perfsonar-ps-users
385
386The perfSONAR-PS subversion repository is located at:
387
388  http://anonsvn.internet2.edu/svn/perfSONAR-PS/trunk
389
390Questions and comments can be directed to the author, or the mailing list.
391Bugs, feature requests, and improvements can be directed here:
392
393  http://code.google.com/p/perfsonar-ps/issues/list
394
395=head1 VERSION
396
397$Id: client.pl 4475 2010-09-29 13:18:06Z zurawski $
398
399=head1 AUTHOR
400
401Jason Zurawski, zurawski@internet2.edu
402Yee-Ting Li <ytl@slac.stanford.edu>
403
404=head1 LICENSE
405
406You should have received a copy of the Internet2 Intellectual Property Framework
407along with this software.  If not, see
408<http://www.internet2.edu/membership/ip.html>
409
410=head1 COPYRIGHT
411
412Copyright (c) 2004-2010, Internet2 and the University of Delaware
413
414All rights reserved.
415
416=cut