Bio-Phylo-CIPRES
view release on metacpan or search on metacpan
lib/Bio/Phylo/CIPRES.pm view on Meta::CPAN
=head1 METHODS
=head2 new()
The constructor takes the arguments as shown in the SYNOPSIS section. The arguments are
a direct translation of the named arguments (not option flags) that are passed on the
command line to the L<cipresrun> program. The value of the C<outfile> argument, and that
of the C<param> argument, is both a hash reference.
=cut
sub new {
my $class = shift;
my @fields = qw[infile tool param outfile url user pass cipres_appkey];
my $self = bless { map { $_ => undef } @fields }, $class;
my %args = @_;
while( my ( $property, $value ) = each %args ) {
$self->$property($value);
}
return $self;
}
=head2 run()
Runs the entire analysis using the configuration as provided to the constructor. Returns
key value pairs where each key is an C<outfile> and each file is the data as text.
=cut
sub run {
my $self = shift;
my $url = $self->launch_job;
while(1) {
sleep(60);
my $status = $self->check_status($url);
if ( $status->{'completed'} eq 'true' ) {
$self->get_results( $status->{'outfiles'} );
return $url;
}
}
}
=head2 launch_job()
Is called by C<run()>. Launches the analysis and returns the status URL at which progress
can be inspected.
=cut
sub launch_job {
my $self = shift;
my $ua = $self->ua;
my $url = $self->url;
my $load = $self->payload;
my @head = $self->headers(1);
my $res = $ua->post( $url . '/job/' . $self->user, $load, @head );
if ( $res->is_success ) {
# run submission, parse result
my $status_url;
my $result = $res->decoded_content;
DEBUG $result;
XML::Twig->new(
'twig_handlers' => {
'jobstatus/selfUri/url' => sub { $status_url = $_->text }
}
)->parse($result);
INFO "Job launched at $status_url";
return $status_url;
}
else {
throw 'NetworkError' => $res->status_line;
}
}
=head2 check_status()
Is called by C<run()>. Consults the status URL. Returns a hash reference whose values
specify whether the job is done, and if so, where the results can be fetched.
=cut
sub check_status {
my ( $self, $url ) = @_;
INFO "Going to check status for $url";
my $ua = $self->ua;
my @head = $self->headers(0);
my $res = $ua->get( $url, @head );
if ( $res->is_success ) {
# post request, fetch result
my ( $status, $outfiles );
my $result = $res->decoded_content;
DEBUG $result;
XML::Twig->new(
'twig_handlers' => {
'jobstatus/resultsUri/url' => sub { $outfiles = $_->text },
'jobstatus/terminalStage' => sub { $status = $_->text }
}
)->parse($result);
my $time = localtime();
INFO "[$time] completed: $status";
return { 'completed' => $status, 'outfiles' => $outfiles };
}
else {
throw 'NetworkError' => $res->status_line;
}
}
=head2 get_results()
Is called by C<run()>. Returns the named result data as a hash.
=cut
sub get_results {
my ( $self, $url ) = @_;
my %out = %{ $self->outfile };
my $ua = $self->ua;
my @head = $self->headers(0);
my $res = $ua->get( $url, @head );
my %out_url;
if ( $res->is_success ) {
my $result = $res->decoded_content;
DEBUG $result;
XML::Twig->new(
'twig_handlers' => {
'results/jobfiles/jobfile' => sub {
my $node = $_;
my $name = $node->findvalue('filename');
if ( $out{ $name } ) {
$out_url{ $name } = $node->findvalue('downloadUri/url');
}
DEBUG $node->toString;
}
}
)->parse($result);
for my $name ( keys %out ) {
my $location = $out_url{ $name };
$res = $ua->get( $location, @head );
if ( $res->is_success ) {
open my $fh, '>', $out{ $name } or die $!;
print $fh $res->decoded_content;
}
else {
throw 'NetworkError' => $res->status_line;
}
}
}
else {
throw 'NetworkError' => $res->status_line;
}
}
=head2 yml()
Given the location the config.yml file, populates properties of the object with the
right parameter values to authenticate the client with the CIPRES server.
=cut
sub yml {
my ( $self, $yml ) = @_;
INFO "Reading YAML file $yml";
my $info = LoadFile($yml);
DEBUG "Parsed " . Dumper( $info );
$self->user( $info->{'CRA_USER'} );
$self->pass( $info->{'PASSWORD'} );
$self->url( $info->{'URL'} );
$self->cipres_appkey( $info->{'KEY'} );
}
=head2 ua()
Instantiates an authenticated L<LWP::UserAgent> object.
=cut
sub ua {
my $self = shift;
my $host = URI->new( $self->url )->host();
my $user = $self->user;
my $pass = $self->pass;
my $ua = LWP::UserAgent->new;
DEBUG "Instantiating UserAgent $host:$PORT / $REALM / $user:****";
$ua->ssl_opts( 'verify_hostname' => 0 );
$ua->credentials(
$host . ':' . $PORT,
$REALM,
$user => $pass
);
return $ua;
}
=head2 payload()
Constructs the HTTP POST payload for launching jobs. Returns an array reference of
key/value pairs.
=cut
sub payload {
my $self = shift;
( run in 0.537 second using v1.01-cache-2.11-cpan-39bf76dae61 )