File Coverage

blib/lib/Pinto/Remote/Action.pm
Criterion Covered Total %
statement 33 82 40.2
branch 0 12 0.0
condition 0 9 0.0
subroutine 11 20 55.0
pod 1 1 100.0
total 45 124 36.2


line stmt bran cond sub pod time code
1             # ABSTRACT: Base class for remote Actions
2              
3             package Pinto::Remote::Action;
4              
5 5     5   140 use Moose;
  5         186  
  5         40  
6 5     5   30432 use MooseX::StrictConstructor;
  5         12  
  5         39  
7 5     5   15529 use MooseX::MarkAsMethods ( autoclean => 1 );
  5         13  
  5         41  
8 5     5   16445 use MooseX::Types::Moose qw(Str Maybe);
  5         12  
  5         312  
9              
10 5     5   22333 use URI;
  5         11  
  5         118  
11 5     5   2076 use JSON;
  5         24272  
  5         29  
12 5     5   2108 use HTTP::Request::Common;
  5         8400  
  5         400  
13              
14 5     5   1375 use Pinto::Result;
  5         21  
  5         225  
15 5     5   41 use Pinto::Constants qw(:protocol);
  5         9  
  5         397  
16 5     5   663 use Pinto::Util qw(current_time_offset);
  5         12  
  5         244  
17 5     5   28 use Pinto::Types qw(Uri);
  5         10  
  5         41  
18              
19             #------------------------------------------------------------------------------
20              
21             our $VERSION = '0.13'; # VERSION
22              
23             #------------------------------------------------------------------------------
24              
25             with qw(Pinto::Role::Plated Pinto::Role::UserAgent);
26              
27             #------------------------------------------------------------------------------
28              
29             has name => (
30             is => 'ro',
31             isa => Str,
32             required => 1,
33             );
34              
35             has root => (
36             is => 'ro',
37             isa => Uri,
38             required => 1,
39             );
40              
41             has args => (
42             is => 'ro',
43             isa => 'HashRef',
44             default => sub { {} },
45             );
46              
47             has username => (
48             is => 'ro',
49             isa => Str,
50             required => 1
51             );
52              
53             has password => (
54             is => 'ro',
55             isa => Maybe [Str],
56             required => 1,
57             );
58              
59             #------------------------------------------------------------------------------
60              
61              
62             sub execute {
63 0     0 1   my ($self) = @_;
64              
65 0           my $request = $self->_make_request;
66 0           my $result = $self->_send_request( req => $request );
67              
68 0           return $result;
69             }
70              
71             #------------------------------------------------------------------------------
72              
73             sub _make_request {
74 0     0     my ( $self, %args ) = @_;
75              
76 0   0       my $action_name = $args{name} || $self->name;
77 0   0       my $request_body = $args{body} || $self->_make_request_body;
78              
79 0           my $uri = URI->new( $self->root );
80 0           $uri->path_segments( '', 'action', lc $action_name );
81              
82 0           my $request = POST(
83             $uri,
84             Accept => $PINTO_PROTOCOL_ACCEPT,
85             Content => $request_body,
86             Content_Type => 'form-data',
87              
88             );
89              
90 0 0         if ( defined $self->password ) {
91 0           $request->authorization_basic( $self->username, $self->password );
92             }
93              
94 0           return $request;
95             }
96              
97             #------------------------------------------------------------------------------
98              
99             sub _make_request_body {
100 0     0     my ($self) = @_;
101              
102 0           return [ $self->_chrome_args, $self->_pinto_args, $self->_action_args ];
103             }
104              
105             #------------------------------------------------------------------------------
106              
107             sub _chrome_args {
108 0     0     my ($self) = @_;
109              
110 0           my $chrome_args = {
111             verbose => $self->chrome->verbose,
112             color => $self->chrome->color,
113             palette => $self->chrome->palette,
114             quiet => $self->chrome->quiet
115             };
116              
117 0           return ( chrome => encode_json($chrome_args) );
118              
119             }
120              
121             #------------------------------------------------------------------------------
122              
123             sub _pinto_args {
124 0     0     my ($self) = @_;
125              
126 0           my $pinto_args = {
127             username => $self->username,
128             time_offset => current_time_offset,
129             };
130              
131 0           return ( pinto => encode_json($pinto_args) );
132             }
133              
134             #------------------------------------------------------------------------------
135              
136             sub _action_args {
137 0     0     my ($self) = @_;
138              
139 0           my $action_args = $self->args;
140              
141 0           return ( action => encode_json($action_args) );
142             }
143              
144             #------------------------------------------------------------------------------
145              
146             sub _send_request {
147 0     0     my ( $self, %args ) = @_;
148              
149 0   0       my $request = $args{req} || $self->_make_request;
150 0           my $status = 0;
151 0           my $buffer = '';
152              
153             # Currying in some extra args to the callback...
154 0     0     my $callback = sub { $self->_response_callback( \$status, \$buffer, @_ ) };
  0            
155 0           my $response = $self->request( $request, $callback );
156              
157 0 0         if ( not $response->is_success ) {
158 0           $self->error( $response->content );
159 0           return Pinto::Result->new( was_successful => 0 );
160             }
161              
162 0           return Pinto::Result->new( was_successful => $status );
163             }
164              
165             #------------------------------------------------------------------------------
166              
167             sub _response_callback {
168 0     0     my ( $self, $status, $buffer, $data ) = @_;
169              
170 0           $data = ${$buffer}.$data;
  0            
171 0           while($data =~ /\G([^\n]*)\n/gc) {
172 0           my $line = $1;
173 0 0         if ( $line eq $PINTO_PROTOCOL_STATUS_OK ) {
    0          
    0          
    0          
174 0           ${$status} = 1;
  0            
175             }
176             elsif ( $line eq $PINTO_PROTOCOL_PROGRESS_MESSAGE ) {
177 0           $self->chrome->show_progress;
178             }
179             elsif ( $line eq $PINTO_PROTOCOL_NULL_MESSAGE ) {
180             # Do nothing, discard message
181             }
182             elsif ( $line =~ m{^ \Q$PINTO_PROTOCOL_DIAG_PREFIX\E (.*)}x ) {
183 0           $self->chrome->diag($1);
184             }
185             else {
186 0           $self->chrome->show($line);
187             }
188             }
189             #Save leftovers, use them in next packet
190 0           (${$buffer}) = ($data =~ /\G(.*)$/g);
  0            
191              
192 0           return 1;
193             }
194              
195             #-----------------------------------------------------------------------------
196              
197             __PACKAGE__->meta->make_immutable;
198              
199             #------------------------------------------------------------------------------
200             1;
201              
202             __END__
203              
204             =pod
205              
206             =encoding UTF-8
207              
208             =for :stopwords Jeffrey Ryan Thalhammer
209              
210             =head1 NAME
211              
212             Pinto::Remote::Action - Base class for remote Actions
213              
214             =head1 VERSION
215              
216             version 0.13
217              
218             =head1 METHODS
219              
220             =head2 execute
221              
222             Runs this Action on the remote server by serializing itself and
223             sending a POST request to the server. Returns a L<Pinto::Result>.
224              
225             =head1 AUTHOR
226              
227             Jeffrey Ryan Thalhammer <jeff@stratopan.com>
228              
229             =head1 COPYRIGHT AND LICENSE
230              
231             This software is copyright (c) 2015 by Jeffrey Ryan Thalhammer.
232              
233             This is free software; you can redistribute it and/or modify it under
234             the same terms as the Perl 5 programming language system itself.
235              
236             =cut