File Coverage

blib/lib/Net/RDEP.pm
Criterion Covered Total %
statement 44 241 18.2
branch 7 100 7.0
condition 2 45 4.4
subroutine 11 23 47.8
pod 11 11 100.0
total 75 420 17.8


line stmt bran cond sub pod time code
1             # Net::RDEP.pm
2             #
3             # $Id: RDEP.pm,v 1.1 2004/12/23 12:05:58 jminieri Exp $
4             #
5             # Copyright (c) 2004 Joe Minieri and OpenService (www.open.com).
6             # All rights reserved.
7             # This program is free software; you can redistribute it and/or modify it under the same
8             # terms as Perl itself.
9             #
10              
11             package Net::RDEP;
12              
13 1     1   28093 use 5.006001;
  1         4  
  1         68  
14 1     1   6 use strict;
  1         2  
  1         39  
15 1     1   6 use warnings;
  1         6  
  1         35  
16              
17 1     1   896 use MIME::Base64;
  1         1246  
  1         79  
18 1     1   6358 use LWP::UserAgent;
  1         107688  
  1         97  
19              
20             # Items to export into callers namespace by default. Note: do not export
21             # names by default without a very good reason. Use EXPORT_OK instead.
22             # Do not simply export all your public functions/methods/constants.
23              
24             our $VERSION = '0.03';
25              
26             my %_eventTypes = (
27             'evError', 1,
28             'evAlert', 1,
29             'evStatus', 1,
30             'evLogTransaction', 1,
31             'evShunRqst', 1
32             );
33              
34             my %_alertSeverities = (
35             'informational', 1,
36             'low', 1,
37             'medium', 1,
38             'high', 1
39             );
40              
41             my %_errorSeverities = (
42             'warning', 1,
43             'error', 1,
44             'fatal', 1
45             );
46              
47             ##########################################################################################
48             #
49             # AUTOLOAD get/set methods when they're generic
50             #
51 1     1   11 use vars '$AUTOLOAD';
  1         2  
  1         55  
52             sub AUTOLOAD {
53 1     1   4 no strict 'refs';
  1         2  
  1         3293  
54 5     5   984 my ($self, $value) = @_;
55              
56 5         36 my $key =($AUTOLOAD =~ /.*::([_\w]+)$/)[0];
57              
58 5 50 33     40 unless(defined($key) and exists($self->{ $key })) {
59 0         0 $self->error(1);
60 0         0 $self->errorString("No such parameter $key");
61 0         0 return undef;
62             }
63              
64             # set this up for next time
65 5         18 *{$AUTOLOAD} = sub {
66 2     2   7 my ($self, $value) = @_;
67 2 50       5 if (defined($value)) {
68 0         0 return $self->{ $key } = $value;
69             } else {
70 2 50       129 return defined($self->{ $key })?$self->{ $key }:undef;
71             }
72 5         22 };
73              
74             # go ahead and execute it this time
75 5 100       53 if ( defined( $value )) {
76             # set operation
77 2         13 return $self->{ $key } = $value;
78             } else {
79             # get operation
80 3 50       21 return defined($self->{ $key })?$self->{ $key }:undef;
81             }
82             }
83              
84             ##########################################################################################
85             #
86             # Helper methods
87             #
88             sub _make_uri {
89 0     0   0 my $self = shift;
90              
91 0         0 my $URI = URI->new();
92 0         0 $URI->scheme('https');
93 0         0 $URI->host( $self->Server );
94 0         0 $URI->port( $self->Port );
95 0         0 $URI->path( $self->Path );
96              
97 0         0 return $URI->as_string;
98             }
99              
100             ##########################################################################################
101             #
102             # Non-generic get/set methods
103             #
104             sub _processTraits {
105 0     0   0 my $self = shift;
106 0         0 my $whichTraits = shift;
107              
108 0         0 $self->error(undef);
109 0         0 $self->errorString(undef);
110              
111 0 0 0     0 unless(defined($whichTraits) and exists($self->{ $whichTraits })) {
112 0         0 $self->error(1);
113 0         0 $self->errorString("No such trait attribute: $whichTraits");
114 0         0 return undef;
115             }
116              
117             # the spec for this parameter isn't clear -- I'm going to assume this
118             # goes from 0-15 instead of 1-16.
119              
120 0         0 my @traits;
121 0         0 foreach my $trait ( @_ ) {
122 0 0 0     0 if( $trait =~ /^\d+$/ and $trait <16 and $trait >-1 ) {
    0 0        
      0        
      0        
      0        
      0        
      0        
123             # individual trait
124 0         0 push(@traits, $trait);
125             } elsif ( $trait =~ /^(\d+)-(\d+)$/ and
126             $1 <16 and $1>-1 and
127             $2 <16 and $2>-1 and
128             $1 < $2 ) {
129             # trait range
130 0         0 push(@traits, $trait);
131             }
132             }
133              
134 0 0       0 if($#traits > -1) {
135             # note -- the spec shows examines with a ',' separating the traits
136             # and specifies a '+' between them. I'm going with the example.
137 0         0 return $self->{ $whichTraits } = join(',', @traits);
138             } else {
139 0         0 $self->error(1);
140 0         0 $self->errorString("No valid alarm traits: " . join(',', @_));
141 0         0 return undef;
142             }
143             }
144              
145             sub mustHaveAlarmTraits {
146 0     0 1 0 my $self = shift;
147              
148 0 0       0 unless(defined($_[0])) {
149             # if no parameter, the treat as "get" method
150 0         0 return $self->{ 'mustHaveAlarmTraits' };
151             }
152              
153 0         0 return $self->_processTraits('mustHaveAlarmTraits', @_);
154             }
155              
156             sub mustNotHaveAlarmTraits {
157 0     0 1 0 my $self = shift;
158              
159 0 0       0 unless(defined($_[0])) {
160             # if no parameter, the treat as "get" method
161 0         0 return $self->{ 'mustNotHaveAlarmTraits' };
162             }
163              
164 0         0 return $self->_processTraits('mustNotHaveAlarmTraits', @_);
165             }
166              
167              
168             sub errorSeverities {
169 0     0 1 0 my $self = shift;
170 0         0 my $error = shift;
171              
172 0         0 $self->error(undef);
173 0         0 $self->errorString(undef);
174              
175 0 0       0 unless(defined($error)) {
176             # if no parameter, the treat as "get" method
177 0         0 return $self->{ 'errorSeverities' };
178             }
179              
180 0         0 $error = lc($error);
181 0 0       0 if(exists($_errorSeverities{ $error })) {
182 0         0 return $self->{ 'errorSeverities' } = $error
183             } else {
184 0         0 $self->error(1);
185 0         0 $self->errorString("Invalid error severity: $error");
186              
187 0         0 return undef;
188             }
189             }
190              
191             sub alertSeverities {
192 0     0 1 0 my $self = shift;
193              
194 0         0 $self->error(undef);
195 0         0 $self->errorString(undef);
196              
197 0 0       0 unless(defined($_[0])) {
198             # if no parameter, the treat as "get" method
199 0         0 return $self->{ 'alertSeverities' };
200             }
201              
202 0         0 my @alertseverities;
203 0         0 foreach my $s ( @_ ) {
204 0         0 my $severity = lc($s);
205 0 0       0 if(exists($_alertSeverities{ $severity })) {
206 0         0 push(@alertseverities, $severity);
207             }
208             }
209              
210 0 0       0 if($#alertseverities > -1) {
211 0         0 return $self->{ 'alertSeverities' } = join('+', @alertseverities);
212             } else {
213 0         0 $self->error(1);
214 0         0 $self->errorString("No valid alert severities: " . join(',', @_));
215 0         0 return undef;
216             }
217             }
218              
219             sub events {
220 0     0 1 0 my $self = shift;
221              
222 0 0       0 unless(defined($_[0])) {
223             # if no parameter, the treat as "get" method
224 0         0 return $self->{ 'events' };
225             }
226              
227 0         0 $self->error(undef);
228 0         0 $self->errorString(undef);
229              
230 0         0 my @eventList;
231              
232             my %dedup;
233 0         0 foreach my $eventtype ( grep( !$dedup{ $_ }++, @_ ) ) {
234 0 0       0 if(exists($_eventTypes{ $eventtype })) {
235 0         0 push(@eventList, $eventtype);
236             }
237             }
238              
239 0 0       0 if($#eventList > -1) {
240 0         0 return $self->{ 'events' } = join('+', @eventList);
241             } else {
242 0         0 $self->error(1);
243 0         0 $self->errorString("No valid event types: " . join(',', @_));
244 0         0 return undef;
245             }
246             }
247              
248             sub confirm {
249 0     0 1 0 my $self = shift;
250 0         0 my $confirm = shift;
251              
252 0 0       0 unless(defined($confirm)) {
253             # if no parameter, the treat as "get" method
254 0         0 return $self->{ 'confirm' };
255             }
256              
257 0         0 $self->error(undef);
258 0         0 $self->errorString(undef);
259              
260 0         0 $confirm = lc($confirm);
261 0 0 0     0 if($confirm eq 'no' or $confirm eq 'yes') {
262 0         0 return $self->{ 'confirm' } = $confirm;
263             } else {
264 0         0 $self->error(1);
265 0         0 $self->errorString("Invalid confirm value: $confirm");
266 0         0 return undef;
267             }
268             }
269              
270             sub Type {
271 0     0 1 0 my $self = shift;
272 0         0 my $type = shift;
273              
274 0 0       0 unless(defined($type)) {
275             # if no parameter, the treat as "get" method
276 0         0 return $self->{ 'Type' };
277             }
278              
279 0         0 $self->error(undef);
280 0         0 $self->errorString(undef);
281              
282 0         0 $type = lc($type);
283 0 0 0     0 if($type eq 'subscription' or $type eq 'query') {
284 0         0 return $self->{ 'Type' } = $type;
285             } else {
286 0         0 $self->error(1);
287 0         0 $self->errorString("Invalid RDEP connection type: $type");
288 0         0 return undef;
289             }
290             }
291              
292             ##########################################################################################
293             #
294             sub new {
295 1     1 1 14 my $caller = shift;
296 1         3 my %attr = @_;
297              
298 1   33     9 my $class = (ref($caller) or $caller);
299 1         25 my $self = bless {
300             # connection parameters
301             'Server', => '127.0.0.1',
302             'Port', => 443,
303             'UserAgent', => 'RDEP Client/4.0',
304             'Username', => 'username',
305             'Password', => 'password',
306             'Path', => '/cgi-bin/event-server',
307             'state', => 'closed',
308             # subscription parameters
309             'Type', => 'subscription',
310             'Cookie', => undef,
311             'Authorization', => undef,
312             'subscriptionId', => undef,
313             # retrieval parameters
314             'startTime', => undef,
315             'stopTime', => undef, # only for queries
316             'events', => 'evAlert',
317             'alertSeverities', => undef,
318             'errorSeverities', => undef,
319             'mustHaveAlarmTraits', => undef,
320             'mustNotHaveAlarmTraits', => undef,
321             'timeout', => 1,
322             'maxNbrOfEvents', => 20, # set this just so we don't crush the box
323             'confirm', => 'yes',
324             # results
325             'missedEvents', => undef,
326             'error', => undef,
327             'errorString', => undef
328             }, $class;
329              
330 1         6 foreach my $attribute ( keys %attr ) {
331 0         0 $self->$attribute( $attr{ $attribute });
332             }
333              
334 1         12 $self->state('closed');
335 1         8 $self->missedEvents(undef);
336 1         8 $self->error(undef);
337 1         8 $self->errorString(undef);
338              
339 1         4 return $self;
340              
341             }
342              
343             sub open {
344 0     0 1 0 my $self = shift;
345              
346 0         0 $self->error(undef);
347 0         0 $self->errorString(undef);
348              
349 0         0 my $http_auth = $self->Username . ':' . $self->Password;
350 0         0 $self->Authorization('Basic ' . MIME::Base64::encode( $http_auth, ''));
351              
352 0         0 my %headers = (
353             'User-Agent' => $self->UserAgent,
354             'Authorization' => $self->Authorization
355             );
356              
357             # manditory parameters for subscription
358 0         0 my %form_parameters = (
359             events => $self->events
360             );
361              
362 0 0       0 if ($self->Type eq 'subscription') {
363 0         0 $form_parameters{ 'action' } = 'open';
364 0 0       0 if (defined($self->timeout)) {
365 0         0 $form_parameters{ 'timeout' } = $self->timeout;
366             }
367 0 0       0 if (defined($self->confirm)) {
368 0         0 $form_parameters{ 'confirm' } = $self->confirm;
369             }
370             }
371              
372 0 0       0 if (defined($self->startTime)) {
373 0         0 $form_parameters{ 'startTime' } = $self->startTime;
374             }
375              
376 0 0       0 if (defined($self->maxNbrOfEvents)) {
377 0         0 $form_parameters{ 'maxNbrOfEvents' } = $self->maxNbrOfEvents;
378             }
379              
380 0 0       0 if (defined($self->mustHaveAlarmTraits)) {
381 0         0 $form_parameters{ 'mustHaveAlarmTraits' } = $self->mustHaveAlarmTraits;
382             }
383              
384 0 0       0 if (defined($self->mustNotHaveAlarmTraits)) {
385 0         0 $form_parameters{ 'mustNotHaveAlarmTraits' } = $self->mustNotHaveAlarmTraits;
386             }
387              
388 0 0       0 if (defined($self->alertSeverities)) {
389 0         0 $form_parameters{ 'alertSeverities' } = $self->alertSeverities;
390             }
391              
392 0 0       0 if (defined($self->errorSeverities)) {
393 0         0 $form_parameters{ 'errorSeverities' } = $self->errorSeverities;
394             }
395              
396 0 0 0     0 if ($self->Type eq 'query' and defined($self->stopTime)) {
397 0         0 $form_parameters{ 'stopTime' } = $self->stopTime;
398             }
399              
400 0         0 my $LWP = LWP::UserAgent->new();
401 0         0 my $result = $LWP->post($self->_make_uri, \%form_parameters, %headers);
402              
403 0 0       0 if($result->is_success) {
404 0 0       0 if($self->Type eq 'subscription' ) {
405 0 0       0 if(my $cookie = $result->header('Set-Cookie')) {
406 0         0 $self->Cookie((split(';', $cookie))[0]);
407             } else {
408 0         0 $self->error(1);
409 0         0 $self->errorString( "No Cookie in header: " . $result->status_line);
410 0         0 return undef;
411             }
412              
413 0 0       0 if(my $parameter = $result->header('X-CISCO-RDEP-PARAMETERS')) {
414 0         0 $self->subscriptionId((split('=',$parameter))[1]);
415             } else {
416 0         0 $self->error(1);
417 0         0 $self->errorString( "No subscription ID in header: " . $result->status_line);
418 0         0 return undef;
419             }
420              
421 0         0 $self->state('opened');
422             }
423             } else {
424 0         0 $self->error(1);
425 0         0 $self->errorString( "Query failed: " . $result->status_line);
426             }
427              
428             # on a subscription open, there is no content. On a query, the content is the events
429 0         0 return $result->content;
430             }
431              
432             sub get {
433 0     0 1 0 my $self = shift;
434              
435 0         0 $self->error(undef);
436 0         0 $self->errorString(undef);
437              
438             # if we're just doing a query, return the "open";
439 0 0       0 if( $self->Type eq 'query' ) { return $self->open() }
  0         0  
440              
441             # if we're doing a subscription, open first, the proceed
442 0 0       0 if( $self->state eq 'closed' ) { $self->open() }
  0         0  
443              
444             #
445             # only event subscriptions should be here
446 0         0 my %headers = (
447             'User-Agent' => $self->UserAgent,
448             'Authorization' => $self->Authorization,
449             'Cookie' => $self->Cookie
450             );
451              
452 0         0 my %form_parameters = (
453             'action' => 'get',
454             'subscriptionId' => $self->subscriptionId
455             );
456              
457 0 0       0 if (defined($self->timeout)) {
458 0         0 $form_parameters{ 'timeout' } = $self->timeout;
459             }
460              
461 0 0       0 if (defined($self->confirm)) {
462 0         0 $form_parameters{ 'confirm' } = $self->confirm;
463             }
464              
465 0 0       0 if (defined($self->maxNbrOfEvents)) {
466 0         0 $form_parameters{ 'maxNbrOfEvents' } = $self->maxNbrOfEvents;
467             }
468              
469 0         0 my $LWP = LWP::UserAgent->new();
470 0         0 my $result = $LWP->post($self->_make_uri, \%form_parameters, %headers);
471              
472 0 0       0 if($result->is_success) {
473 0 0       0 if(my $cookie = $result->header('Set-Cookie')) {
474 0         0 $self->Cookie((split(';', $cookie))[0]);
475             }
476              
477 0 0       0 if(my $parameter = $result->header('X-CISCO-RDEP-PARAMETERS')) {
478 0         0 my ($name, $value) = split('=', $parameter);
479 0 0       0 if($name eq 'missedEvents') {
480 0 0       0 if($value eq 'true') {
481 0         0 $self->missedEvents(1);
482 0         0 $self->error(1);
483 0         0 $self->errorString( "Events were dropped between polls");
484             } else {
485 0         0 $self->missedEvents(undef);
486             }
487             }
488             }
489 0         0 $self->state('opened');
490 0         0 return $result->content;
491             } else {
492 0         0 $self->error(1);
493 0         0 $self->errorString( "Query failed: " . $result->status_line);
494 0         0 $self->state('closed');
495 0         0 return undef;
496             }
497             }
498              
499             sub close {
500 0     0 1 0 my $self = shift;
501              
502 0         0 $self->error(undef);
503 0         0 $self->errorString(undef);
504              
505 0 0 0     0 return if( $self->state eq 'closed' or $self->Type eq 'query' );
506              
507 0         0 my %headers = (
508             'User-Agent' => $self->UserAgent,
509             'Authorization' => $self->Authorization,
510             'Cookie' => $self->Cookie
511             );
512              
513             # manditory parameters for subscription
514 0         0 my %form_parameters = (
515             action => 'close',
516             subscriptionId => $self->subscriptionId
517             );
518              
519 0         0 my $LWP = LWP::UserAgent->new();
520 0         0 my $result = $LWP->post($self->_make_uri, \%form_parameters, %headers);
521              
522 0         0 $self->state('closed');
523 0 0 0     0 if(defined($result) and $result->is_success) {
524 0         0 return $result->content;
525             } else {
526 0         0 $self->error(1);
527 0         0 $self->errorString( "Query failed: " . $result->status_line);
528 0         0 return undef;
529             }
530             }
531              
532             #
533             # close connection, just in case we forgot to call close() properly
534             sub DESTROY {
535 1     1   732 my $self = shift;
536              
537 1 50       5 if($self->state eq 'opened') { $self->close() }
  0            
538             }
539              
540             #
541             ##########################################################################################
542              
543             1;
544             __END__