API-Eulerian
view release on metacpan or search on metacpan
lib/API/Eulerian/EDW/Peer/Rest.pm view on Meta::CPAN
#/usr/bin/env perl
###############################################################################
#
# @file Rest.pm
#
# @brief Eulerian Data Warehouse REST Peer Module definition.
#
# This module is aimed to provide access to Eulerian Data Warehouse
# Analytics Analysis Through REST Protocol.
#
# @author Thorillon Xavier:x.thorillon@eulerian.com
#
# @date 26/11/2021
#
# @version 1.0
#
###############################################################################
#
# Setup module name
#
package API::Eulerian::EDW::Peer::Rest;
use strict;
use JSON();
use POSIX();
use Sys::Hostname();
use API::Eulerian::EDW::Peer();
use API::Eulerian::EDW::File();
use API::Eulerian::EDW::Bench();
use API::Eulerian::EDW::Status();
use API::Eulerian::EDW::Authority();
use API::Eulerian::EDW::Parser::JSON();
use API::Eulerian::EDW::Parser::CSV();
our @ISA = qw/ API::Eulerian::EDW::Peer /;
#
# Defines Parser class name matching format.
#
my %PARSERS = (
'json' => 'API::Eulerian::EDW::Parser::JSON',
'csv' => 'API::Eulerian::EDW::Parser::CSV',
);
#
# @brief Allocate and initialize a new Eulerian Data Warehouse Rest Peer.
#
# @param $class - Eulerian Data Warehouse Rest Peer class.
# @param $setup - Setup attributes.
#
# @return Eulerian Data Warehouse Peer.
#
sub new
{
my $proto = shift();
my $class = ref($proto) || $proto;
my $setup = shift() || {};
my $self = $class->SUPER::new();
# Setup Rest Peer Default attributes values
$self->{ _ACCEPT } = $setup->{accept} || 'application/json';
$self->{ _ENCODING } = 'gzip';
$self->{ _WDIR } = $setup->{wdir} || '/tmp';
$self->{ _UUID } = 0;
# Setup Rest Peer Attributes
$self->setup( $setup );
return bless($self, $class);
}
#
# @brief UUID attribute accessors.
#
# @param $self - Eulerian Data Warehouse Peer.
# @param $uuid - Request UUID.
#
# @return UUID.
#
sub uuid
{
my ( $self, $uuid ) = @_;
$self->{ _UUID } = $uuid if defined( $uuid );
return $self->{ _UUID };
}
#
# @brief Encoding attribute accessors.
#
# @param $self - Eulerian Data Warehouse Peer.
# @param $encoding - Encoding.
#
# @return Encoding.
#
sub encoding
{
my ( $self, $encoding ) = @_;
$self->{ _ENCODING } = $encoding if defined( $encoding );
return $self->{ _ENCODING };
}
#
# @brief Accept attribute accessors.
#
# @param $self - Eulerian Data Warehouse Peer.
# @param $accept - Accept.
#
# @return Accept.
#
sub accept
{
my ( $self, $accept ) = @_;
$self->{ _ACCEPT } = $accept if defined( $accept );
return $self->{ _ACCEPT };
}
#
# @brief Working directory attribute accessors.
#
# @param $self - Eulerian Data Warehouse Peer.
# @param $wdir - Working directory.
#
# @return Working Directory.
#
sub wdir
{
my ( $self, $wdir ) = @_;
$self->{ _WDIR } = $wdir if defined( $wdir );
return $self->{ _WDIR };
}
#
# @brief Setup Eulerian Data Warehouse Peer.
#
# @param $self - Eulerian Data Warehouse Peer.
# @param $setup - Setup entries.
#
sub setup
{
my ( $self, $setup ) = @_;
# Setup base interface values
$self->SUPER::setup( $setup );
# Setup Rest specifics options
$self->accept( $setup->{ accept } ) if exists( $setup->{ accept } );
$self->encoding( $setup->{ encoding } ) if exists( $setup->{ encoding } );
$self->wdir( $setup->{ wdir } ) if exists( $setup->{ wdir } );
return $self;
}
#
# @brief Dump Eulerian Data Warehouse Peer setup.
#
# @param $self - Eulerian Data Warehouse Peer.
#
sub dump
{
my $self = shift;
my $dump = '';
$self->SUPER::dump();
$dump .= 'Accept : ' . $self->accept() . "\n";
$dump .= 'Encoding : ' . $self->encoding() . "\n";
$dump .= 'WorkDir : ' . $self->wdir() . "\n\n";
print( $dump );
return $self;
}
#
# @brief Get remote URL to Eulerian Data Warehouse Platform.
#
# @param $self - Eulerian Data Warehouse Peer.
#
# @return Remote URL to Eulerian Data Warehouse Platform.
#
sub url
{
my $self = shift;
my $platform;
my $host;
my $url;
$url = $self->secure() ? 'https://' : 'http://';
$platform = $self->platform();
$host = $self->host();
if( $host ) {
$url .= $host . ':';
$url .= $self->ports()->[ $self->secure() ];
} elsif( $platform eq 'fr' ) {
$url .= 'edw.ea.eulerian.com';
} elsif( $platform eq 'ca' ) {
$url .= 'edw.ea.eulerian.ca';
} else {
$url = undef;
}
return $url;
}
#
# @brief Get HTTP Request Body used to send command to Eulerian Data Warehouse
# Platform.
#
# @param $self - Eulerian Data Warehouse Rest Peer.
# @param $command - Eulerian Data Warehouse Command.
#
# @return HTTP Request Body.
#
sub body
{
my ( $self, $command ) = @_;
$command =~ s/\n//gm;
return JSON::encode_json({
kind => 'edw#request',
query => $command,
lib/API/Eulerian/EDW/Peer/Rest.pm view on Meta::CPAN
);
}
return $status;
}
#
# @brief Test if Job status is 'Running';
#
# @param $self - API::Eulerian::EDW::Rest instance.
# @param $rc - Return context.
#
# @return 0 - Not running.
# @return 1 - Running.
#
sub running
{
my ( $self, $status ) = @_;
return API::Eulerian::EDW::Request->json(
$status->{ response }
)->{ status } eq 'Running';
}
#
# @brief Test if Job status is 'Done'.
#
# @param $self - API::Eulerian::EDW::Rest instance.
# @param $rc - Return context.
#
# @return 0 - Not Done.
# @return 1 - Done.
#
sub done
{
my ( $self, $status ) = @_;
return ! $status->{ error } ?
API::Eulerian::EDW::Request->json(
$status->{ response }
)->{ status } eq 'Done' :
0;
}
#
# @brief Get Path to local filepath.
#
# @param $self - API::Eulerian::EDW::Rest instance.
#
# @return Local file path.
#
sub path
{
my ( $self, $response ) = @_;
my $encoding = $self->encoding();
my $json = API::Eulerian::EDW::Request->json( $response );
my $pattern = '([0-9]*)\.(json|csv|parquet)';
my $status = API::Eulerian::EDW::Status->new();
my $url = $json->{ data }->[ 1 ];
my $wdir = $self->wdir();
my %rc = ();
if( ! $wdir ) {
$status->error( 1 );
$status->code( 400 );
$status->msg( "Working directory isn't set" );
} elsif( ! API::Eulerian::EDW::File->writable( $wdir ) ) {
$status->error( 1 );
$status->code( 400 );
$status->msg( "Working directory isn't writable" );
} elsif( ! ( $url =~ m/$pattern/ ) ) {
$status->error( 1 );
$status->code( 400 );
$status->msg( "Unknown local file name" );
} else {
my $path = $wdir. '/' . "$1.$2";
$status->{ url } = $url;
$status->{ path } = $path;
}
return $status;
}
#
# @brief Unzip given file.
#
# @param $self - API::Eulerian::EDW::Rest instance.
# @param $zipped - Path to zipped file.
#
# @return Path to unzipped file.
#
sub unzip
{
my( $self, $zipped ) = @_;
my $unzipped;
# Parse zipped file
$zipped =~ /(.*)\.gz/;
# Unzipped file name
$unzipped = $1;
# Gunzip zipped file into unzipped file
IO::Uncompress::Gunzip::gunzip(
$zipped, $unzipped, BinModeOut => 1
);
# Remove zipped file
unlink $zipped;
# Return path to unzipped file
return $unzipped;
}
#
# @brief Download Job reply file.
#
# @param $self - Eulerian Data Warehouse Rest Peer.
# @param $rc - Reply context.
#
# @return Reply context
#
sub download
{
my ( $self, $status ) = @_;
# From Last status message compute local file path
$status = $self->path( $status->{ response } );
( run in 1.285 second using v1.01-cache-2.11-cpan-8f98c5d2c55 )