1 | #!/usr/bin/perl -w |
---|
2 | |
---|
3 | use strict; |
---|
4 | use warnings; |
---|
5 | |
---|
6 | our $VERSION = 3.2; |
---|
7 | |
---|
8 | =head1 NAME |
---|
9 | |
---|
10 | dump.pl - Dumps the contents of an XMLDB. |
---|
11 | |
---|
12 | =head1 DESCRIPTION |
---|
13 | |
---|
14 | Given the information on an XMLDB, connect and dump all metadata and data |
---|
15 | elements. |
---|
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 | |
---|
54 | use Getopt::Long; |
---|
55 | use Log::Log4perl qw(:easy); |
---|
56 | use XML::LibXML; |
---|
57 | use File::Basename; |
---|
58 | use Carp; |
---|
59 | use Params::Validate qw(:all); |
---|
60 | use English qw( -no_match_vars ); |
---|
61 | |
---|
62 | use Time::Local; |
---|
63 | |
---|
64 | my $dirname; |
---|
65 | my $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. |
---|
69 | BEGIN { |
---|
70 | $dirname = dirname( $PROGRAM_NAME ); |
---|
71 | $libdir = $dirname . "/../lib"; |
---|
72 | } |
---|
73 | |
---|
74 | use lib "$libdir"; |
---|
75 | |
---|
76 | use perfSONAR_PS::Transport; |
---|
77 | use perfSONAR_PS::Common qw( readXML ); |
---|
78 | use perfSONAR_PS::Utils::ParameterValidation; |
---|
79 | |
---|
80 | our $DEBUGFLAG; |
---|
81 | our %opts = (); |
---|
82 | our $help_needed; |
---|
83 | |
---|
84 | my $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 | |
---|
95 | if ( not $ok or $help_needed ) { |
---|
96 | print_help(); |
---|
97 | exit( 1 ); |
---|
98 | } |
---|
99 | |
---|
100 | our $level = $INFO; |
---|
101 | $level = $DEBUG if $DEBUGFLAG; |
---|
102 | |
---|
103 | Log::Log4perl->easy_init( $level ); |
---|
104 | my $logger = get_logger( "perfSONAR_PS" ); |
---|
105 | |
---|
106 | my $host = q{}; |
---|
107 | my $port = q{}; |
---|
108 | my $endpoint = q{}; |
---|
109 | my $filter = '/'; |
---|
110 | my $file = q{}; |
---|
111 | my $starttime= q{}; |
---|
112 | my $endtime= q{}; |
---|
113 | my $montype= q{}; |
---|
114 | my $interface= q{}; |
---|
115 | my $device= q{}; |
---|
116 | my $devhost= q{}; |
---|
117 | if ( 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 | } |
---|
126 | else { |
---|
127 | print_help(); |
---|
128 | croak "Invalid number of parameters: must be 1 for a uri"; |
---|
129 | } |
---|
130 | |
---|
131 | my $syear = q {}; |
---|
132 | my $smon = q {}; |
---|
133 | my $sday = q {}; |
---|
134 | my $shour = q {}; |
---|
135 | my $smin = q {}; |
---|
136 | my $ssec = q {}; |
---|
137 | my $eyear = q {}; |
---|
138 | my $emon = q {}; |
---|
139 | my $eday = q {}; |
---|
140 | my $ehour = q {}; |
---|
141 | my $emin = q {}; |
---|
142 | my $esec = q {}; |
---|
143 | |
---|
144 | if ( defined $opts{HOST} ) { |
---|
145 | $host = $opts{HOST}; |
---|
146 | } |
---|
147 | if ( defined $opts{PORT} ) { |
---|
148 | $port = $opts{PORT}; |
---|
149 | } |
---|
150 | if ( defined $opts{ENDPOINT} ) { |
---|
151 | $endpoint = $opts{ENDPOINT}; |
---|
152 | } |
---|
153 | if ( defined $opts{FILTER} ) { |
---|
154 | $filter = $opts{FILTER}; |
---|
155 | } |
---|
156 | if ( 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 | } |
---|
164 | if ( 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 | } |
---|
172 | if ( defined $opts{TYPE} ) { |
---|
173 | $montype= $opts{TYPE}; |
---|
174 | } |
---|
175 | if ( defined $opts{INTERFACE} ) { |
---|
176 | $interface= $opts{INTERFACE}; |
---|
177 | } |
---|
178 | if ( defined $opts{DEVICE} ) { |
---|
179 | ($device,$devhost)= split(':',$opts{DEVICE}); |
---|
180 | } |
---|
181 | |
---|
182 | unless ( $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 | } |
---|
186 | my $id=0; |
---|
187 | |
---|
188 | my $xmlf; |
---|
189 | if (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 | } |
---|
211 | elsif (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 | } |
---|
220 | else { |
---|
221 | print "Currently only INFINERA and POLATIS devices are supported.\n"; |
---|
222 | } |
---|
223 | |
---|
224 | my $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"; |
---|
236 | my $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 |
---|
254 | my $sender = new perfSONAR_PS::Transport( $host, $port, $endpoint ); |
---|
255 | |
---|
256 | # Make a SOAP envelope, use the XML file as the body. |
---|
257 | my $envelope = &perfSONAR_PS::Common::makeEnvelope( $xmlf_header.$xmlf.$xmlf_tail ); |
---|
258 | my $error; |
---|
259 | |
---|
260 | # Send/receive to the server, store the response for later processing |
---|
261 | my $responseContent = $sender->sendReceive( $envelope, q{}, \$error ); |
---|
262 | |
---|
263 | croak "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 | |
---|
268 | exit( 0 ); |
---|
269 | |
---|
270 | =head2 dump( { response, find } ) |
---|
271 | |
---|
272 | Print out results of service message. |
---|
273 | |
---|
274 | =cut |
---|
275 | |
---|
276 | sub 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 | } |
---|
322 | if (defined $opts{PLOT}){ |
---|
323 | close FILE; |
---|
324 | my %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; |
---|
329 | set term x11 |
---|
330 | set xdata time |
---|
331 | set timefmt "%b-%d-%H:%M:%S" |
---|
332 | set output "load.png" |
---|
333 | set xrange ["$months{$smon}-$sday-$shour:$smin:00":"$months{$emon}-$eday-$ehour:$emin:00"] |
---|
334 | set yrange [0:-50] |
---|
335 | set grid |
---|
336 | set xlabel "Date\\nTime" |
---|
337 | set ylabel "$montype" |
---|
338 | set title "$device-$devhost" |
---|
339 | plot "temp" using 1:2 index 0 title "port: $interface" with lines |
---|
340 | pause 30 |
---|
341 | EOF |
---|
342 | } |
---|
343 | elsif (uc $montype eq 'PREFEC-BER'){ |
---|
344 | print GNUPLOT<<EOF; |
---|
345 | set term x11 |
---|
346 | set xdata time |
---|
347 | set timefmt "%b-%d-%H:%M:%S" |
---|
348 | set output "load.png" |
---|
349 | set xrange ["$months{$smon}-$sday-$shour:$smin:00":"$months{$emon}-$eday-$ehour:$emin:00"] |
---|
350 | set yrange [0:-30] |
---|
351 | set grid |
---|
352 | set xlabel "Date\\nTime" |
---|
353 | set ylabel "$montype (BER=2^y)" |
---|
354 | set title "$device-$devhost" |
---|
355 | plot "temp" using 1:2 index 0 title "port: $interface" with lines |
---|
356 | pause 30 |
---|
357 | EOF |
---|
358 | } |
---|
359 | close(GNUPLOT); |
---|
360 | } |
---|
361 | return; |
---|
362 | } |
---|
363 | |
---|
364 | =head2 help() |
---|
365 | |
---|
366 | Print a help message |
---|
367 | |
---|
368 | =cut |
---|
369 | |
---|
370 | sub 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 | |
---|
380 | L<use Getopt::Long>, L<perfSONAR_PS::DB::XMLDB> |
---|
381 | |
---|
382 | To join the 'perfSONAR Users' mailing list, please visit: |
---|
383 | |
---|
384 | https://lists.internet2.edu/sympa/info/perfsonar-ps-users |
---|
385 | |
---|
386 | The perfSONAR-PS subversion repository is located at: |
---|
387 | |
---|
388 | http://anonsvn.internet2.edu/svn/perfSONAR-PS/trunk |
---|
389 | |
---|
390 | Questions and comments can be directed to the author, or the mailing list. |
---|
391 | Bugs, 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 | |
---|
401 | Jason Zurawski, zurawski@internet2.edu |
---|
402 | Yee-Ting Li <ytl@slac.stanford.edu> |
---|
403 | |
---|
404 | =head1 LICENSE |
---|
405 | |
---|
406 | You should have received a copy of the Internet2 Intellectual Property Framework |
---|
407 | along with this software. If not, see |
---|
408 | <http://www.internet2.edu/membership/ip.html> |
---|
409 | |
---|
410 | =head1 COPYRIGHT |
---|
411 | |
---|
412 | Copyright (c) 2004-2010, Internet2 and the University of Delaware |
---|
413 | |
---|
414 | All rights reserved. |
---|
415 | |
---|
416 | =cut |
---|