App-EventStreamr/lib/App/EventStreamr/Roles/ConfigAPI.pm
package App::EventStreamr::Roles::ConfigAPI;
use v5.010;
use strict;
use warnings;
use Config::JSON;
use JSON;
use Method::Signatures 20140224; # libmethod-signatures-perl
use HTTP::Tiny '0.053'; # libhttp-tiny-perl
use Proc::ProcessTable; # libproc-processtable-perl
use Moo::Role; # libmoo-perl
# ABSTRACT: A config api
our $VERSION = '0.5'; # VERSION: Generated by DZP::OurPkg:Version
requires 'write_config','localconfig','config_path','macaddress','devices';
has 'controller_config' => ( is => 'ro', lazy => 1, builder => 1 );
has 'controller' => ( is => 'rw', lazy => 1, builder => 1 );
has 'remote_config' => ( is => 'rw', lazy => 1, builder => 1 );
has 'http' => ( is => 'rw', lazy => 1, builder => 1, handles => [ qw( post get ) ] );
has 'api_url' => ( is => 'ro', default => sub { "http://127.0.0.1:3000/internal/settings" } );
method _build_http() {
return HTTP::Tiny->new(timeout => 15);
}
method _build_controller_config() {
return $self->config_path."/controller.json";
}
method _build_controller() {
if ( -e $self->controller_config ) {
return Config::JSON->new($self->controller_config)->config->{controller};
} else {
return 0;
}
}
method _build_remote_config() {
# We're designed to operate without a controller.
return 0 if (! $self->controller);
$self->info("Registering with controller ".$self->controller."/api/station/".$self->macaddress);
my $response = $self->http->post($self->controller."/api/station/".$self->macaddress);
# Controller responds with created 201, post our config.
# This occurs when our identifier isn't registered in the
# Frontend.
if ($response->{status} == 201) {
# Status Post Data
my $json = to_json($self->_post_data());
$self->debug($json);
my %post_data = (
content => $json,
headers => {
'station-mgr' => 1,
'Content-Type' => 'application/json',
}
);
$response = $self->http->post($self->controller."/api/station", \%post_data);
}
# We get a 200 if exist and are already registered. Previous
# if block takes care of requesting config after registering.
if ($response->{status} == 200 ) {
$self->debug({filter => \&Data::Dumper::Dumper,
value => $response}) if ($self->is_debug());
if (defined $response->{content} && $response->{content} ne 'true') {
my $content = from_json($response->{content});
return $content->{settings};
}
return 0;
} else {
return 0;
}
}
# Although this works, it's rather horrible. We really should
# use the accessors properly and we wouldn't have to ignore
# them and do this (I'll however settle for working first up).
after '_load_config' => sub {
my $self = shift;
if ( $self->remote_config ) {
# Eww code duplication of _load_config. Same applies.
foreach my $key (keys %{$self->{remote_config}}) {
$self->{$key} = $self->{remote_config}{$key};
}
$self->write_config();
} else {
$self->post_config();
}
};
after 'write_config' => sub {
my $self = shift;
$self->post_config();
};
method post_config() {
$self->update_devices();
# Post config to manager api
my $json = to_json($self->_post_data());
my %post_data = (
content => $json,
'content-type' => 'application/json',
'content-length' => length($json),
);
my $post = $self->http->post(
$self->api_url,
\%post_data,
);
if ( $self->remote_config ) {
# Post devices to controller.
$self->info("posting devices to controller");
my $data;
$data->{key} = "devices";
@{$data->{value}} = @{$self->{available_devices}{array}};
# I don't think this is needed!
#$json = to_json($data);
## FROM ORIGINAL CODE:
## some bug and it's late this could cause hideous issues if
## a device id has a / in it, but this should be unlikely
#$json =~ s{/|\.}{}g;
%post_data = (
content => to_json($data),
headers => {
'station-mgr' => 1,
'Content-Type' => 'application/json',
}
);
$post = $self->http->post(
$self->controller."/api/station/".$self->macaddress."/partial",
\%post_data,
);
$self->debug({filter => \&Data::Dumper::Dumper,
value => $post}) if ($self->is_debug());
}
}
method get_config() {
$self->info("Retrieving config from manager API");
my $get = $self->http->get($self->api_url);
my $content = from_json($get->{content});
$self->debug({filter => \&Data::Dumper::Dumper,
value => $get}) if ($self->is_debug());
# Eww code duplication of _load_config. Same appliest.
foreach my $key (keys %{$content->{config}}) {
$self->{$key} = $content->{config}{$key};
}
$self->write_config();
}
1;
__END__
=pod
=encoding UTF-8
=head1 NAME
App::EventStreamr::Roles::ConfigAPI - A config api
=head1 VERSION
version 0.5
=head1 SYNOPSIS
This is a role wraps around the 'run_stop' of a process.
=head1 DESCRIPTION
This is a Role that can be consumed to post config to the internal
and controller APIs.
It requires a methods from the config package, so really should only
be consumed by L<App::EventStreamr::Config>.
=head1 AUTHOR
Leon Wright < techman@cpan.org >
=head1 COPYRIGHT AND LICENSE
This software is Copyright (c) 2014 by Leon Wright.
This is free software, licensed under:
The GNU Affero General Public License, Version 3, November 2007
=cut