File Coverage

blib/lib/Siebel/Srvrmgr/ListParser/FSA.pm
Criterion Covered Total %
statement 165 194 85.0
branch 34 46 73.9
condition 5 9 55.5
subroutine 51 60 85.0
pod 4 4 100.0
total 259 313 82.7


line stmt bran cond sub pod time code
1             package Siebel::Srvrmgr::ListParser::FSA;
2              
3 21     21   150 use warnings;
  21         51  
  21         815  
4 21     21   126 use strict;
  21         183  
  21         504  
5 21     21   119 use Siebel::Srvrmgr;
  21         46  
  21         532  
6 21     21   124 use Siebel::Srvrmgr::Regexes qw(SRVRMGR_PROMPT prompt_slices);
  21         43  
  21         1225  
7              
8 21     21   133 use parent 'FSA::Rules';
  21         49  
  21         197  
9              
10             our $VERSION = '0.29'; # VERSION
11              
12             =pod
13              
14             =head1 NAME
15              
16             Siebel::Srvrmgr::ListParser::FSA - the FSA::Rules class specification for Siebel::Srvrmgr::ListParser
17              
18             =head1 SYNOPSIS
19              
20             use FSA::Rules;
21             my $fsa = Siebel::Srvrmgr::ListParser::FSA->get_fsa();
22             # do something with $fsa
23              
24             # for getting a diagram exported in your currently directory with a onliner
25             perl -MSiebel::Srvrmgr::ListParser::FSA -e "Siebel::Srvrmgr::ListParser::FSA->export_diagram"
26              
27             =head1 DESCRIPTION
28              
29             Siebel::Srvrmgr::ListParser::FSA subclasses the state machine implemented by L<FSA::Rules>, which is used by L<Siebel::Srvrmgr::ListParser> class.
30              
31             This class also have a L<Log::Log4perl> instance built in.
32              
33             =head1 EXPORTS
34              
35             Nothing.
36              
37             =head1 METHODS
38              
39             =head2 export_diagram
40              
41             Creates a PNG file with the state machine diagram in the current directory where the method was invoked.
42              
43             =cut
44              
45             sub export_diagram {
46              
47 0     0 1 0 my $fsa = get_fsa();
48              
49 0         0 my $graph = $fsa->graph( layout => 'neato', overlap => 'false' );
50 0         0 $graph->as_png('pretty.png');
51              
52 0         0 return 1;
53              
54             }
55              
56             =pod
57              
58             =head2 new
59              
60             Returns the state machine object defined for usage with a L<Siebel::Srvrmgr::ListParser> instance.
61              
62             Expects as parameter a hash table reference containing all the commands alias as keys and their respective regular expressions to detect
63             state change as values. See L<Siebel::Srvrmgr::ListParser::OutputFactory> C<get_mapping> method for details.
64              
65             =cut
66              
67             sub new {
68              
69 81     81 1 247 my $class = shift;
70 81         203 my $map_ref = shift;
71              
72 81         574 my $logger =
73             Siebel::Srvrmgr->gimme_logger('Siebel::Srvrmgr::ListParser::FSA');
74              
75 81 50 33     12146 $logger->logdie('the output type mapping reference received is not valid')
76             unless ( ( defined($map_ref) ) and ( ref($map_ref) eq 'HASH' ) );
77              
78             my %params = (
79             done => sub {
80              
81 50459     50459   591619 my $self = shift;
82              
83 50459         81213 my $curr_line = shift( @{ $self->{data} } );
  50459         129628  
84              
85 50459 100       122889 if ( defined($curr_line) ) {
86              
87 50397 50 66     131693 if ( defined( $self->notes('last_command') )
88             and ( $self->notes('last_command') eq 'exit' ) )
89             {
90              
91 0         0 return 1;
92              
93             }
94             else {
95              
96 50397         1071470 $self->{curr_line} = $curr_line;
97 50397         190918 return 0;
98              
99             }
100              
101             }
102             else { # no more lines to process
103              
104 62         366 return 1;
105              
106             }
107              
108             }
109 81         846 );
110              
111             my $self = $class->SUPER::new(
112             \%params,
113             no_data => {
114             do => sub {
115              
116 62     62   6022 my $logger =
117             Siebel::Srvrmgr->gimme_logger('Siebel::Srvrmgr::ListParser');
118              
119 62 50       2675 if ( $logger->is_debug() ) {
120              
121 0         0 $logger->debug('Searching for useful data');
122              
123             }
124              
125             },
126             rules => [
127             greetings => sub {
128              
129 140     140   4114 my $state = shift;
130              
131 140         561 my $line = $state->machine()->{curr_line};
132              
133 140 100       1014 if ( defined($line) ) {
134              
135 78         675 return ( $line =~ $map_ref->{greetings} );
136              
137             }
138             else {
139              
140 62         243 return 0;
141              
142             }
143              
144             },
145             command_submission => sub {
146              
147 124     124   1159 my $state = shift;
148 124         433 my $line = $state->machine()->{curr_line};
149              
150 124 100       2274 if ( defined($line) ) {
151              
152 62         353 return ( $line =~ SRVRMGR_PROMPT );
153              
154             }
155             else {
156              
157 62         216 return 0;
158              
159             }
160              
161             },
162             ],
163             message => 'Line read'
164              
165             },
166             greetings => {
167             label => 'greetings message from srvrmgr',
168             on_enter => sub {
169              
170 16     16   1202 my $state = shift;
171 16         88 $state->notes( is_cmd_changed => 0 );
172 16         358 $state->notes( is_data_wanted => 1 );
173 16 50       287 $state->notes( 'create_greetings' => 1 )
174             unless ( $state->notes('greetings_created') );
175             },
176             on_exit => sub {
177              
178 16     16   697 my $state = shift;
179 16         93 $state->notes( is_data_wanted => 0 );
180              
181             },
182             rules => [
183             command_submission => sub {
184              
185 295     295   7322 my $state = shift;
186 295         922 my $line = $state->machine()->{curr_line};
187 295         2009 return ( $line =~ SRVRMGR_PROMPT );
188              
189             },
190             ],
191             message => 'prompt found'
192             },
193             end => {
194             do => sub {
195              
196 0     0   0 my $logger =
197             Siebel::Srvrmgr->gimme_logger('Siebel::Srvrmgr::ListParser');
198 0         0 $logger->debug('Enterprise says bye-bye');
199              
200             },
201             rules => [
202             no_data => sub {
203 0     0   0 return 1;
204             }
205             ],
206             message => 'EOF'
207             },
208             list_comp => {
209             label => 'parses output from a list comp command',
210             on_enter => sub {
211 31     31   2297 my $state = shift;
212 31         148 $state->notes( is_cmd_changed => 0 );
213 31         630 $state->notes( is_data_wanted => 1 );
214             },
215             on_exit => sub {
216              
217 22     22   1399 my $state = shift;
218 22         164 $state->notes( is_data_wanted => 0 );
219              
220             },
221             rules => [
222             command_submission => sub {
223              
224 2518     2518   59235 my $state = shift;
225 2518         6896 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
226              
227             },
228             ],
229             message => 'prompt found'
230             },
231             list_comp_types => {
232             label => 'parses output from a list comp types command',
233             on_enter => sub {
234 20     20   1309 my $state = shift;
235 20         88 $state->notes( is_cmd_changed => 0 );
236 20         360 $state->notes( is_data_wanted => 1 );
237             },
238             on_exit => sub {
239              
240 17     17   700 my $state = shift;
241 17         84 $state->notes( is_data_wanted => 0 );
242              
243             },
244             rules => [
245             command_submission => sub {
246              
247 5220     5220   114680 my $state = shift;
248 5220         13616 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
249              
250             },
251             ],
252             message => 'prompt found'
253             },
254             list_params => {
255             label => 'parses output from a list params command',
256             on_enter => sub {
257 25     25   1724 my $state = shift;
258 25         125 $state->notes( is_cmd_changed => 0 );
259 25         459 $state->notes( is_data_wanted => 1 );
260             },
261             on_exit => sub {
262              
263 22     22   925 my $state = shift;
264 22         107 $state->notes( is_data_wanted => 0 );
265              
266             },
267             rules => [
268             command_submission => sub {
269              
270 20125     20125   435503 my $state = shift;
271 20125         51540 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
272              
273             },
274             ],
275             message => 'prompt found'
276             },
277             list_comp_def => {
278             label => 'parses output from a list comp def command',
279             on_enter => sub {
280 31     31   2152 my $state = shift;
281 31         156 $state->notes( is_cmd_changed => 0 );
282 31         587 $state->notes( is_data_wanted => 1 );
283             },
284             on_exit => sub {
285              
286 25     25   1000 my $state = shift;
287 25         117 $state->notes( is_data_wanted => 0 );
288              
289             },
290             rules => [
291             command_submission => sub {
292              
293 3121     3121   66325 my $state = shift;
294 3121         7747 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
295              
296             },
297             ],
298             message => 'prompt found'
299             },
300             list_tasks => {
301             label => 'parses output from a list tasks command',
302             on_enter => sub {
303 22     22   1350 my $state = shift;
304 22         88 $state->notes( is_cmd_changed => 0 );
305 22         385 $state->notes( is_data_wanted => 1 );
306             },
307             on_exit => sub {
308              
309 20     20   819 my $state = shift;
310 20         92 $state->notes( is_data_wanted => 0 );
311              
312             },
313             rules => [
314             command_submission => sub {
315              
316 7719     7719   164085 my $state = shift;
317 7719         18810 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
318              
319             },
320             ],
321             message => 'prompt found'
322             },
323             list_procs => {
324             label => 'parses output from a list procs command',
325             on_enter => sub {
326 0     0   0 my $state = shift;
327 0         0 $state->notes( is_cmd_changed => 0 );
328 0         0 $state->notes( is_data_wanted => 1 );
329             },
330             on_exit => sub {
331              
332 0     0   0 my $state = shift;
333 0         0 $state->notes( is_data_wanted => 0 );
334              
335             },
336             rules => [
337             command_submission => sub {
338              
339 0     0   0 my $state = shift;
340 0         0 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
341              
342             },
343             ],
344             message => 'prompt found'
345             },
346             list_servers => {
347             label => 'parses output from a list servers command',
348             on_enter => sub {
349 4     4   297 my $state = shift;
350 4         29 $state->notes( is_cmd_changed => 0 );
351 4         66 $state->notes( is_data_wanted => 1 );
352             },
353             on_exit => sub {
354              
355 4     4   263 my $state = shift;
356 4         24 $state->notes( is_data_wanted => 0 );
357              
358             },
359             rules => [
360             command_submission => sub {
361              
362 72     72   1706 my $state = shift;
363 72         179 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
364              
365             },
366             ],
367             message => 'prompt found'
368             },
369             list_sessions => {
370             label => 'parses output from a list sessions command',
371             on_enter => sub {
372 21     21   1478 my $state = shift;
373 21         166 $state->notes( is_cmd_changed => 0 );
374 21         403 $state->notes( is_data_wanted => 1 );
375             },
376             on_exit => sub {
377              
378 21     21   873 my $state = shift;
379 21         139 $state->notes( is_data_wanted => 0 );
380              
381             },
382             rules => [
383             command_submission => sub {
384              
385 11040     11040   232892 my $state = shift;
386 11040         27930 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
387              
388             },
389             ],
390             message => 'prompt found'
391             },
392             set_delimiter => {
393             label => 'parses output (?) from set delimiter command',
394             on_enter => sub {
395 0     0   0 my $state = shift;
396 0         0 $state->notes( is_cmd_changed => 0 );
397 0         0 $state->notes( is_data_wanted => 1 );
398             },
399             on_exit => sub {
400              
401 0     0   0 my $state = shift;
402 0         0 $state->notes( is_data_wanted => 0 );
403              
404             },
405             rules => [
406             command_submission => sub {
407              
408 0     0   0 my $state = shift;
409 0         0 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
410              
411             },
412             ],
413             message => 'prompt found'
414             },
415             load_preferences => {
416             label => 'parses output from a load preferences command',
417             on_enter => sub {
418 18     18   1266 my $state = shift;
419 18         108 $state->notes( is_cmd_changed => 0 );
420 18         360 $state->notes( is_data_wanted => 1 );
421             },
422             on_exit => sub {
423              
424 17     17   704 my $state = shift;
425 17         74 $state->notes( is_data_wanted => 0 );
426              
427             },
428             rules => [
429             command_submission => sub {
430              
431 35     35   905 my $state = shift;
432 35         116 return ( $state->machine->{curr_line} =~ SRVRMGR_PROMPT );
433              
434             },
435             ],
436             message => 'prompt found'
437             },
438             command_submission => {
439             do => sub {
440              
441 208     208   16514 my $state = shift;
442              
443 208         1087 my $logger =
444             Siebel::Srvrmgr->gimme_logger('Siebel::Srvrmgr::ListParser');
445 208 50       8085 if ( $logger->is_debug() ) {
446              
447 0         0 my $line = $state->notes('line');
448 0 0       0 $logger->debug( 'command_submission got [' . $line . ']' )
449             if ( defined($line) );
450              
451             }
452              
453 208         2686 $state->notes( found_prompt => 1 );
454             my ( $server, $cmd ) =
455 208         4568 prompt_slices( $state->machine->{curr_line} );
456              
457 208 100 66     1530 if ( ( defined($cmd) ) and ( $cmd ne '' ) ) {
458 173 50       1235 $logger->debug("last_command set with '$cmd'")
459             if $logger->is_debug();
460 173         1697 $state->notes( last_command => $cmd );
461 173         3377 $state->notes( is_cmd_changed => 1 );
462             }
463             else {
464              
465 35 50       242 if ( $logger->is_debug() ) {
466 0         0 $logger->debug('got prompt, but no command submitted');
467             }
468              
469 35         453 $state->notes( last_command => '' );
470 35         764 $state->notes( is_cmd_changed => 1 );
471             }
472              
473             },
474             rules => [
475             set_delimiter => sub {
476              
477 174     174   4718 my $state = shift;
478              
479 174 50       663 if ( $state->notes('last_command') =~
480             $map_ref->{set_delimiter} )
481             {
482              
483 0         0 return 1;
484              
485             }
486             else {
487              
488 174         4031 return 0;
489              
490             }
491              
492             },
493             list_comp => sub {
494              
495 174     174   1542 my $state = shift;
496              
497 174 100       613 if (
498             $state->notes('last_command') =~ $map_ref->{list_comp} )
499             {
500              
501 31         806 return 1;
502              
503             }
504             else {
505              
506 143         3253 return 0;
507              
508             }
509              
510             },
511             list_comp_types => sub {
512              
513 143     143   1194 my $state = shift;
514              
515 143 100       444 if ( $state->notes('last_command') =~
516             $map_ref->{list_comp_types} )
517             {
518              
519 20         461 return 1;
520              
521             }
522             else {
523              
524 123         2920 return 0;
525              
526             }
527              
528             },
529             list_params => sub {
530              
531 123     123   1149 my $state = shift;
532              
533 123 100       553 if ( $state->notes('last_command') =~
534             $map_ref->{list_params} )
535             {
536              
537 25         670 return 1;
538              
539             }
540             else {
541              
542 98         2566 return 0;
543              
544             }
545              
546             },
547             list_tasks => sub {
548              
549 98     98   1013 my $state = shift;
550              
551 98 100       356 if ( $state->notes('last_command') =~
552             $map_ref->{list_tasks} )
553             {
554              
555 22         505 return 1;
556              
557             }
558             else {
559              
560 76         1625 return 0;
561              
562             }
563              
564             },
565             list_procs => sub {
566              
567 76     76   687 my $state = shift;
568              
569 76 50       267 if ( $state->notes('last_command') =~
570             $map_ref->{list_procs} )
571             {
572              
573 0         0 return 1;
574              
575             }
576             else {
577              
578 76         1547 return 0;
579              
580             }
581              
582             },
583             list_servers => sub {
584              
585 76     76   633 my $state = shift;
586              
587 76 100       263 if ( $state->notes('last_command') =~
588             $map_ref->{list_servers} )
589             {
590              
591 4         80 return 1;
592              
593             }
594             else {
595              
596 72         1622 return 0;
597              
598             }
599              
600             },
601             list_sessions => sub {
602              
603 72     72   646 my $state = shift;
604              
605 72 100       244 if ( $state->notes('last_command') =~
606             $map_ref->{list_sessions} )
607             {
608              
609 21         618 return 1;
610              
611             }
612             else {
613              
614 51         1068 return 0;
615              
616             }
617              
618             },
619             list_comp_def => sub {
620 51     51   427 my $state = shift;
621              
622 51 100       179 if ( $state->notes('last_command') =~
623             $map_ref->{list_comp_def} )
624             {
625 31         762 return 1;
626             }
627             else {
628 20         411 return 0;
629             }
630             },
631             load_preferences => sub {
632 20     20   169 my $state = shift;
633              
634 20 100       75 if ( $state->notes('last_command') =~
635             $map_ref->{load_preferences} )
636             {
637 18         427 return 1;
638             }
639             else {
640 2         25 return 0;
641             }
642             },
643             no_data => sub {
644 2     2   12 my $state = shift;
645              
646 2 50       4 if ( $state->notes('last_command') eq '' ) {
647 0         0 return 1;
648             }
649             else {
650 2         23 return 0;
651             }
652              
653             },
654              
655             # add other possibilities here of list commands
656 81         13396 ],
657             message => 'command submitted'
658             }
659             );
660              
661 81         93027 $self->{data} = undef;
662 81         286 $self->{curr_line} = undef;
663 81         4269 return $self;
664             }
665              
666             =head2 set_data
667              
668             Set the array reference of the data to be parsed by this object.
669              
670             =cut
671              
672             sub set_data {
673 62     62 1 216 my $self = shift;
674 62         268 $self->{data} = shift;
675             }
676              
677             =head2 get_curr_line
678              
679             Returns a string, the current line being processed by this object.
680              
681             =cut
682              
683             sub get_curr_line {
684              
685 50459     50459 1 182641 return shift->{curr_line};
686              
687             }
688              
689             1;
690              
691             =pod
692              
693             =head1 SEE ALSO
694              
695             =over
696              
697             =item *
698              
699             L<Siebel::Srvrmgr::ListParser>
700              
701             =item *
702              
703             L<FSA::Rules>
704              
705             =back
706              
707             =head1 CAVEATS
708              
709             This class has some problems, most due the API of L<FSA::Rules>: since the state machine is a group of references to subroutines, it holds references
710             to L<Siebel::Srvrmgr::ListParser>, which basically causes circular references between the two classes.
711              
712             There is some workaround to the caused memory leaks due this configuration, but in future releases L<FSA::Rules> may be replaced to something else.
713              
714             =head1 AUTHOR
715              
716             Alceu Rodrigues de Freitas Junior, E<lt>arfreitas@cpan.orgE<gt>.
717              
718             =head1 COPYRIGHT AND LICENSE
719              
720             This software is copyright (c) 2013 of Alceu Rodrigues de Freitas Junior, E<lt>arfreitas@cpan.orgE<gt>.
721              
722             This file is part of Siebel Monitoring Tools.
723              
724             Siebel Monitoring Tools is free software: you can redistribute it and/or modify
725             it under the terms of the GNU General Public License as published by
726             the Free Software Foundation, either version 3 of the License, or
727             (at your option) any later version.
728              
729             Siebel Monitoring Tools is distributed in the hope that it will be useful,
730             but WITHOUT ANY WARRANTY; without even the implied warranty of
731             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
732             GNU General Public License for more details.
733              
734             You should have received a copy of the GNU General Public License
735             along with Siebel Monitoring Tools. If not, see <http://www.gnu.org/licenses/>.
736              
737             =cut