File Coverage

blib/lib/App/EventStreamr/Roles/ConfigAPI.pm
Criterion Covered Total %
statement 85 87 97.7
branch 18 30 60.0
condition 1 3 33.3
subroutine 21 21 100.0
pod n/a
total 125 141 88.6


line stmt bran cond sub pod time code
1             package App::EventStreamr::Roles::ConfigAPI;
2              
3 8     8   4099 use v5.010;
  8         19  
  8         282  
4 8     8   77 use strict;
  8         15  
  8         187  
5 8     8   24 use warnings;
  8         9  
  8         159  
6 8     8   25 use Config::JSON;
  8         4  
  8         114  
7 8     8   24 use JSON;
  8         7  
  8         42  
8 8     8   952 use Method::Signatures 20140224; # libmethod-signatures-perl
  8         127  
  8         35  
9 8     8   6572 use HTTP::Tiny '0.053'; # libhttp-tiny-perl
  8         212199  
  8         263  
10 8     8   2986 use Proc::ProcessTable; # libproc-processtable-perl
  8         34898  
  8         351  
11              
12 8     8   41 use Moo::Role; # libmoo-perl
  8         14  
  8         65  
13              
14             # ABSTRACT: A config api
15              
16             our $VERSION = '0.3'; # VERSION: Generated by DZP::OurPkg:Version
17              
18              
19             requires 'write_config','localconfig','config_path','macaddress','devices';
20              
21             has 'controller_config' => ( is => 'ro', lazy => 1, builder => 1 );
22             has 'controller' => ( is => 'rw', lazy => 1, builder => 1 );
23             has 'remote_config' => ( is => 'rw', lazy => 1, builder => 1 );
24             has 'http' => ( is => 'rw', lazy => 1, builder => 1, handles => [ qw( post get ) ] );
25             has 'api_url' => ( is => 'ro', default => sub { "http://127.0.0.1:3000/internal/settings" } );
26              
27              
28 8 50   8   7290 method _build_http() {
  10     10   2882  
  10         44  
29 10         169 return HTTP::Tiny->new(timeout => 15);
30             }
31              
32 8 50   8   3455 method _build_controller_config() {
  14     14   2149  
  14         49  
33 14         281 return $self->config_path."/controller.json";
34             }
35              
36 8 50   8   3375 method _build_controller() {
  14     14   2101  
  14         47  
37 14 100       46 if ( -e $self->controller_config ) {
38 2         15 return Config::JSON->new($self->controller_config)->config->{controller};
39             } else {
40 12         82 return 0;
41             }
42             }
43              
44 8 50   8   3572 method _build_remote_config() {
  14     14   2189  
  14         49  
45             # We're designed to operate without a controller.
46 14 100       52 return 0 if (! $self->controller);
47            
48 2         750 $self->info("Registering with controller ".$self->controller."/api/station/".$self->macaddress);
49 2         12 my $response = $self->http->post($self->controller."/api/station/".$self->macaddress);
50              
51             # Controller responds with created 201, post our config.
52             # This occurs when our identifier isn't registered in the
53             # Frontend.
54 2 50       17473 if ($response->{status} == 201) {
55             # Status Post Data
56 2         17 my $json = to_json($self->_post_data());
57 2         127 $self->debug($json);
58            
59 2         13 my %post_data = (
60             content => $json,
61             headers => {
62             'station-mgr' => 1,
63             'Content-Type' => 'application/json',
64             }
65             );
66            
67 2         10 $response = $self->http->post($self->controller."/api/station", \%post_data);
68             }
69              
70             # We get a 200 if exist and are already registered. Previous
71             # if block takes care of requesting config after registering.
72 2 50       8179 if ($response->{status} == 200 ) {
73 2 50       90 $self->debug({filter => \&Data::Dumper::Dumper,
74             value => $response}) if ($self->is_debug());
75              
76 2 50 33     19 if (defined $response->{content} && $response->{content} ne 'true') {
77 2         11 my $content = from_json($response->{content});
78 2         65 return $content->{settings};
79             }
80 0         0 return 0;
81             } else {
82 0         0 return 0;
83             }
84             }
85              
86             # Although this works, it's rather horrible. We really should
87             # use the accessors properly and we wouldn't have to ignore
88             # them and do this (I'll however settle for working first up).
89             after '_load_config' => sub {
90             my $self = shift;
91            
92             if ( $self->remote_config ) {
93             # Eww code duplication of _load_config. Same applies.
94             foreach my $key (keys %{$self->{remote_config}}) {
95             $self->{$key} = $self->{remote_config}{$key};
96             }
97             $self->write_config();
98             } else {
99             $self->post_config();
100             }
101             };
102              
103             after 'write_config' => sub {
104             my $self = shift;
105             $self->post_config();
106             };
107              
108 8 50   8   5105 method post_config() {
  25     25   32  
  25         67  
109 25         87 $self->update_devices();
110              
111             # Post config to manager api
112 25         104 my $json = to_json($self->_post_data());
113 21         946 my %post_data = (
114             content => $json,
115             'content-type' => 'application/json',
116             'content-length' => length($json),
117             );
118 21         115 my $post = $self->http->post(
119             $self->api_url,
120             \%post_data,
121             );
122            
123 21 100       41663 if ( $self->remote_config ) {
124             # Post devices to controller.
125 10         495 $self->info("posting devices to controller");
126 10         10 my $data;
127 10         26 $data->{key} = "devices";
128 10         21 @{$data->{value}} = @{$self->{available_devices}{array}};
  10         27  
  10         22  
129              
130             # I don't think this is needed!
131             #$json = to_json($data);
132             ## FROM ORIGINAL CODE:
133             ## some bug and it's late this could cause hideous issues if
134             ## a device id has a / in it, but this should be unlikely
135             #$json =~ s{/|\.}{}g;
136            
137 10         32 %post_data = (
138             content => to_json($data),
139             headers => {
140             'station-mgr' => 1,
141             'Content-Type' => 'application/json',
142             }
143             );
144              
145 10         215 $post = $self->http->post(
146             $self->controller."/api/station/".$self->macaddress."/partial",
147             \%post_data,
148             );
149            
150 10 50       32199 $self->debug({filter => \&Data::Dumper::Dumper,
151             value => $post}) if ($self->is_debug());
152             }
153             }
154              
155 8 50   8   4271 method get_config() {
  1     1   56  
  1         4  
156 1         17 $self->info("Retrieving config from manager API");
157 1         4 my $get = $self->http->get($self->api_url);
158 1         2132 my $content = from_json($get->{content});
159            
160 1 50       43 $self->debug({filter => \&Data::Dumper::Dumper,
161             value => $get}) if ($self->is_debug());
162              
163              
164             # Eww code duplication of _load_config. Same appliest.
165 1         1 foreach my $key (keys %{$content->{config}}) {
  1         4  
166 4         7 $self->{$key} = $content->{config}{$key};
167             }
168 1         20 $self->write_config();
169             }
170              
171             1;
172              
173             __END__
174              
175             =pod
176              
177             =encoding UTF-8
178              
179             =head1 NAME
180              
181             App::EventStreamr::Roles::ConfigAPI - A config api
182              
183             =head1 VERSION
184              
185             version 0.3
186              
187             =head1 SYNOPSIS
188              
189             This is a role wraps around the 'run_stop' of a process.
190              
191             =head1 DESCRIPTION
192              
193             This is a Role that can be consumed to post config to the internal
194             and controller APIs.
195              
196             It requires a methods from the config package, so really should only
197             be consumed by L<App::EventStreamr::Config>.
198              
199             =head1 AUTHOR
200              
201             Leon Wright < techman@cpan.org >
202              
203             =head1 COPYRIGHT AND LICENSE
204              
205             This software is Copyright (c) 2014 by Leon Wright.
206              
207             This is free software, licensed under:
208              
209             The GNU Affero General Public License, Version 3, November 2007
210              
211             =cut