Change Run to Task. Add Percona/WebAPI/Exception/Resource.pm.

This commit is contained in:
Daniel Nichter
2013-03-01 09:47:49 -07:00
parent 0be24a3b8d
commit 5e5943bd36
9 changed files with 217 additions and 59 deletions

View File

@@ -21,10 +21,11 @@ BEGIN {
Percona::WebAPI::Representation Percona::WebAPI::Representation
Percona::WebAPI::Client Percona::WebAPI::Client
Percona::WebAPI::Exception::Request Percona::WebAPI::Exception::Request
Percona::WebAPI::Exception::Resource
Percona::WebAPI::Resource::Agent Percona::WebAPI::Resource::Agent
Percona::WebAPI::Resource::Config Percona::WebAPI::Resource::Config
Percona::WebAPI::Resource::Service Percona::WebAPI::Resource::Service
Percona::WebAPI::Resource::Run Percona::WebAPI::Resource::Task
Percona::WebAPI::Util Percona::WebAPI::Util
VersionCheck VersionCheck
DSNParser DSNParser
@@ -771,6 +772,7 @@ use Lmo;
use Percona::Toolkit; use Percona::Toolkit;
use Percona::WebAPI::Representation; use Percona::WebAPI::Representation;
use Percona::WebAPI::Exception::Request; use Percona::WebAPI::Exception::Request;
use Percona::WebAPI::Exception::Resource;
Percona::WebAPI::Representation->import(qw(as_json)); Percona::WebAPI::Representation->import(qw(as_json));
Percona::Toolkit->import(qw(_d Dumper have_required_args)); Percona::Toolkit->import(qw(_d Dumper have_required_args));
@@ -862,9 +864,13 @@ sub get {
$resource_objects = $type->new(%$resource); $resource_objects = $type->new(%$resource);
} }
}; };
if ( $EVAL_ERROR ) { if ( my $e = $EVAL_ERROR ) {
warn "Error creating $type resource objects: $EVAL_ERROR"; die Percona::WebAPI::Exception::Resource->new(
return; type => $type,
link => $link,
data => (ref $resource eq 'ARRAY' ? $resource : [ $resource ]),
error => $e,
);
} }
} }
elsif ( exists $resource->{links} ) { elsif ( exists $resource->{links} ) {
@@ -892,7 +898,7 @@ sub put {
%args, %args,
method => 'PUT', method => 'PUT',
); );
return $args{link}; return $self->response->header('Location');
} }
sub delete { sub delete {
@@ -1090,6 +1096,62 @@ no Lmo;
# End Percona::WebAPI::Exception::Request package # End Percona::WebAPI::Exception::Request package
# ########################################################################### # ###########################################################################
# ###########################################################################
# Percona::WebAPI::Exception::Resource package
# This package is a copy without comments from the original. The original
# with comments and its test file can be found in the Bazaar repository at,
# lib/Percona/WebAPI/Exception/Resource.pm
# t/lib/Percona/WebAPI/Exception/Resource.t
# See https://launchpad.net/percona-toolkit for more information.
# ###########################################################################
{
package Percona::WebAPI::Exception::Resource;
use Lmo;
use overload '""' => \&as_string;
use Data::Dumper;
has 'type' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'link' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'data' => (
is => 'ro',
isa => 'ArrayRef',
required => 1,
);
has 'error' => (
is => 'ro',
isa => 'Str',
required => 1,
);
sub as_string {
my $self = shift;
chomp(my $error = $self->error);
local $Data::Dumper::Indent = 1;
local $Data::Dumper::Sortkeys = 1;
local $Data::Dumper::Quotekeys = 0;
return sprintf "Invalid %s resource from %s:\n\n%s\nError: %s\n\n",
$self->type, $self->link, Dumper($self->data), $error;
}
no Lmo;
1;
}
# ###########################################################################
# End Percona::WebAPI::Exception::Resource package
# ###########################################################################
# ########################################################################### # ###########################################################################
# Percona::WebAPI::Resource::Agent package # Percona::WebAPI::Resource::Agent package
# This package is a copy without comments from the original. The original # This package is a copy without comments from the original. The original
@@ -1159,7 +1221,7 @@ package Percona::WebAPI::Resource::Config;
use Lmo; use Lmo;
has 'config_id' => ( has 'ts' => (
is => 'ro', is => 'ro',
isa => 'Int', isa => 'Int',
required => 1, required => 1,
@@ -1210,9 +1272,9 @@ has 'name' => (
required => 1, required => 1,
); );
has 'runs' => ( has 'tasks' => (
is => 'ro', is => 'ro',
isa => 'ArrayRef[Percona::WebAPI::Resource::Run]', isa => 'ArrayRef[Percona::WebAPI::Resource::Task]',
required => 1, required => 1,
); );
@@ -1237,13 +1299,13 @@ has 'links' => (
sub BUILDARGS { sub BUILDARGS {
my ($class, %args) = @_; my ($class, %args) = @_;
if ( ref $args{runs} eq 'ARRAY' ) { if ( ref $args{tasks} eq 'ARRAY' ) {
my @runs; my @tasks;
foreach my $run_hashref ( @{$args{runs}} ) { foreach my $run_hashref ( @{$args{tasks}} ) {
my $run = Percona::WebAPI::Resource::Run->new(%$run_hashref); my $task = Percona::WebAPI::Resource::Task->new(%$run_hashref);
push @runs, $run; push @tasks, $task;
} }
$args{runs} = \@runs; $args{tasks} = \@tasks;
} }
return $class->SUPER::BUILDARGS(%args); return $class->SUPER::BUILDARGS(%args);
} }
@@ -1256,18 +1318,24 @@ no Lmo;
# ########################################################################### # ###########################################################################
# ########################################################################### # ###########################################################################
# Percona::WebAPI::Resource::Run package # Percona::WebAPI::Resource::Task package
# This package is a copy without comments from the original. The original # This package is a copy without comments from the original. The original
# with comments and its test file can be found in the Bazaar repository at, # with comments and its test file can be found in the Bazaar repository at,
# lib/Percona/WebAPI/Resource/Run.pm # lib/Percona/WebAPI/Resource/Task.pm
# t/lib/Percona/WebAPI/Resource/Run.t # t/lib/Percona/WebAPI/Resource/Task.t
# See https://launchpad.net/percona-toolkit for more information. # See https://launchpad.net/percona-toolkit for more information.
# ########################################################################### # ###########################################################################
{ {
package Percona::WebAPI::Resource::Run; package Percona::WebAPI::Resource::Task;
use Lmo; use Lmo;
has 'name' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'number' => ( has 'number' => (
is => 'ro', is => 'ro',
isa => 'Int', isa => 'Int',
@@ -1276,7 +1344,7 @@ has 'number' => (
has 'program' => ( has 'program' => (
is => 'ro', is => 'ro',
isa => 'Str', isa => 'Maybe[Str]',
required => 1, required => 1,
); );
@@ -1294,7 +1362,7 @@ has 'query' => (
has 'output' => ( has 'output' => (
is => 'ro', is => 'ro',
isa => 'Str', isa => 'Maybe[Str]',
required => 1, required => 1,
); );
@@ -1304,7 +1372,7 @@ no Lmo;
1; 1;
} }
# ########################################################################### # ###########################################################################
# End Percona::WebAPI::Resource::Run package # End Percona::WebAPI::Resource::Task package
# ########################################################################### # ###########################################################################
# ########################################################################### # ###########################################################################
@@ -4080,10 +4148,10 @@ use File::Path;
use Percona::Toolkit; use Percona::Toolkit;
use Percona::WebAPI::Client; use Percona::WebAPI::Client;
use Percona::WebAPI::Exception::Request; use Percona::WebAPI::Exception::Request;
use Percona::WebAPI::Exception::Resource;
use Percona::WebAPI::Resource::Agent; use Percona::WebAPI::Resource::Agent;
use Percona::WebAPI::Resource::Config; use Percona::WebAPI::Resource::Config;
use Percona::WebAPI::Resource::Service; use Percona::WebAPI::Resource::Service;
use Percona::WebAPI::Resource::Run;
use Percona::WebAPI::Representation; use Percona::WebAPI::Representation;
use Percona::WebAPI::Util; use Percona::WebAPI::Util;
@@ -4381,7 +4449,6 @@ sub init_agent {
} }
$action = 'put'; # must be lc $action = 'put'; # must be lc
$link = $agents_link . '/' . $agent->uuid; $link = $agents_link . '/' . $agent->uuid;
$agent_uri = $link;
} }
else { else {
_info("Creating new Agent"); _info("Creating new Agent");
@@ -4473,35 +4540,42 @@ sub run_agent {
); );
}; };
if ( my $e = $EVAL_ERROR ) { if ( my $e = $EVAL_ERROR ) {
if (blessed($e) && $e->isa('Percona::WebAPI::Exception::Request')) { if (blessed($e)) {
if ( $e->status == 404 ) { if ($e->isa('Percona::WebAPI::Exception::Request')) {
_info('Agent ' . $agent->name. ' is not configured.'); if ( $e->status == 404 ) {
_info('Agent ' . $agent->name. ' is not configured.');
}
else {
_info("$e"); # PWS API error?
}
} }
else { elsif ($e->isa('Percona::WebAPI::Exception::Resource')) {
_info("$e"); # PWS API error? _warn("$e");
} }
} }
else { else {
_err("$e"); # internal error _err($e); # internal error
} }
} }
else { else {
eval { eval {
if ( !$config || $new_config->config_id != $config->config_id ) { if ( !$config || $new_config->ts > $config->ts ) {
$lib_dir = apply_config( $lib_dir = apply_config(
agent => $agent, agent => $agent,
config => $new_config, config => $new_config,
lib_dir => $lib_dir, lib_dir => $lib_dir,
); );
$config = $new_config; $config = $new_config;
_info('Config ' . $config->config_id . ' applied successfully'); _info('Config ' . $config->ts . ' applied successfully');
} }
else { else {
_info('Config has not changed'); _info('Config has not changed');
} }
}; };
if ( $EVAL_ERROR ) { if ( $EVAL_ERROR ) {
_warn($EVAL_ERROR); chomp $EVAL_ERROR;
_warn("Failed to apply config " . $new_config->ts
. ": $EVAL_ERROR Will try again.");
} }
} }
@@ -4629,12 +4703,7 @@ sub apply_config {
my $config = $args{config}; my $config = $args{config};
my $lib_dir = $args{lib_dir}; my $lib_dir = $args{lib_dir};
_info('Applying config ' . $config->config_id); _info('Applying config ' . $config->ts);
# Save config in $HOME/.pt-agent.conf
write_config(
config => $config,
);
# If the --lib dir has changed, init the new one and re-write # If the --lib dir has changed, init the new one and re-write
# the Agent resource in it. # the Agent resource in it.
@@ -4651,6 +4720,11 @@ sub apply_config {
# TODO: copy old-lib/services/* to new-lib/services/ ? # TODO: copy old-lib/services/* to new-lib/services/ ?
} }
# Save config in $HOME/.pt-agent.conf if successful.
write_config(
config => $config,
);
return $new_lib_dir || $lib_dir; return $new_lib_dir || $lib_dir;
} }

View File

@@ -35,6 +35,7 @@ use Lmo;
use Percona::Toolkit; use Percona::Toolkit;
use Percona::WebAPI::Representation; use Percona::WebAPI::Representation;
use Percona::WebAPI::Exception::Request; use Percona::WebAPI::Exception::Request;
use Percona::WebAPI::Exception::Resource;
Percona::WebAPI::Representation->import(qw(as_json)); Percona::WebAPI::Representation->import(qw(as_json));
Percona::Toolkit->import(qw(_d Dumper have_required_args)); Percona::Toolkit->import(qw(_d Dumper have_required_args));
@@ -133,9 +134,13 @@ sub get {
$resource_objects = $type->new(%$resource); $resource_objects = $type->new(%$resource);
} }
}; };
if ( $EVAL_ERROR ) { if ( my $e = $EVAL_ERROR ) {
warn "Error creating $type resource objects: $EVAL_ERROR"; die Percona::WebAPI::Exception::Resource->new(
return; type => $type,
link => $link,
data => (ref $resource eq 'ARRAY' ? $resource : [ $resource ]),
error => $e,
);
} }
} }
elsif ( exists $resource->{links} ) { elsif ( exists $resource->{links} ) {

View File

@@ -0,0 +1,66 @@
# This program is copyright 2012-2013 Percona Inc.
# Feedback and improvements are welcome.
#
# THIS PROGRAM IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR IMPLIED
# WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
# MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
#
# This program is free software; you can redistribute it and/or modify it under
# the terms of the GNU General Public License as published by the Free Software
# Foundation, version 2; OR the Perl Artistic License. On UNIX and similar
# systems, you can issue `man perlgpl' or `man perlartistic' to read these
# licenses.
#
# You should have received a copy of the GNU General Public License along with
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA.
# ###########################################################################
# Percona::WebAPI::Exception::Resource package
# ###########################################################################
{
package Percona::WebAPI::Exception::Resource;
use Lmo;
use overload '""' => \&as_string;
use Data::Dumper;
has 'type' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'link' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'data' => (
is => 'ro',
isa => 'ArrayRef',
required => 1,
);
has 'error' => (
is => 'ro',
isa => 'Str',
required => 1,
);
sub as_string {
my $self = shift;
chomp(my $error = $self->error);
local $Data::Dumper::Indent = 1;
local $Data::Dumper::Sortkeys = 1;
local $Data::Dumper::Quotekeys = 0;
return sprintf "Invalid %s resource from %s:\n\n%s\nError: %s\n\n",
$self->type, $self->link, Dumper($self->data), $error;
}
no Lmo;
1;
}
# ###########################################################################
# End Percona::WebAPI::Exception::Resource package
# ###########################################################################

View File

@@ -22,7 +22,7 @@ package Percona::WebAPI::Resource::Config;
use Lmo; use Lmo;
has 'config_id' => ( has 'ts' => (
is => 'ro', is => 'ro',
isa => 'Int', isa => 'Int',
required => 1, required => 1,

View File

@@ -28,9 +28,9 @@ has 'name' => (
required => 1, required => 1,
); );
has 'runs' => ( has 'tasks' => (
is => 'ro', is => 'ro',
isa => 'ArrayRef[Percona::WebAPI::Resource::Run]', isa => 'ArrayRef[Percona::WebAPI::Resource::Task]',
required => 1, required => 1,
); );
@@ -55,13 +55,13 @@ has 'links' => (
sub BUILDARGS { sub BUILDARGS {
my ($class, %args) = @_; my ($class, %args) = @_;
if ( ref $args{runs} eq 'ARRAY' ) { if ( ref $args{tasks} eq 'ARRAY' ) {
my @runs; my @tasks;
foreach my $run_hashref ( @{$args{runs}} ) { foreach my $run_hashref ( @{$args{tasks}} ) {
my $run = Percona::WebAPI::Resource::Run->new(%$run_hashref); my $task = Percona::WebAPI::Resource::Task->new(%$run_hashref);
push @runs, $run; push @tasks, $task;
} }
$args{runs} = \@runs; $args{tasks} = \@tasks;
} }
return $class->SUPER::BUILDARGS(%args); return $class->SUPER::BUILDARGS(%args);
} }

View File

@@ -15,13 +15,19 @@
# this program; if not, write to the Free Software Foundation, Inc., 59 Temple # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
# Place, Suite 330, Boston, MA 02111-1307 USA. # Place, Suite 330, Boston, MA 02111-1307 USA.
# ########################################################################### # ###########################################################################
# Percona::WebAPI::Resource::Run package # Percona::WebAPI::Resource::Task package
# ########################################################################### # ###########################################################################
{ {
package Percona::WebAPI::Resource::Run; package Percona::WebAPI::Resource::Task;
use Lmo; use Lmo;
has 'name' => (
is => 'ro',
isa => 'Str',
required => 1,
);
has 'number' => ( has 'number' => (
is => 'ro', is => 'ro',
isa => 'Int', isa => 'Int',
@@ -30,7 +36,7 @@ has 'number' => (
has 'program' => ( has 'program' => (
is => 'ro', is => 'ro',
isa => 'Str', isa => 'Maybe[Str]',
required => 1, required => 1,
); );
@@ -48,7 +54,7 @@ has 'query' => (
has 'output' => ( has 'output' => (
is => 'ro', is => 'ro',
isa => 'Str', isa => 'Maybe[Str]',
required => 1, required => 1,
); );
@@ -58,5 +64,5 @@ no Lmo;
1; 1;
} }
# ########################################################################### # ###########################################################################
# End Percona::WebAPI::Resource::Run package # End Percona::WebAPI::Resource::Task package
# ########################################################################### # ###########################################################################

View File

@@ -19,7 +19,7 @@ use Percona::WebAPI::Client;
use Percona::WebAPI::Resource::Agent; use Percona::WebAPI::Resource::Agent;
use Percona::WebAPI::Resource::Config; use Percona::WebAPI::Resource::Config;
use Percona::WebAPI::Resource::Service; use Percona::WebAPI::Resource::Service;
use Percona::WebAPI::Resource::Run; use Percona::WebAPI::Resource::Task;
Percona::Toolkit->import(qw(Dumper have_required_args)); Percona::Toolkit->import(qw(Dumper have_required_args));
Percona::WebAPI::Representation->import(qw(as_json as_hashref)); Percona::WebAPI::Representation->import(qw(as_json as_hashref));
@@ -155,7 +155,7 @@ $return_links = {
}; };
my $return_config = Percona::WebAPI::Resource::Config->new( my $return_config = Percona::WebAPI::Resource::Config->new(
id => '1', ts => '100',
name => 'Default', name => 'Default',
options => {}, options => {},
links => $return_links, links => $return_links,
@@ -186,7 +186,8 @@ $return_links = {
'send_data' => '/query-monitor', 'send_data' => '/query-monitor',
}; };
my $run0 = Percona::WebAPI::Resource::Run->new( my $run0 = Percona::WebAPI::Resource::Task->new(
name => 'run-pqd',
number => '0', number => '0',
program => 'pt-query-digest', program => 'pt-query-digest',
options => '--output json', options => '--output json',
@@ -197,7 +198,7 @@ my $svc0 = Percona::WebAPI::Resource::Service->new(
name => 'query-monitor', name => 'query-monitor',
run_schedule => '1 * * * *', run_schedule => '1 * * * *',
spool_schedule => '2 * * * *', spool_schedule => '2 * * * *',
runs => [ $run0 ], tasks => [ $run0 ],
links => $return_links, links => $return_links,
); );

View File

@@ -32,6 +32,8 @@ is(
); );
my $config = Percona::WebAPI::Resource::Config->new( my $config = Percona::WebAPI::Resource::Config->new(
ts => '100',
name => 'Default',
options => { options => {
'check-interval' => 60, 'check-interval' => 60,
}, },

View File

@@ -17,6 +17,8 @@ use Percona::WebAPI::Resource::Config;
use Percona::WebAPI::Util qw(resource_diff); use Percona::WebAPI::Util qw(resource_diff);
my $x = Percona::WebAPI::Resource::Config->new( my $x = Percona::WebAPI::Resource::Config->new(
ts => '100',
name => 'Default',
options => { options => {
'lib' => '/var/lib', 'lib' => '/var/lib',
'spool' => '/var/spool', 'spool' => '/var/spool',
@@ -24,6 +26,8 @@ my $x = Percona::WebAPI::Resource::Config->new(
); );
my $y = Percona::WebAPI::Resource::Config->new( my $y = Percona::WebAPI::Resource::Config->new(
ts => '100',
name => 'Default',
options => { options => {
'lib' => '/var/lib', 'lib' => '/var/lib',
'spool' => '/var/spool', 'spool' => '/var/spool',