File Coverage

blib/lib/App/MBUtiny/Collector/Client.pm
Criterion Covered Total %
statement 18 102 17.6
branch 0 28 0.0
condition 0 18 0.0
subroutine 6 15 40.0
pod 8 8 100.0
total 32 171 18.7


line stmt bran cond sub pod time code
1             package App::MBUtiny::Collector::Client; # $Id: Client.pm 121 2019-07-01 19:51:50Z abalama $
2 3     3   64042 use strict;
  3         16  
  3         107  
3 3     3   572 use utf8;
  3         20  
  3         20  
4              
5             =encoding utf-8
6              
7             =head1 NAME
8              
9             App::MBUtiny::Collector::Client - Client for access to App::MBUtiny collector server
10              
11             =head1 VIRSION
12              
13             Version 1.00
14              
15             =head1 SYNOPSIS
16              
17             use App::MBUtiny::Collector::Client;
18              
19             my $client = new App::MBUtiny::Collector::Client(
20             url => 'http://test:test@localhost/mbutiny', # Base URL
21             timeout => 180, # default: 180
22             verbose => 1, # Show req/res data
23             );
24              
25             my $check_struct = $client->check;
26              
27             print STDERR $client->error unless $check_status;
28              
29             =head1 DESCRIPTION
30              
31             Client for access to App::MBUtiny collector server
32              
33             This module is based on L class
34              
35             =head2 new
36              
37             my $client = new App::MBUtiny::Collector::Client(
38             url => 'http://test:test@localhost/mbutiny', # Base URL
39             timeout => 180, # default: 180
40             verbose => 1, # Show req/res data
41             );
42              
43             Returns the collector client object
44              
45             =over 4
46              
47             =item B
48              
49             Timeout of requests
50              
51             Default: 180 sec
52              
53             =item B
54              
55             The Full URL of the collector location
56              
57             =item B
58              
59             Verbose flag. 0 = off, 1 = on
60              
61             Default: 0
62              
63             =back
64              
65             See L
66              
67             =head2 add
68              
69             $client->add(
70             type => 1,
71             name => "foo",
72             file => "foo-2019-06-25.tar.gz",
73             size => 123456,
74             md5 => "3a5fb8a1e0564eed5a6f5c4389ec5fa0",
75             sha1 => "22d12324fa2256e275761b55d5c063b8d9fc3b95",
76             status => 1,
77             error => "",
78             comment => "Test external fixup"
79             ) or die $client->error;
80              
81             Request for fixupping of backup on collector by name and others parameters.
82              
83             The method returns status of operation: 0 - Error; 1 - Ok
84              
85             =head2 check
86              
87             my $check = $client->check;
88              
89             Performs the checking of MBUtiny collector server and returns structure in format:
90              
91             {
92             'description' => 'Check collectors',
93             'dsn' => 'dbi:SQLite:dbname=/var/lib/mbutiny/mbutiny.db',
94             'error' => '',
95             'method' => 'GET',
96             'name' => 'check',
97             'path' => '/mbutiny',
98             'status' => 1,
99             'time' => '0.004'
100             }
101              
102             =head2 del
103              
104             $client->del(
105             type => 1,
106             name => "foo",
107             file => "foo-2019-06-25.tar.gz",
108             ) or die $client->error;
109              
110             Delete file-record from collector
111              
112             The method returns status of operation: 0 - Error; 1 - Ok
113              
114             =head2 get
115              
116             my %info = $client->get(
117             name => "foo",
118             file => "foo-2019-06-25.tar.gz",
119             );
120              
121             Request for getting information about file on collector by name and filename.
122              
123             The method returns info-structure. See L
124              
125             =head2 list
126              
127             my @list = $client->list(name => "foo");
128              
129             Request for getting list of files on collector by name.
130              
131             The method returns array of info-structures.
132             See L
133              
134             =head2 report
135              
136             my @list = $client->report(start => 123456789);
137              
138             Request for getting report of backup on collector by name.
139             See L
140              
141             =head2 request
142              
143             my $struct = $client->request();
144              
145             Performs request to collector server over L
146              
147             =head1 HISTORY
148              
149             See C file
150              
151             =head1 TO DO
152              
153             See C file
154              
155             =head1 BUGS
156              
157             * none noted
158              
159             =head1 SEE ALSO
160              
161             L, L
162              
163             =head1 AUTHOR
164              
165             Serż Minus (Sergey Lepenkov) L Eabalama@cpan.orgE
166              
167             =head1 COPYRIGHT
168              
169             Copyright (C) 1998-2019 D&D Corporation. All Rights Reserved
170              
171             =head1 LICENSE
172              
173             This program is free software; you can redistribute it and/or
174             modify it under the same terms as Perl itself.
175              
176             See C file and L
177              
178             =cut
179              
180 3     3   180 use vars qw/ $VERSION /;
  3         7  
  3         246  
181             $VERSION = '1.00';
182              
183             #use Carp;
184             #use CTK::TFVals qw/ :ALL /;
185 3     3   421 use CTK::ConfGenUtil;
  3         1067  
  3         282  
186             #use Try::Tiny;
187             #use File::Basename qw/basename/;
188              
189 3     3   30 use base qw/ WWW::MLite::Client /;
  3         6  
  3         1097  
190              
191             use constant {
192 3         2840 CONTENT_TYPE => "application/json",
193             SERIALIZE_FORMAT => 'json',
194             SR_ATTRS => {
195             json => [
196             { # For serialize
197             utf8 => 0,
198             pretty => 1,
199             allow_nonref => 1,
200             allow_blessed => 1,
201             },
202             { # For deserialize
203             utf8 => 0,
204             allow_nonref => 1,
205             allow_blessed => 1,
206             },
207             ],
208             },
209 3     3   329953 };
  3         7  
210              
211             sub new {
212 0     0 1   my $class = shift;
213 0           my %params = @_;
214 0   0       $params{sr_attrs} ||= SR_ATTRS;
215 0   0       $params{ua_opts} ||= { agent => "MBUtiny/$VERSION" };
216 0   0       $params{format} ||= SERIALIZE_FORMAT;
217 0   0       $params{content_type} ||= CONTENT_TYPE;
218 0   0       $params{no_check_redirect} //= 1;
219 0           return $class->SUPER::new(%params);
220             }
221             sub request {
222 0     0 1   my $self = shift;
223 0           my $data = $self->SUPER::request(@_);
224 0           my $state = $self->status;
225 0 0         if ($state) {
226 0           my $err = _check_response($data);
227 0 0         if ($err) {
228 0           $self->status(0);
229 0           $self->error($err);
230             }
231             }
232 0 0         return $data if is_hash($data);
233 0 0         if ($data) {
234 0           $self->status(0);
235 0           $self->error("Non serialized content found!");
236             }
237             return {
238 0           status => $self->status,
239             error => $self->error,
240             };
241             }
242             sub check {
243 0     0 1   my $self = shift;
244 0           return $self->request();
245             }
246             sub add {
247 0     0 1   my $self = shift;
248 0           my %args = @_;
249 0           $self->request(POST => undef, {%args});
250 0           return $self->status;
251             }
252             sub del {
253 0     0 1   my $self = shift;
254 0           my %args = @_;
255 0           my $base_path = $self->{uri}->path;
256 0           my $name = $args{name};
257 0 0         unless ($name) {
258 0           $self->error("The name attribute not specified!");
259 0           return $self->status(0);
260             }
261 0           my $file = $args{file};
262 0 0         unless ($file) {
263 0           $self->error("The file attribute not specified!");
264 0           return $self->status(0);
265             }
266 0   0       $self->request(DELETE => sprintf('%s/%s?file=%s&type=%d', $base_path, $name, $file, $args{type} || 0));
267 0           return $self->status;
268             }
269             sub list {
270 0     0 1   my $self = shift;
271 0           my $uri = $self->{uri}->clone;
272 0           my %args = @_;
273 0           my $name = $args{name};
274 0 0         unless ($name) {
275 0           $self->error("The name attribute not specified!");
276 0           return ();
277             }
278 0           my $path_orig = $uri->path;
279 0           $uri->path(sprintf("%s/list", $path_orig));
280 0           $uri->query_form(name => $name);
281 0   0       my $list = $self->request(GET => $uri->path_query) || {};
282 0           my $result = array($list, "list");
283 0           return @$result;
284             }
285             sub get {
286 0     0 1   my $self = shift;
287 0           my $uri = $self->{uri}->clone;
288 0           my %args = @_;
289 0           my $name = $args{name};
290 0 0         unless ($name) {
291 0           $self->error("The name attribute not specified!");
292 0           return ();
293             }
294 0           my $file = $args{file};
295 0           my $path_orig = $uri->path;
296 0           $uri->path(sprintf("%s/%s", $path_orig, $name));
297 0 0         $uri->query_form(file => $file) if $file;
298 0   0       my $info = $self->request(GET => $uri->path_query) || {};
299 0           my $result = hash($info, "info");
300 0           return %$result;
301             }
302             sub report {
303 0     0 1   my $self = shift;
304 0           my $uri = $self->{uri}->clone;
305 0           my %args = @_;
306 0           $uri->path(sprintf("%s/report", $uri->path));
307 0           my $start = $args{start};
308 0 0         $uri->query_form(start => $start) if $start;
309 0   0       my $list = $self->request(GET => $uri->path_query) || {};
310 0           my $result = array($list, "report");
311 0           return @$result;
312             }
313              
314             sub _check_response {
315             # Returns error string when status = 0 and error is not empty
316 0     0     my $res = shift;
317             # Returns:
318             # "..." - errors!
319             # undef - no errors
320 0 0         if ( !$res ) {
    0          
321 0           return;
322             } elsif (is_hash($res)) {
323 0 0         return if value($res => "status"); # OK
324 0 0         if (my $err = value($res => "error")) {
325 0           return $err;
326             }
327             } else {
328 0           return "The response has not valid JSON format";
329             }
330 0           return "Unknown error";
331             }
332              
333             1;
334              
335             __END__