Skip to content

Commit

Permalink
Merge pull request #1559 from alvarocarvajald/poo#16282
Browse files Browse the repository at this point in the history
WebAPI: Add API description from Controller's POD
  • Loading branch information
coolo committed Feb 13, 2018
2 parents 3977d2f + 70e15bf commit 8d54de2
Show file tree
Hide file tree
Showing 19 changed files with 1,254 additions and 31 deletions.
1 change: 1 addition & 0 deletions cpanfile
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ requires 'URI::Heuristic';
requires 'URI::URL';
requires 'URI::WithBase';
requires 'URI::data';
requires 'Pod::POM';
requires 'base';
requires 'constant';
requires 'diagnostics';
Expand Down
29 changes: 22 additions & 7 deletions lib/OpenQA/WebAPI.pm
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ use OpenQA::WebAPI::Plugin::Helpers;
use OpenQA::IPC;
use OpenQA::Utils qw(log_warning job_groups_and_parents detect_current_version);
use OpenQA::Setup;
use OpenQA::WebAPI::Description qw(get_pod_from_controllers set_api_desc);
use Mojo::IOLoop;
use Mojolicious::Commands;
use DateTime;
Expand Down Expand Up @@ -302,13 +303,16 @@ sub startup {
#
## JSON API starts here
###
# Array to store new API routes' references, so they can all be checked to get API description from POD
my @api_routes = ();
my $api_auth_any_user = $r->under('/api/v1')->to(controller => 'API::V1', action => 'auth');
my $api_auth_operator = $r->under('/api/v1')->to(controller => 'API::V1', action => 'auth_operator');
my $api_auth_admin = $r->under('/api/v1')->to(controller => 'API::V1', action => 'auth_admin');
my $api_ru = $api_auth_any_user->route('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1');
my $api_ro = $api_auth_operator->route('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1');
my $api_ra = $api_auth_admin->route('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1');
my $api_public_r = $r->route('/api/v1')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1');
my $api_ru = $api_auth_any_user->route('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1');
my $api_ro = $api_auth_operator->route('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1');
my $api_ra = $api_auth_admin->route('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1');
my $api_public_r = $r->route('/api/v1')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1');
push @api_routes, $api_ru, $api_ro, $api_ra, $api_public_r;
# this is fallback redirect if one does not use apache
$api_public_r->websocket(
'/ws/:workerid' => sub {
Expand All @@ -323,6 +327,7 @@ sub startup {
});
my $api_job_auth = $r->under('/api/v1')->to(controller => 'API::V1', action => 'auth_jobtoken');
my $api_r_job = $api_job_auth->route('/')->to(namespace => 'OpenQA::WebAPI::Controller::API::V1');
push @api_routes, $api_job_auth, $api_r_job;
$api_r_job->get('/whoami')->name('apiv1_jobauth_whoami')->to('job#whoami'); # primarily for tests

# api/v1/job_groups
Expand All @@ -347,6 +352,7 @@ sub startup {
$api_ro->post('/jobs/restart')->name('apiv1_restart_jobs')->to('job#restart');

my $job_r = $api_ro->route('/jobs/:jobid', jobid => qr/\d+/);
push @api_routes, $job_r;
$api_public_r->route('/jobs/:jobid', jobid => qr/\d+/)->name('apiv1_job')->to('job#show');
$api_public_r->route('/jobs/:jobid/details', jobid => qr/\d+/)->name('apiv1_job')->to('job#show', details => 1);
$job_r->put('/')->name('apiv1_put_job')->to('job#update');
Expand All @@ -357,9 +363,9 @@ sub startup {
$job_r->post('/artefact')->name('apiv1_create_artefact')->to('job#create_artefact');
$job_r->post('/ack_temporary')->to('job#ack_temporary');


# job_set_waiting, job_set_continue
my $command_r = $job_r->route('/set_:command', command => [qw(waiting running)]);
push @api_routes, $command_r;
$command_r->post('/')->name('apiv1_set_command')->to('job#set_command');
$job_r->post('/restart')->name('apiv1_restart')->to('job#restart');
$job_r->post('/cancel')->name('apiv1_cancel')->to('job#cancel');
Expand All @@ -369,6 +375,7 @@ sub startup {
$api_public_r->get('/bugs')->name('apiv1_bugs')->to('bug#list');
$api_ro->post('/bugs')->name('apiv1_create_bug')->to('bug#create');
my $bug_r = $api_ro->route('/bugs/:id', bid => qr/\d+/);
push @api_routes, $bug_r;
$bug_r->get('/')->name('apiv1_show_bug')->to('bug#show');
$bug_r->put('/')->name('apiv1_put_bug')->to('bug#update');
$bug_r->delete('/')->name('apiv1_delete_bug')->to('bug#destroy');
Expand All @@ -379,6 +386,7 @@ sub startup {
= 'Each entry contains the "hostname", the boolean flag "connected" which can be 0 or 1 depending on the connection to the websockets server and the field "status" which can be "dead", "idle", "running". A worker can be considered "up" when "connected=1" and "status!=dead"';
$api_ro->post('/workers')->name('apiv1_create_worker')->to('worker#create');
my $worker_r = $api_ro->route('/workers/:workerid', workerid => qr/\d+/);
push @api_routes, $worker_r;
$api_public_r->route('/workers/:workerid', workerid => qr/\d+/)->get('/')->name('apiv1_worker')->to('worker#show');
$worker_r->post('/commands/')->name('apiv1_create_command')->to('command#create');

Expand Down Expand Up @@ -407,6 +415,7 @@ sub startup {

# api/v1/mm
my $mm_api = $api_r_job->route('/mm');
push @api_routes, $mm_api;
$mm_api->get('/children/:status' => [status => [qw(running scheduled done)]])->name('apiv1_mm_running_children')
->to('mm#get_children_status');
$mm_api->get('/children')->name('apiv1_mm_children')->to('mm#get_children');
Expand Down Expand Up @@ -474,8 +483,14 @@ sub startup {

# api/v1/feature
$api_ru->post('/feature')->name('apiv1_post_informed_about')->to('feature#informed');
$api_description{'apiv1_post_informed_about'}
= 'Post integer value to save feature tour progress of current user in the database';

# Parse API controller modules for POD
get_pod_from_controllers(@api_routes);
# Set API descriptions
$api_description{apiv1} = 'Root API V1 path';
foreach my $api_rt (@api_routes) {
set_api_desc(\%api_description, $api_rt);
}

# reduce_result is obsolete (replaced by limit_results_and_logs)
$self->gru->add_task(reduce_result => \&OpenQA::Schema::Result::Jobs::reduce_result);
Expand Down
60 changes: 60 additions & 0 deletions lib/OpenQA/WebAPI/Controller/API/V1/Asset.pm
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,32 @@ use Mojo::Base 'Mojolicious::Controller';
use OpenQA::Utils;
use OpenQA::IPC;

=pod
=head1 NAME
OpenQA::WebAPI::Controller::API::V1::Asset
=head1 SYNOPSIS
use OpenQA::WebAPI::Controller::API::V1::Asset;
=head1 DESCRIPTION
OpenQA API implementation for assets handling methods.
=head1 METHODS
=over 4
=item register()
Register an asset given its name and type. Returns a code of 200 on success and of 400 on error.
=back
=cut

sub register {
my ($self) = @_;

Expand All @@ -38,6 +64,17 @@ sub register {
$self->render(json => $json, status => $status);
}

=over 4
=item list()
Returns a list of all assets present in the system. For each asset relevant information such
as its id, name, timestamp of creation and type is included.
=back
=cut

sub list {
my $self = shift;
my $schema = $self->app->schema;
Expand All @@ -47,6 +84,18 @@ sub list {
$self->render(json => {assets => [$rs->all]});
}

=over 4
=item get()
Returns information for a specific asset given its id or its type and name. Information
returned the asset id, name, timestamp of creation and type. Returns a code of 200
on success and of 404 on error.
=back
=cut

sub get {
my $self = shift;
my $schema = $self->app->schema;
Expand All @@ -72,6 +121,17 @@ sub get {
}
}

=over 4
=item delete()
Removes an asset from the system given its id or its type and name. Returns the
number of assets removed.
=back
=cut

sub delete {
my ($self) = @_;

Expand Down
86 changes: 85 additions & 1 deletion lib/OpenQA/WebAPI/Controller/API/V1/Bug.pm
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,35 @@ use DBIx::Class::Timestamps 'now';
use Date::Format 'time2str';
use Try::Tiny;

=pod
=head1 NAME
OpenQA::WebAPI::Controller::API::V1::Bug
=head1 SYNOPSIS
use OpenQA::WebAPI::Controller::API::V1::Bug;
=head1 DESCRIPTION
OpenQA API implementation for bug handling methods.
=head1 METHODS
=over 4
=item list()
Returns list of bugs reported in the system with its id and text.
=back
=cut

sub list {
my ($self) = @_;


my $bugs;
if ($self->param('refreshable')) {
my $delta = $self->param('delta') || 3600;
Expand All @@ -46,6 +71,18 @@ sub list {
$self->render(json => {bugs => \%ret});
}

=over 4
=item show()
Returns information for a bug given its id in the system. Information includes the internal
(openQA-specific) and the external bug id. Also shows the bug's title, priority, whether its
assigned or not and its assignee, whether its open or not, status, resolution, whether its an
existing bug or not, and the date when the bug was last updated in the system.
=back
=cut

sub show {
my ($self) = @_;
Expand All @@ -62,6 +99,18 @@ sub show {
$self->render(json => \%json);
}

=over 4
=item create()
Creates a new bug in the system. This method will check for the existence of a bug with the same
external bug id, in which case the method fails with an error code of 1. Otherwise, the new bug
is created with the bug values passed as arguments.
=back
=cut

sub create {
my ($self) = @_;

Expand All @@ -77,6 +126,17 @@ sub create {
$self->render(json => {id => $bug->id});
}

=over 4
=item update()
Updates the information of a bug given its id and a set of bug values to update. Returns
the id of the bug, or an error if the bug id is not found in the system.
=back
=cut

sub update {
my ($self) = @_;

Expand All @@ -92,6 +152,16 @@ sub update {
$self->render(json => {id => $bug->id});
}

=over 4
=item destroy()
Removes a bug from the system given its bug id. Return 1 on success or not found on error.
=back
=cut

sub destroy {
my ($self) = @_;

Expand All @@ -107,6 +177,20 @@ sub destroy {
$self->render(json => {result => 1});
}

=over 4
=item get_bug_values()
Internal method to extract from the query string the named arguments for values that can be
set for a bug: title, priority, whether its assigned or not (assigned), assignee, whether its
an open bug or not (open), status, resolution, whether its an existing bug or not (existing),
and the timestamp of the update operation (t_updated). This method is used by B<create()> and
B<update()>.
=back
=cut

sub get_bug_values {
my ($self) = @_;

Expand Down
28 changes: 28 additions & 0 deletions lib/OpenQA/WebAPI/Controller/API/V1/Command.pm
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,34 @@ use OpenQA::Utils;
use OpenQA::IPC;
use Try::Tiny;

=pod
=head1 NAME
OpenQA::WebAPI::Controller::API::V1::Command
=head1 SYNOPSIS
use OpenQA::WebAPI::Controller::API::V1::Command;
=head1 DESCRIPTION
Implements API methods for openQA commands.
=head1 METHODS
=over 4
=item create()
Sends a command to a worker. Receives the worker id and the command as arguments. Returns not
found if the worker cannot be found or a 200 status code and a JSON with an OK status of 1 on
success.
=back
=cut

sub create {
my $self = shift;
my $workerid = $self->stash('workerid');
Expand Down
Loading

0 comments on commit 8d54de2

Please sign in to comment.