File Coverage

blib/lib/Net/Hadoop/YARN/Roles/AppMasterHistoryServer.pm
Criterion Covered Total %
statement 17 58 29.3
branch 0 6 0.0
condition 0 13 0.0
subroutine 6 11 54.5
pod n/a
total 23 88 26.1


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