Repository: incubator-trafficcontrol Updated Branches: refs/heads/master 51b038af2 -> b05a51144
adds routes to fetch jobs Project: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/commit/b05a5114 Tree: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/tree/b05a5114 Diff: http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/diff/b05a5114 Branch: refs/heads/master Commit: b05a511444b9414cab10edb98f954f5e85512482 Parents: 5db8985 Author: Jeremy Mitchell <[email protected]> Authored: Tue Apr 11 10:00:57 2017 -0600 Committer: Dewayne Richardson <[email protected]> Committed: Wed Apr 12 08:58:31 2017 -0600 ---------------------------------------------------------------------- docs/source/development/traffic_ops.rst | 1 + .../development/traffic_ops_api/v12/job.rst | 136 +++++++++++++++++++ traffic_ops/app/lib/API/Job.pm | 88 ++++++++++-- traffic_ops/app/lib/Fixtures/Job.pm | 45 +++++- traffic_ops/app/lib/TrafficOpsRoutes.pm | 8 +- traffic_ops/app/t/api/1.2/job.t | 58 ++++++++ 6 files changed, 314 insertions(+), 22 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/b05a5114/docs/source/development/traffic_ops.rst ---------------------------------------------------------------------- diff --git a/docs/source/development/traffic_ops.rst b/docs/source/development/traffic_ops.rst index 41ad9cd..18b73a8 100644 --- a/docs/source/development/traffic_ops.rst +++ b/docs/source/development/traffic_ops.rst @@ -614,6 +614,7 @@ API 1.2 Reference traffic_ops_api/v12/division traffic_ops_api/v12/federation traffic_ops_api/v12/hwinfo + traffic_ops_api/v12/job traffic_ops_api/v12/parameter traffic_ops_api/v12/phys_location traffic_ops_api/v12/profile http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/b05a5114/docs/source/development/traffic_ops_api/v12/job.rst ---------------------------------------------------------------------- diff --git a/docs/source/development/traffic_ops_api/v12/job.rst b/docs/source/development/traffic_ops_api/v12/job.rst new file mode 100644 index 0000000..be27309 --- /dev/null +++ b/docs/source/development/traffic_ops_api/v12/job.rst @@ -0,0 +1,136 @@ +.. +.. +.. Licensed under the Apache License, Version 2.0 (the "License"); +.. you may not use this file except in compliance with the License. +.. You may obtain a copy of the License at +.. +.. http://www.apache.org/licenses/LICENSE-2.0 +.. +.. Unless required by applicable law or agreed to in writing, software +.. distributed under the License is distributed on an "AS IS" BASIS, +.. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +.. See the License for the specific language governing permissions and +.. limitations under the License. +.. + +.. _to-api-v12-job: + +Jobs +==== + +.. _to-api-v12-job-route: + +/api/1.2/jobs +++++++++++++++++++ + +**GET /api/1.2/jobs** + + Get all jobs (currently limited to invalidate content (PURGE) jobs) sorted by start time (descending). + + Authentication Required: Yes + + Role(s) Required: Operations or Admin + + **Request Query Parameters** + + +-----------------+----------+---------------------------------------------------+ + | Name | Required | Description | + +=================+==========+===================================================+ + | ``dsId`` | no | Filter jobs by Delivery Service ID. | + +-----------------+----------+---------------------------------------------------+ + | ``userId`` | no | Filter jobs by User ID. | + +-----------------+----------+---------------------------------------------------+ + + **Response Properties** + + +----------------------+--------+-------------------------------------------------+ + | Parameter | Type | Description | + +======================+========+=================================================+ + |``id`` | int | Job id | + +----------------------+--------+-------------------------------------------------+ + |``assetUrl`` | string | URL of the asset to invalidate. | + +----------------------+--------+-------------------------------------------------+ + |``deliveryService`` | string | Unique identifier of the job's DS. | + +----------------------+--------+-------------------------------------------------+ + |``keyword`` | string | Job keyword (PURGE) | + +----------------------+--------+-------------------------------------------------+ + |``parameters`` | string | Parameters associated with the job. | + +----------------------+--------+-------------------------------------------------+ + |``startTime`` | string | Start time of the job. | + +----------------------+--------+-------------------------------------------------+ + |``createdBy`` | string | Username that initiated the job. | + +----------------------+--------+-------------------------------------------------+ + + **Response Example** :: + + { + "response": [ + { + "id": 1 + "assetUrl": "http:\/\/foo-bar.domain.net\/taco.html", + "deliveryService": "foo-bar", + "keyword": "PURGE", + "parameters": "TTL:48h", + "startTime": "2015-05-14 08:56:36-06", + "createdBy": "jdog24" + }, + { + "id": 2 + "assetUrl": "http:\/\/foo-bar.domain.net\/bell.html", + "deliveryService": "foo-bar", + "keyword": "PURGE", + "parameters": "TTL:72h", + "startTime": "2015-05-16 08:56:36-06", + "createdBy": "jdog24" + } + ] + } + +| + + +**GET /api/1.2/jobs/:id** + + Get a job by ID (currently limited to invalidate content (PURGE) jobs). + + Authentication Required: Yes + + Role(s) Required: Operations or Admin + + **Response Properties** + + +----------------------+--------+-------------------------------------------------+ + | Parameter | Type | Description | + +======================+========+=================================================+ + |``id`` | int | Job id | + +----------------------+--------+-------------------------------------------------+ + |``assetUrl`` | string | URL of the asset to invalidate. | + +----------------------+--------+-------------------------------------------------+ + |``deliveryService`` | string | Unique identifier of the job's DS. | + +----------------------+--------+-------------------------------------------------+ + |``keyword`` | string | Job keyword (PURGE) | + +----------------------+--------+-------------------------------------------------+ + |``parameters`` | string | Parameters associated with the job. | + +----------------------+--------+-------------------------------------------------+ + |``startTime`` | string | Start time of the job. | + +----------------------+--------+-------------------------------------------------+ + |``createdBy`` | string | Username that initiated the job. | + +----------------------+--------+-------------------------------------------------+ + + **Response Example** :: + + { + "response": [ + { + "id": 1 + "assetUrl": "http:\/\/foo-bar.domain.net\/taco.html", + "deliveryService": "foo-bar", + "keyword": "PURGE", + "parameters": "TTL:48h", + "startTime": "2015-05-14 08:56:36-06", + "createdBy": "jdog24" + } + ] + } + +| http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/b05a5114/traffic_ops/app/lib/API/Job.pm ---------------------------------------------------------------------- diff --git a/traffic_ops/app/lib/API/Job.pm b/traffic_ops/app/lib/API/Job.pm index 49891e5..0b2d804 100644 --- a/traffic_ops/app/lib/API/Job.pm +++ b/traffic_ops/app/lib/API/Job.pm @@ -38,6 +38,67 @@ use UI::Tools; use Data::Dumper; sub index { + my $self = shift; + my $ds_id = $self->param('dsId'); + my $user_id = $self->param('userId'); + + if ( !&is_oper($self) ) { + return $self->forbidden(); + } + + my %criteria; + if ( defined $ds_id ) { + $criteria{'job_deliveryservice'} = $ds_id; + } + if ( defined $user_id ) { + $criteria{'job_user'} = $user_id; + } + + my @data; + my $jobs = $self->db->resultset("Job")->search( \%criteria, { prefetch => [ 'job_deliveryservice', 'job_user' ], order_by => 'me.start_time DESC' } ); + while ( my $job = $jobs->next ) { + push( + @data, { + "id" => $job->id, + "assetUrl" => $job->asset_url, + "deliveryService" => $job->job_deliveryservice->xml_id, + "keyword" => $job->keyword, + "parameters" => $job->parameters, + "startTime" => $job->start_time, + "createdBy" => $job->job_user->username, + } + ); + } + $self->success( \@data ); +} + +sub show { + my $self = shift; + my $id = $self->param('id'); + + if ( !&is_oper($self) ) { + return $self->forbidden(); + } + + my $jobs = $self->db->resultset("Job")->search( { 'me.id' => $id }, { prefetch => [ 'job_deliveryservice', 'job_user' ] } ); + my @data = (); + while ( my $job = $jobs->next ) { + push( + @data, { + "id" => $job->id, + "keyword" => $job->keyword, + "assetUrl" => $job->asset_url, + "parameters" => $job->parameters, + "startTime" => $job->start_time, + "deliveryService" => $job->job_deliveryservice->xml_id, + "createdBy" => $job->job_user->username, + } + ); + } + $self->success( \@data ); +} + +sub get_current_user_jobs { my $self = shift; my $response = []; @@ -45,26 +106,26 @@ sub index { my $ds_id = $self->param('dsId'); my $keyword = $self->param('keyword') || 'PURGE'; - my $dbh; + my $jobs; if ( defined($ds_id) ) { - $dbh = $self->db->resultset('Job')->search( + $jobs = $self->db->resultset('Job')->search( { keyword => $keyword, 'job_user.username' => $username, 'job_deliveryservice.id' => $ds_id }, { prefetch => [ { 'job_deliveryservice' => undef } ], join => 'job_user' } ); - my $row_count = $dbh->count(); - if ( defined($dbh) && ( $row_count > 0 ) ) { - my @data = $self->job_ds_data($dbh); + my $job_count = $jobs->count(); + if ( defined($jobs) && ( $job_count > 0 ) ) { + my @data = $self->job_ds_data($jobs); my $rh = new Utils::Helper::ResponseHelper(); $response = $rh->camelcase_response_keys(@data); } } else { - $dbh = + $jobs = $self->db->resultset('Job') ->search( { keyword => $keyword, 'job_user.username' => $username }, { prefetch => [ { 'job_user' => undef } ], join => 'job_user' } ); - my $row_count = $dbh->count(); - if ( defined($dbh) && ( $row_count > 0 ) ) { - my @data = $self->job_data($dbh); + my $job_count = $jobs->count(); + if ( defined($jobs) && ( $job_count > 0 ) ) { + my @data = $self->job_data($jobs); my $rh = new Utils::Helper::ResponseHelper(); $response = $rh->camelcase_response_keys(@data); } @@ -75,7 +136,7 @@ sub index { # Creates a purge job based upon the Deliveryservice (ds_id) instead # of the ds_xml_id like the UI does. -sub create { +sub create_current_user_job { my $self = shift; my $ds_id = $self->req->json->{dsId}; @@ -195,11 +256,12 @@ sub is_valid_date_format { } sub is_ttl_in_range { - my $self = shift; - my $value = shift; + my $self = shift; + my $value = shift; my $min_hours = 1; my $max_days = - $self->db->resultset('Parameter')->search( { name => "maxRevalDurationDays" }, { config_file => "regex_revalidate.config" } )->get_column('value')->first; + $self->db->resultset('Parameter')->search( { name => "maxRevalDurationDays" }, { config_file => "regex_revalidate.config" } )->get_column('value') + ->first; my $max_hours = $max_days * 24; if ( !defined $value or $value eq '' ) { http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/b05a5114/traffic_ops/app/lib/Fixtures/Job.pm ---------------------------------------------------------------------- diff --git a/traffic_ops/app/lib/Fixtures/Job.pm b/traffic_ops/app/lib/Fixtures/Job.pm index ad01cce..6cb35b7 100644 --- a/traffic_ops/app/lib/Fixtures/Job.pm +++ b/traffic_ops/app/lib/Fixtures/Job.pm @@ -18,21 +18,53 @@ extends 'DBIx::Class::EasyFixture'; use namespace::autoclean; use POSIX qw(strftime); -my $now = strftime( "%Y-%m-%d %H:%M:%S", gmtime() ); my %definition_for = ( - admin_job1 => { + job1 => { new => 'Job', using => { + id => 100, agent => 1, keyword => 'PURGE', parameters => 'TTL:48h', - asset_url => 'http://cdn2.edge/foo1/.*', + asset_url => 'http://cdn2.edge/job1/.*', asset_type => 'file', status => 1, - start_time => $now, + start_time => strftime( "%Y-%m-%d %H:%M:%S", gmtime( time() - 1000 ) ), job_user => 100, job_deliveryservice => 100, - entered_time => $now + entered_time => strftime( "%Y-%m-%d %H:%M:%S", gmtime( time() - 1000 ) ), + }, + }, + job2 => { + new => 'Job', + using => { + id => 200, + agent => 1, + keyword => 'PURGE', + parameters => 'TTL:48h', + asset_url => 'http://cdn2.edge/job2/.*', + asset_type => 'file', + status => 1, + start_time => strftime( "%Y-%m-%d %H:%M:%S", gmtime( time() - 500 ) ), + job_user => 100, + job_deliveryservice => 200, + entered_time => strftime( "%Y-%m-%d %H:%M:%S", gmtime( time() - 500 ) ), + }, + }, + job3 => { + new => 'Job', + using => { + id => 300, + agent => 1, + keyword => 'PURGE', + parameters => 'TTL:48h', + asset_url => 'http://cdn2.edge/job3/.*', + asset_type => 'file', + status => 1, + start_time => strftime( "%Y-%m-%d %H:%M:%S", gmtime( time() - 200 ) ), + job_user => 200, + job_deliveryservice => 100, + entered_time => strftime( "%Y-%m-%d %H:%M:%S", gmtime( time() - 200 ) ), }, }, ); @@ -43,8 +75,7 @@ sub get_definition { } sub all_fixture_names { - # sort by db name to guarantee insertion order - return (sort { $definition_for{$a}{using}{id} cmp $definition_for{$b}{using}{id} } keys %definition_for); + return keys %definition_for; } __PACKAGE__->meta->make_immutable; http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/b05a5114/traffic_ops/app/lib/TrafficOpsRoutes.pm ---------------------------------------------------------------------- diff --git a/traffic_ops/app/lib/TrafficOpsRoutes.pm b/traffic_ops/app/lib/TrafficOpsRoutes.pm index 083636a..553c967 100644 --- a/traffic_ops/app/lib/TrafficOpsRoutes.pm +++ b/traffic_ops/app/lib/TrafficOpsRoutes.pm @@ -585,6 +585,10 @@ sub api_routes { $r->get("/api/$version/hwinfo/dtdata")->over( authenticated => 1 )->to( 'HwInfo#data', namespace => $namespace ); $r->get("/api/$version/hwinfo")->over( authenticated => 1 )->to( 'HwInfo#index', namespace => $namespace ); + # -- JOBS + $r->get("/api/$version/jobs")->over( authenticated => 1 )->to( 'Job#index', namespace => $namespace ); + $r->get("/api/$version/jobs/:id")->over( authenticated => 1 )->to( 'Job#show', namespace => $namespace ); + # -- PARAMETERS # Supports ?orderby=key $r->get("/api/$version/parameters")->over( authenticated => 1 )->to( 'Parameter#index', namespace => $namespace ); @@ -744,8 +748,8 @@ sub api_routes { ->to( 'User#get_available_deliveryservices', namespace => $namespace ); # -- USERS: JOBS - $r->get("/api/$version/user/current/jobs")->over( authenticated => 1 )->to( 'Job#index', namespace => $namespace ); - $r->post("/api/$version/user/current/jobs")->over( authenticated => 1 )->to( 'Job#create', namespace => $namespace ); + $r->get("/api/$version/user/current/jobs")->over( authenticated => 1 )->to( 'Job#get_current_user_jobs', namespace => $namespace ); + $r->post("/api/$version/user/current/jobs")->over( authenticated => 1 )->to( 'Job#create_current_user_job', namespace => $namespace ); # -- RIAK # -- RIAK: KEYS http://git-wip-us.apache.org/repos/asf/incubator-trafficcontrol/blob/b05a5114/traffic_ops/app/t/api/1.2/job.t ---------------------------------------------------------------------- diff --git a/traffic_ops/app/t/api/1.2/job.t b/traffic_ops/app/t/api/1.2/job.t new file mode 100644 index 0000000..9b92564 --- /dev/null +++ b/traffic_ops/app/t/api/1.2/job.t @@ -0,0 +1,58 @@ +package main; +# +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +use Mojo::Base -strict; +use Test::More; +use Test::Mojo; +use DBI; +use strict; +use warnings; +no warnings 'once'; +use warnings 'all'; +use Test::TestHelper; + +#no_transactions=>1 ==> keep fixtures after every execution, beware of duplicate data! +#no_transactions=>0 ==> delete fixtures after every execution + +BEGIN { $ENV{MOJO_MODE} = "test" } + +my $schema = Schema->connect_to_database; +my $t = Test::Mojo->new('TrafficOps'); + +Test::TestHelper->unload_core_data($schema); +Test::TestHelper->load_core_data($schema); + +ok $t->post_ok( '/login', => form => { u => Test::TestHelper::ADMIN_USER, p => Test::TestHelper::ADMIN_USER_PASSWORD } )->status_is(302) + ->or( sub { diag $t->tx->res->content->asset->{content}; } ), 'Should login?'; + +# get first one sorted by start_time DESC +$t->get_ok("/api/1.2/jobs")->status_is(200)->json_is( "/response/0/id", 300 ) + ->json_is( "/response/0/assetUrl", "http://cdn2.edge/job3/.*" )->or( sub { diag $t->tx->res->content->asset->{content}; } ); + +# get first one sorted by start_time and filtered by DS +$t->get_ok("/api/1.2/jobs?dsId=200")->status_is(200)->json_is( "/response/0/id", 200 ) + ->json_is( "/response/0/assetUrl", "http://cdn2.edge/job2/.*" )->or( sub { diag $t->tx->res->content->asset->{content}; } ); + +# get first one sorted by start_time and filtered by User +$t->get_ok("/api/1.2/jobs?userId=200")->status_is(200)->json_is( "/response/0/id", 300 ) + ->json_is( "/response/0/assetUrl", "http://cdn2.edge/job3/.*" )->or( sub { diag $t->tx->res->content->asset->{content}; } ); + +# get specific job +$t->get_ok("/api/1.2/jobs/100")->status_is(200)->json_is( "/response/0/id", 100 ) + ->json_is( "/response/0/keyword", "PURGE" )->or( sub { diag $t->tx->res->content->asset->{content}; } ); + +ok $t->get_ok('/logout')->status_is(302)->or( sub { diag $t->tx->res->content->asset->{content}; } ); +done_testing(); +
