File Coverage

blib/lib/Siebel/Srvrmgr/ListParser/FSA.pm
Criterion Covered Total %
statement 165 185 89.1
branch 34 44 77.2
condition 5 9 55.5
subroutine 50 56 89.2
pod 2 2 100.0
total 256 296 86.4


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