File Coverage

blib/lib/IO/Iron/IronWorker/Client.pm
Criterion Covered Total %
statement 60 276 21.7
branch 3 44 6.8
condition n/a
subroutine 14 29 48.2
pod 15 15 100.0
total 92 364 25.2


line stmt bran cond sub pod time code
1             package IO::Iron::IronWorker::Client;
2              
3             ## no critic (Documentation::RequirePodAtEnd
4             ## no critic (Documentation::RequirePodSections)
5             ## no critic (ControlStructures::ProhibitPostfixControls)
6             ## no critic (Subroutines::RequireArgUnpacking)
7              
8 4     4   97692 use 5.010_000;
  4         20  
9 4     4   20 use strict;
  4         8  
  4         91  
10 4     4   20 use warnings;
  4         6  
  4         149  
11              
12             # Global creator
13             BEGIN {
14 4     4   812 use parent qw( IO::Iron::ClientBase ); # Inheritance
  4         596  
  4         21  
15             }
16              
17             # Global destructor
18       4     END {
19             }
20              
21              
22             # ABSTRACT: IronWorker (Online Worker Platform) Client.
23              
24             our $VERSION = '0.13'; # VERSION: generated by DZP::OurPkgVersion
25              
26              
27              
28 4     4   357 use Log::Any qw{$log};
  4         22  
  4         25  
29 4     4   873 use Hash::Util 0.06 qw{lock_keys lock_keys_plus unlock_keys legal_keys};
  4         68  
  4         23  
30 4     4   289 use Carp::Assert::More;
  4         10  
  4         651  
31 4     4   60 use English '-no_match_vars';
  4         10  
  4         23  
32 4     4   2611 use Params::Validate qw(:all);
  4         23177  
  4         674  
33              
34 4     4   1818 use IO::Iron::IronWorker::Api ();
  4         10  
  4         94  
35 4     4   804 use IO::Iron::Common ();
  4         11  
  4         162  
36             require IO::Iron::Connection;
37             require IO::Iron::IronWorker::Task;
38              
39             # CONSTANTS for this package
40              
41             # DEFAULTS
42 4     4   864 use Const::Fast;
  4         4724  
  4         23  
43              
44             # Service specific!
45             const my $DEFAULT_API_VERSION => '2';
46             const my $DEFAULT_HOST => 'worker-aws-us-east-1.iron.io';
47              
48              
49              
50             sub new {
51 1     1 1 1900 my $class = shift;
52             my %params = validate(
53             @_, {
54 1         5 map { $_ => { type => SCALAR, optional => 1 }, } IO::Iron::Common::IRON_CLIENT_PARAMETERS(), ## no critic (ValuesAndExpressions::ProhibitCommaSeparatedStatements)
  10         58  
55             }
56             );
57              
58 1         14 $log->tracef('Entering new(%s, %s)', $class, \%params);
59 1         9 my $self = IO::Iron::ClientBase->new();
60             # Add more keys to the self hash.
61             my @self_keys = (
62 1         2 legal_keys(%{$self}),
  1         4  
63             );
64 1         6 unlock_keys(%{$self});
  1         4  
65 1         10 lock_keys_plus(%{$self}, @self_keys);
  1         5  
66 1         35 my $config = IO::Iron::Common::get_config(%params);
67 1         6 $log->debugf('The config: %s', $config);
68 1 50       6 $self->{'project_id'} = defined $config->{'project_id'} ? $config->{'project_id'} : undef;
69 1         6 assert_nonblank( $self->{'project_id'}, 'self->{project_id} is not defined or is blank');
70              
71 1         14 unlock_keys(%{$self});
  1         4  
72 1         10 bless $self, $class;
73 1         2 lock_keys(%{$self}, @self_keys);
  1         11  
74              
75             # Set up the connection client
76             my $connection = IO::Iron::Connection->new( {
77             'project_id' => $config->{'project_id'},
78             'token' => $config->{'token'},
79             'host' => defined $config->{'host'} ? $config->{'host'} : $DEFAULT_HOST,
80             'protocol' => $config->{'protocol'},
81             'port' => $config->{'port'},
82             'api_version' => defined $config->{'api_version'} ? $config->{'api_version'} : $DEFAULT_API_VERSION,
83             'timeout' => $config->{'timeout'},
84 1 50       59 'connector' => $params{'connector'},
    50          
85             }
86             );
87 1         7 $self->{'connection'} = $connection;
88 1         7 $log->debugf('IronWorker Client created with config: (project_id=%s; token=%s; host=%s; timeout=%s).', $config->{'project_id'}, $config->{'token'}, $config->{'host'}, $config->{'timeout'});
89 1         5 $log->tracef('Exiting new: %s', $self);
90 1         14 return $self;
91             }
92              
93             ###############################################
94             ######## FUNCTIONS: CODE PACKAGES #############
95             ###############################################
96              
97              
98             sub list_code_packages {
99 0     0 1   my ($self) = @_;
100 0           $log->tracef('Entering list_code_packages()');
101              
102 0           my $connection = $self->{'connection'};
103 0           my ($http_status_code, $response_message) = $connection->perform_iron_action(
104             IO::Iron::IronWorker::Api::IRONWORKER_LIST_CODE_PACKAGES(), { } );
105 0           $self->{'last_http_status_code'} = $http_status_code;
106 0           my @codes;
107 0           foreach (@{$response_message}) {
  0            
108 0           push @codes, $_;
109             }
110 0           $log->debugf('Returning %d code packages.', scalar @codes);
111 0           $log->tracef('Exiting list_code_packages: %s', \@codes);
112 0           return @codes;
113             }
114              
115              
116             sub update_code_package {
117 0     0 1   my $self = shift;
118 0           my %params = validate(
119             @_, {
120             'name' => { type => SCALAR, }, # Code package name.
121             'file' => { type => SCALAR, optional => 1, # The zip archive as a string buffer.
122             depends => [ 'file_name', 'runtime' ], },
123             'file_name' => { type => SCALAR, optional => 1 }, # Name of the zip file, not
124             'runtime' => { type => SCALAR, optional => 1, }, # The runtime type, e.g. sh, perl, ruby.
125             'config' => { type => SCALAR, optional => 1, },
126             'max_concurrency' => { type => SCALAR, optional => 1, },
127             'retries' => { type => SCALAR, optional => 1, },
128             'retries_delay' => { type => SCALAR, optional => 1, },
129             }
130             );
131 0           $log->tracef('Entering update_code_package(%s)', \%params);
132 0           my $connection = $self->{'connection'};
133 0           my ($http_status_code, $response_message) = $connection->perform_iron_action(
134             IO::Iron::IronWorker::Api::IRONWORKER_UPLOAD_OR_UPDATE_A_CODE_PACKAGE(),
135             {
136             'body' => \%params,
137             }
138             );
139 0           $self->{'last_http_status_code'} = $http_status_code;
140 0           my $id = $response_message->{'id'};
141 0           $log->tracef('Exiting update_code_package: %s', $id);
142 0           return $id;
143             }
144              
145              
146             sub get_info_about_code_package {
147 0     0 1   my $self = shift;
148 0           my %params = validate(
149             @_, {
150             'id' => { type => SCALAR, }, # Code package id.
151             }
152             );
153 0           $log->tracef('Entering get_info_about_code_package(%s)', \%params);
154 0           my $connection = $self->{'connection'};
155             my ($http_status_code, $response_message) = $connection->perform_iron_action(
156             IO::Iron::IronWorker::Api::IRONWORKER_GET_INFO_ABOUT_A_CODE_PACKAGE(),
157 0           { '{Code ID}' => $params{'id'}, }
158             );
159 0           $self->{'last_http_status_code'} = $http_status_code;
160 0           my $info = $response_message;
161 0           $log->tracef('Exiting get_info_about_code_package: %s', $info);
162 0           return $info;
163             }
164              
165              
166             sub delete_code_package {
167 0     0 1   my $self = shift;
168 0           my %params = validate(
169             @_, {
170             'id' => { type => SCALAR, }, # Code package id.
171             }
172             );
173 0           $log->tracef('Entering delete_code_package(%s)', $params{'id'});
174 0           my $connection = $self->{'connection'};
175             my ($http_status_code, $response_message) = $connection->perform_iron_action(
176             IO::Iron::IronWorker::Api::IRONWORKER_DELETE_A_CODE_PACKAGE(),
177             {
178 0           '{Code ID}' => $params{'id'},
179             }
180             );
181 0           $self->{'last_http_status_code'} = $http_status_code;
182 0           $log->tracef('Exiting delete_code_package: %d', 1);
183 0           return 1;
184             }
185              
186              
187             sub download_code_package {
188 0     0 1   my $self = shift;
189 0           my %params = validate(
190             @_, {
191             'id' => { type => SCALAR, }, # Code package id.
192             'revision' => { type => SCALAR, optional => 1, }, # Code package revision.
193             }
194             );
195 0           $log->tracef('Entering download_code_package(%s)', \%params);
196 0           my $connection = $self->{'connection'};
197 0           my %query_params;
198 0 0         $query_params{'{revision}'} = $params{'revision'} if $params{'revision'}; ## no critic (ControlStructures::ProhibitPostfixControls)
199             my ($http_status_code, $response_message) = $connection->perform_iron_action(
200             IO::Iron::IronWorker::Api::IRONWORKER_DOWNLOAD_A_CODE_PACKAGE(),
201             {
202 0           '{Code ID}' => $params{'id'},
203             %query_params,
204             }
205             );
206 0           my $code_package = $response_message->{'file'};
207 0           my $file_name = $response_message->{'file_name'};
208 0           $self->{'last_http_status_code'} = $http_status_code;
209              
210 0           $log->tracef('Exiting download_code_package:%s, %s', $code_package, $file_name);
211 0           return ($code_package, $file_name);
212             }
213              
214              
215             sub list_code_package_revisions {
216 0     0 1   my $self = shift;
217 0           my %params = validate(
218             @_, {
219             'id' => { type => SCALAR, }, # Code package id.
220             }
221             );
222 0           $log->tracef('Entering list_code_package_revisions(%s)', $params{'id'});
223              
224 0           my $connection = $self->{'connection'};
225             my ($http_status_code, $response_message) = $connection->perform_iron_action(
226             IO::Iron::IronWorker::Api::IRONWORKER_LIST_CODE_PACKAGE_REVISIONS(),
227 0           { '{Code ID}' => $params{'id'}, }
228             );
229 0           my @revisions;
230 0           foreach (@{$response_message}) {
  0            
231 0           push @revisions, $_;
232             }
233 0           $log->debugf('Returning %d code packages.', scalar @revisions);
234 0           $log->tracef('Exiting list_code_package_revisions: %s', \@revisions);
235 0           return @revisions;
236             }
237              
238              
239             ###############################################
240             ######## FUNCTIONS: TASK ######################
241             ###############################################
242              
243              
244             sub create_task {
245 0     0 1   my $self = shift;
246             my %params = validate_with(
247             'params' => \@_,
248 0     0     'normalize_keys' => sub { return lc shift },
249 0           'spec' => {
250             'code_name' => { type => SCALAR, }, # Code package name.
251             'payload' => { type => SCALAR, }, # Payload
252             },
253             'allow_extra' => 1,
254             );
255 0           $log->tracef('Entering create_task(%s)', \%params);
256              
257 0           my $connection = $self->{'connection'};
258              
259 0           my $task = IO::Iron::IronWorker::Task->new({
260             'ironworker_client' => $self, # Pass a reference to the parent object.
261             'connection' => $connection,
262             %params,
263             });
264              
265 0           $log->tracef('Exiting create_task: %s', $task);
266 0           return $task;
267             }
268              
269              
270             sub tasks {
271 0     0 1   my $self = shift;
272 0           my %params = validate(
273             @_, {
274             'code_name' => { type => SCALAR, }, # Code package name.
275             'queued' => { type => SCALAR, 'optional' => 1, },
276             'running' => { type => SCALAR, 'optional' => 1, },
277             'complete' => { type => SCALAR, 'optional' => 1, },
278             'error' => { type => SCALAR, 'optional' => 1, },
279             'cancelled' => { type => SCALAR, 'optional' => 1, },
280             'killed' => { type => SCALAR, 'optional' => 1, },
281             'from_time' => { type => SCALAR, 'optional' => 1, },
282             'to_time' => { type => SCALAR, 'optional' => 1, },
283             }
284             );
285 0           $log->tracef('Entering tasks(%s, %s)', \%params);
286              
287 0           my $code_name = $params{'code_name'};
288 0           delete $params{'code_name'};
289 0           my $connection = $self->{'connection'};
290 0           my ($http_status_code, $response_message) = $connection->perform_iron_action(
291             IO::Iron::IronWorker::Api::IRONWORKER_LIST_TASKS(), {
292             '{code_name}' => $code_name,
293             %params,
294             } );
295 0           $self->{'last_http_status_code'} = $http_status_code;
296 0           my @tasks;
297 0           foreach (@{$response_message}) {
  0            
298 0           $log->debugf('task info:%s', $_);
299             push @tasks, $self->create_task(
300             'code_name' => $_->{'code_name'},
301             'payload' => $_->{'payload'} ? $_->{'payload'} : q{},
302 0 0         %{$_},
  0            
303             );
304             }
305 0           $log->debugf('Returning %d tasks.', scalar @tasks);
306 0           $log->tracef('Exiting tasks: %s', \@tasks);
307 0           return @tasks;
308             }
309              
310              
311             sub queue {
312 0     0 1   my $self = shift;
313 0           my %validate_params = (
314             'tasks' => { type => OBJECT | ARRAYREF, }, # ref to task.
315             );
316 0           my %params = validate(
317             @_, {
318             %validate_params
319             }
320             );
321 0           lock_keys(%params, keys %validate_params);
322 0           $log->tracef('Entering queue(%s)', \%params);
323              
324 0           my $connection = $self->{'connection'};
325 0           my @message_tasks;
326 0 0         if(ref $params{'tasks'} eq 'IO::Iron::IronWorker::Task') {
327 0           $params{'tasks'} = [ $params{'tasks'} ];
328             }
329 0           foreach my $task (@{$params{'tasks'}}) {
  0            
330 0           assert_isa( $task, 'IO::Iron::IronWorker::Task', 'task is IO::Iron::IronWorker::Task.');
331 0           my %task_body;
332 0           $task_body{'code_name'} = $task->{'code_name'};
333 0           $task_body{'payload'} = $task->{'payload'};
334 0 0         $task_body{'priority'} = $task->{'priority'} if defined $task->{'priority'};
335 0 0         $task_body{'timeout'} = $task->{'timeout'} if defined $task->{'timeout'};
336 0 0         $task_body{'delay'} = $task->{'delay'} if defined $task->{'delay'};
337 0 0         $task_body{'name'} = $task->{'name'} if defined $task->{'name'};
338 0           push @message_tasks, \%task_body;
339             }
340              
341 0           my %message_body = ('tasks' => \@message_tasks);
342 0           my ($http_status_code, $response_message) = $connection->perform_iron_action(
343             IO::Iron::IronWorker::Api::IRONWORKER_QUEUE_A_TASK(),
344             {
345             'body' => \%message_body,
346             }
347             );
348 0           $self->{'last_http_status_code'} = $http_status_code;
349              
350 0           my @ids;
351 0           my @ret_tasks = ( @{ $response_message->{'tasks'} } ); # tasks.
  0            
352 0           foreach my $task (@{$params{'tasks'}}) {
  0            
353 0           my $task_info = shift @ret_tasks; # We are using the same task objects.
354 0           push @ids, $task_info->{'id'};
355 0           $task->id( $task_info->{'id'} );
356             }
357             #assert_is($response_message->{'msg'}, 'Queued up'); # Could be dangerous!
358 0           $log->debugf( 'Queued IronWorker Task(s) (task id(s)=%s).', ( join q{,}, @ids ) );
359 0 0         if (wantarray) {
360 0           $log->tracef( 'Exiting queue: %s', ( join q{:}, @ids ) );
361 0           return @ids;
362             }
363             else {
364 0 0         if ( scalar @{$params{'tasks'}} == 1 ) {
  0            
365 0           $log->tracef( 'Exiting queue: %s', $ids[0] );
366 0           return $ids[0];
367             }
368             else {
369 0           $log->tracef( 'Exiting queue: %s', scalar @ids );
370 0           return scalar @ids;
371             }
372             }
373             }
374              
375              
376             sub get_info_about_task {
377 0     0 1   my $self = shift;
378 0           my %params = validate(
379             @_, {
380             'id' => { type => SCALAR, }, # task id.
381             }
382             );
383 0           $log->tracef('Entering get_info_about_task(%s)', \%params);
384              
385 0           my $connection = $self->{'connection'};
386             my ($http_status_code, $response_message) = $connection->perform_iron_action(
387             IO::Iron::IronWorker::Api::IRONWORKER_GET_INFO_ABOUT_A_TASK(),
388 0           { '{Task ID}' => $params{'id'}, }
389             );
390 0           $self->{'last_http_status_code'} = $http_status_code;
391 0           my $info = $response_message;
392 0           $log->tracef('Exiting get_info_about_task: %s', $info);
393 0           return $info;
394             }
395              
396             ###############################################
397             ######## FUNCTIONS: SCHEDULED TASK ############
398             ###############################################
399              
400              
401             sub scheduled_tasks {
402 0     0 1   my ($self) = @_;
403 0           $log->tracef('Entering scheduled_tasks()');
404              
405 0           my $connection = $self->{'connection'};
406 0           my ($http_status_code, $response_message) = $connection->perform_iron_action(
407             IO::Iron::IronWorker::Api::IRONWORKER_LIST_SCHEDULED_TASKS(), { } );
408 0           $self->{'last_http_status_code'} = $http_status_code;
409 0           my @tasks;
410 0           foreach (@{$response_message}) {
  0            
411 0           $log->debugf('task info:%s', $_);
412             push @tasks, $self->create_task(
413             'code_name' => $_->{'code_name'},
414             'payload' => $_->{'payload'} ? $_->{'payload'} : q{},
415 0 0         %{$_},
  0            
416             );
417             }
418 0           $log->debugf('Returning %d tasks.', scalar @tasks);
419 0           $log->tracef('Exiting scheduled_tasks: %s', \@tasks);
420 0           return @tasks;
421             }
422              
423              
424             sub schedule {
425 0     0 1   my $self = shift;
426 0           my %validate_params = (
427             'tasks' => { type => OBJECT | ARRAYREF, }, # ref to task.
428             );
429 0           my %params = validate(
430             @_, {
431             %validate_params
432             }
433             );
434 0           lock_keys(%params, keys %validate_params);
435 0           $log->tracef('Entering schedule(%s)', \%params);
436              
437 0           my $connection = $self->{'connection'};
438 0           my @message_tasks;
439 0 0         if(ref $params{'tasks'} eq 'IO::Iron::IronWorker::Task') {
440 0           $log->debugf('The parameter is a single object.');
441 0           $params{'tasks'} = [ $params{'tasks'} ];
442             }
443 0           foreach my $task (@{$params{'tasks'}}) {
  0            
444 0           assert_isa( $task, 'IO::Iron::IronWorker::Task', 'task is IO::Iron::IronWorker::Task.');
445 0           my %task_body;
446 0           $task_body{'code_name'} = $task->{'code_name'};
447 0           $task_body{'payload'} = $task->{'payload'};
448 0 0         $task_body{'run_every'} = $task->{'run_every'} if defined $task->{'run_every'};
449 0 0         $task_body{'end_at'} = $task->{'end_at'} if defined $task->{'end_at'};
450 0 0         $task_body{'run_times'} = $task->{'run_times'} if defined $task->{'run_times'};
451 0 0         $task_body{'priority'} = $task->{'priority'} if defined $task->{'priority'};
452 0 0         $task_body{'start_at'} = $task->{'start_at'} if defined $task->{'start_at'};
453 0 0         $task_body{'name'} = $task->{'name'} if defined $task->{'name'}; # Hm... documents do not mention but example does...
454 0           push @message_tasks, \%task_body;
455             }
456              
457 0           my %message_body = ('schedules' => \@message_tasks);
458 0           my ($http_status_code, $response_message) = $connection->perform_iron_action(
459             IO::Iron::IronWorker::Api::IRONWORKER_SCHEDULE_A_TASK(),
460             {
461             'body' => \%message_body,
462             }
463             );
464 0           $self->{'last_http_status_code'} = $http_status_code;
465              
466 0           my ( @ids, $msg ); ## no critic (Variables::ProhibitUnusedVariables)
467 0           my @ret_tasks = ( @{ $response_message->{'schedules'} } ); # scheduled tasks.
  0            
468 0           foreach my $task (@{$params{'tasks'}}) {
  0            
469 0           my $task_info = shift @ret_tasks;
470 0           push @ids, $task_info->{'id'};
471 0           $task->id( $task_info->{'id'} );
472             }
473             #assert_is($response_message->{'msg'}, 'Scheduled'); # Could be dangerous!
474             ## It was dangerous! Failing discovered 2014-08-10, response message has dropped the field "msg"!
475 0           $log->debugf( 'Scheduled IronWorker Task(s) (task id(s)=%s).', ( join q{,}, @ids ) );
476 0 0         if (wantarray) {
477 0           $log->tracef( 'Exiting schedule: %s', ( join q{:}, @ids ) );
478 0           return @ids;
479             }
480             else {
481 0 0         if ( scalar @{$params{'tasks'}} == 1 ) {
  0            
482 0           $log->tracef( 'Exiting schedule: %s', $ids[0] );
483 0           return $ids[0];
484             }
485             else {
486 0           $log->tracef( 'Exiting schedule: %s', scalar @ids );
487 0           return scalar @ids;
488             }
489             }
490             }
491              
492              
493             sub get_info_about_scheduled_task {
494 0     0 1   my $self = shift;
495 0           my %params = validate(
496             @_, {
497             'id' => { type => SCALAR, }, # task id.
498             }
499             );
500 0           $log->tracef('Entering get_info_about_scheduled_task(%s)', \%params);
501              
502 0           my $connection = $self->{'connection'};
503             my ($http_status_code, $response_message) = $connection->perform_iron_action(
504             IO::Iron::IronWorker::Api::IRONWORKER_GET_INFO_ABOUT_A_SCHEDULED_TASK(),
505 0           { '{Schedule ID}' => $params{'id'}, }
506             );
507 0           $self->{'last_http_status_code'} = $http_status_code;
508 0           my $info = $response_message;
509 0           $log->tracef('Exiting get_info_about_scheduled_task: %s', $info);
510 0           return $info;
511             }
512              
513             ###############################################
514             ########### FUNCTIONS: STACKS #################
515             ###############################################
516              
517              
518             sub list_available_stacks {
519 0     0 1   my ($self) = @_;
520 0           $log->tracef('Entering list_available_stacks()');
521              
522 0           my $connection = $self->{'connection'};
523 0           my ($http_status_code, $response_message) = $connection->perform_iron_action(
524             IO::Iron::IronWorker::Api::IRONWORKER_LIST_OF_AVAILABLE_STACKS(), { } );
525 0           $self->{'last_http_status_code'} = $http_status_code;
526 0           my @stacks;
527 0           foreach (@{$response_message}) {
  0            
528 0           push @stacks, $_;
529             }
530 0           $log->debugf('Returning %d stacks.', scalar @stacks);
531 0           $log->tracef('Exiting list_available_stacks(): %s', \@stacks);
532 0           return @stacks;
533             }
534              
535             1;
536              
537             __END__