File Coverage

blib/lib/Net/Hadoop/YARN/Roles/AppMasterHistoryServer.pm
Criterion Covered Total %
statement 35 69 50.7
branch 0 6 0.0
condition 4 19 21.0
subroutine 8 13 61.5
pod n/a
total 47 107 43.9


line stmt bran cond sub pod time code
1             package Net::Hadoop::YARN::Roles::AppMasterHistoryServer;
2             $Net::Hadoop::YARN::Roles::AppMasterHistoryServer::VERSION = '0.203';
3 2     2   15050 use strict;
  2         5  
  2         56  
4 2     2   10 use warnings;
  2         3  
  2         39  
5 2     2   25 use 5.10.0;
  2         6  
6              
7 2     2   13 use Carp qw( croak );
  2         4  
  2         89  
8 2     2   696 use Hash::Path;
  2         626  
  2         70  
9 2     2   10 use Moo::Role;
  2         4  
  2         23  
10              
11             my %validation_pattern = (
12             appid => 'application_[0-9]+_[0-9]+',
13             jobid => 'job_[0-9]+_[0-9]+',
14             taskid => 'task_[0-9]+_[0-9]+_[a-z]_[0-9]+',
15             attemptid => 'attempt_[0-9]+_[0-9]+_[a-z]_[0-9]+_[0-9]+',
16             );
17              
18             my $RE_EXTRACT_VALIDS = sprintf '(?:%s)',
19             join '|',
20             map { $validation_pattern{$_} }
21             keys %validation_pattern;
22              
23             # used by consuming classes, for specific cases
24             sub _validate_id {
25 0     0   0 my $self = shift;
26 0         0 return $_[1] =~ /^$validation_pattern{$_[0]}$/;
27             }
28              
29             sub _extract_valid_params {
30             # TODO: this doesn't recognise container or attempt etc ids per above hash
31             #
32 0     0   0 my $self = shift;
33 0   0     0 my $str = shift || return;
34              
35 0         0 my @ids;
36 0         0 while ( my($type) = $str =~ /$RE_EXTRACT_VALIDS/gc ) {
37 0         0 push @ids, $type;
38             }
39              
40 0         0 return @ids;
41             }
42              
43             sub _mk_subs {
44 3     3   7 my $methods_urls = shift;
45 3   100     23 my $opt = shift || {};
46 3   100     16 my $pfix = $opt->{prefix} || '';
47              
48 3         5 for my $key ( keys %{$methods_urls} ) {
  3         13  
49              
50             # use a closure to only run the preprocessing once per method for
51             # validation. URL params are of the form {appid}, {taskid}, hence the
52             # regexes to find them
53 33         159 my @param_names = $methods_urls->{$key}[0] =~ m/\{([a-z]+)\}/g;
54             my @validations = map {
55 33         62 my $name = $_;
  62         95  
56             {
57             name => $name,
58             validate => sub {
59 0   0 0   0 my $val = shift || return;
60 0         0 $val =~ /^$validation_pattern{$name}$/
61             },
62 62         257 };
63             } @param_names;
64              
65 33         59 my $url = $methods_urls->{$key}[0];
66 33         45 my $json_path = $methods_urls->{$key}[1];
67              
68             my $new_method = sub {
69 0     0   0 my $self = shift;
70             # check the list of params validates against the list of
71             # placeholders gathered in the url split above
72 0         0 my $params_idx = 0;
73              
74 0         0 for my $param ( @_ ) {
75             my $v = $validations[ $params_idx ]
76 0   0     0 || do {
77             my $what = $key =~ m{ \A _ }xms
78             ? do {
79             if ( my $who = (caller 1)[3] ) {
80             my($short) = (split m{ [:]{2} }xms, $who)[-1];
81             sprintf qq{%s` via: `%s}, $short, $who;
82             }
83             else {
84             $key;
85             }
86             }
87             : $key
88             ;
89             croak sprintf "No validator for `%s` [%s]. Be sure that `%s` is a valid API endpoint for this object",
90             $param,
91             $params_idx,
92             $what,
93             ;
94             };
95              
96 0 0 0     0 if ( ! ref $param && ! $v->{validate}->( $param ) ) {
97             croak sprintf "Param `%s` doesn't satisfy pattern /%s/ in call to `%s`.",
98             $param || '',
99             $validation_pattern{ $v->{name} },
100 0   0     0 $key,
101             ;
102             }
103 0         0 $params_idx++;
104             }
105              
106             # now replace all url placeholders with the params we were given;
107             # extra parameters (in a hashref) will be passed as regular URL
108             # params, not interpolated in the path
109 0         0 my $interp_url = $url;
110 0         0 my $extra_params;
111 0         0 while (my $param = shift) {
112 0 0 0     0 if (! @_ && ref $param) {
113 0         0 $extra_params = $param;
114 0         0 last;
115             }
116 0         0 $interp_url =~ s/\{[a-z]+\}/$param/;
117             }
118 0         0 my $res = $self->_get($interp_url, { params => $extra_params });
119              
120             # Only return the JSON fragment we need
121 0         0 return Hash::Path->get($res, split(/\./, $json_path));
122 33         151 };
123             {
124             # limit the scope of non-strict-ness
125             # insert the method for the endpoint in the using class
126 2     2   1653 no strict 'refs';
  2         4  
  2         342  
  33         50  
127 33         41 *{ ( caller() )[0] . '::' . $pfix . $key } = $new_method;
  33         198  
128             }
129             }
130             }
131              
132             sub _mk_uri {
133 0     0     my $self = shift;
134 0           my ($server, $path, $params) = @_;
135 0           my $uri = $server . "/" . $path;
136 0           $uri =~ s#//+#/#g;
137 0           $uri = URI->new("http://" . $uri);
138 0 0         if ($params) {
139 0           $uri->query_form($params);
140             }
141 0           return $uri;
142             }
143              
144             1;
145              
146             __END__