BGPmon-core-2

 view release on metacpan or  search on metacpan

lib/BGPmon/Fetch/Archive.pm  view on Meta::CPAN

package BGPmon::Fetch::Archive;
our $VERSION = '2.0';

use strict;
use warnings;
use POSIX qw/strftime/;
use File::Path qw/mkpath rmtree/;
use BGPmon::Translator::XFB2PerlHash;
use BGPmon::Fetch::File;
use LWP::Simple;
use Data::Dumper;

BEGIN{
require Exporter;
    our $AUTOLOAD;
    our @ISA = qw(Exporter);
    our %EXPORT_TAGS = ( 'all' => [ qw(init_bgpdata connect_archive 
      read_xml_message close_connection is_connected messages_read 
      files_read uptime connection_endtime connection_duration get_error_code 
      get_error_message get_error_msg) ] );
    our @EXPORT_OK = ( @{ $EXPORT_TAGS{'all'} } );
}

# connection status
my $msgs_read = 0;
my $files_read = 0;
my $connection_start;
my $connection_stop;
my $connected = 0;

#state variables to maintain state between calls to read_xml_message
my $upd_url;        #Root URL to retrieve update files from
my $begin_time;     #interval start time
my $end_time;       #interval end time
my $year;           #year/month used for URL construction
my $month;
my $append;         #variable detects /UPDATES/ dirs below the normal depth
my @index_page;     #list of HTML download links
my $scratch_dir = "/tmp/";
my $ignore_data_errors = 0;
my $ignore_incomplete_data = 0;

#Error codes and messages
my %error_code;
my %error_msg;
my @function_names = ('init_bgpdata', 'connect_archive', 'read_xml_message',
'close_connection', 'is_connected','uptime','connection_endtime',
'connection_duration');

use constant NO_ERROR_CODE => 0;
use constant NO_ERROR_MSG => 'No Error';
use constant UNDEFINED_ARGUMENT_CODE => 401;
use constant UNDEFINED_ARGUMENT_MSG => 'Undefined Argument(s)';
use constant UNCONNECTED_CODE => 402;
use constant UNCONNECTED_MSG => 'Not connected to an archive';
use constant ALREADY_CONNECTED_CODE => 403;
use constant ALREADY_CONNECTED_MSG => 'Already connected to an archive';
use constant NO_INDEX_PAGE_CODE => 404;
use constant NO_INDEX_PAGE_MSG => 'Unable to find an index page';
use constant SYSCALL_FAIL_CODE => 405;
use constant SYSCALL_FAIL_MSG => 'System call failed';
use constant INVALID_ARGUMENT_CODE => 406;
use constant INVALID_ARGUMENT_MSG => 'Invalid value given for argument';
use constant INIT_FAIL_CODE => 407;
use constant INIT_FAIL_MSG => 'Failed to initialize connection to archive';
use constant FILE_OPERATION_FAIL_CODE => 408;
use constant FILE_OPERATION_FAIL_MSG => 'File operation failed';
use constant DOWNLOAD_FAIL_CODE => 409;
use constant DOWNLOAD_FAIL_MSG => 'Failed to download file';
use constant INVALID_MESSAGE_CODE => 410;
use constant INVALID_MESSAGE_MSG => 'Invalid message read';
use constant INVALID_FUNCTION_SPECIFIED_CODE => 411;
use constant INVALID_FUNCTION_SPECIFIED_MSG => 'Invalid function specified';
use constant IGNORE_ERROR_CODE => 412;
use constant IGNORE_ERROR_MSG => 
  'Cannot have ignore_incomplete_data off with ignore_data_errors on';

for my $function_name (@function_names) {
    $error_code{$function_name} = NO_ERROR_CODE;
    $error_msg{$function_name} = NO_ERROR_MSG;
}

END{
    my $errs;
    rmtree($scratch_dir,{keep_root => 1, safe => 1, error => \$errs});
}

=head1 NAME

BGPmon::Fetch::Archive

The BGPmon::Fetch::Archive module, to connect to an online archive of
BGP files, download XML files and read XML messages one at a time.

=head1 SYNOPSIS

The BGPmon::Fetch::Archive module provides functionality to connect
to an BGP archive and read one XML message at a time.

    use BGPmon::Fetch::Archive;
    my $ret = init_bgpdata('scratch_dir' => '/tmp/',
'ignore_incomplete_data' => 1, 'ignore_data_errors' => 0);
    my $ret = connect_archive('archive.netsec.colostate.edu/collectors/bgpdata-netsec/',
1234567890,2345678901);
    my $xml_msg = read_xml_message();
    my $ret = is_connected();
    my $num_read = messages_read();
    my $num_files = files_read();
    my $uptime = uptime();
    my $ret = close_connection();
    my $downtime = connection_endtime();
    my $duration = connection_duration();

=head1 EXPORT

init_bgpdata
connect_archive
read_xml_message

lib/BGPmon/Fetch/Archive.pm  view on Meta::CPAN

    close($index_fh);
    return 0;
}

# download_URL
#
#Downloads a target file and saves it to a user-specified file
#This function is primarily a wrapper around several functions of
# the LWP::Simple module.
#Input:        a target URL, either an HTML index or another file
#              an output file name
#Output:       0 on success, 1 on failure

sub download_URL{
    my $fname = "download_URL";

    #Get argument(s) and check that they exist
    my $target_url = shift;
    my $output = shift;

    #If the target is not defined, obviously that is a problem
    if(!defined($target_url) || $target_url eq "" || 
       !defined($output) || $output eq "" ){
        $error_code{$fname} = UNDEFINED_ARGUMENT_CODE;
        $error_msg{$fname} = UNDEFINED_ARGUMENT_MSG;
        return 1;
    }

    if($target_url !~ m/http/){
      $target_url = "http://".$target_url;
    }

    ## Download the specified file into the given output file
    my $ret = LWP::Simple::getstore($target_url, $output);
    #If grabbing the url fails, log the reason why
    if(LWP::Simple::is_error($ret)){
        $error_code{$fname} = DOWNLOAD_FAIL_CODE;
        $error_msg{$fname} = DOWNLOAD_FAIL_MSG.$ret." ";
        return 1;
    }
    return 0;
}

########################### END UNEXPORTED FUNCTIONS ##########################

=head1 ERROR CODES AND MESSAGES
The following error codes and messages are defined:

    0:  No Error
        'No Error'

    401:    A subroutine was missing an expected argument
            'Undefined Argument(s)'

    402:    There is no active connection to an archive
            'Not connected to an archive'

    403:    There is a currently-active connection to an archive
            'Already connected to an archive'

    404:    The module was unable to find an HTML index page
                or any download links on the index page
            'Unable to find an index page'

    405:    A system call failed
            'System call failed'

    406:    An invalid value was passed to a subroutine as an argument
            'Invalid value given for argument'

    407:    The connection could not be initialized, either by a failure
                to set the scratch directory, ignore-error flags, or
                the first update file could not be loaded.
            'Failed to initialize connection to archive'

    408:    A filesystem 'open' command failed
            'File operation failed'

    409:    There was a failure trying to download a file
            'Failed to download file'

    410:    An invalid XML message was read, or the end of the archive was read
            'Invalid message read'

    411:    An invalid function name was passed to get_error_[code/message/msg]
            'Invalid function specified'

    412:    User tried to ignore all data errors, but was checking for
                incomplete data
            'Cannot have ignore_incomplete_data off with ignore_data_errors on'

=head1 AUTHOR

Jason Bartlett, C<< <bartletj at cs.colostate.edu> >>

=head1 BUGS

Please report any bugs or feature requests to C<bgpmon at netsec.colostate.edu>
, or through the web interface at L<http://bgpmon.netsec.colostate.edu>.


=head1 SUPPORT

You can find documentation for this module with the perldoc command.

    perldoc BGPmon::Fetch::Archive

=cut

=head1 LICENSE AND COPYRIGHT

Copyright (c) 2012 Colorado State University

    Permission is hereby granted, free of charge, to any person
    obtaining a copy of this software and associated documentation
    files (the "Software"), to deal in the Software without
    restriction, including without limitation the rights to use,
    copy, modify, merge, publish, distribute, sublicense, and/or
    sell copies of the Software, and to permit persons to whom
    the Software is furnished to do so, subject to the following
    conditions:



( run in 1.874 second using v1.01-cache-2.11-cpan-39bf76dae61 )