diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm new file mode 100644 index 0000000000..01c7c5f991 --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceProfiles.pm @@ -0,0 +1,138 @@ +package NGCP::Panel::Controller::API::PbxDeviceProfiles; +use Sipwise::Base; +use namespace::sweep; +use boolean qw(true); +use Data::HAL qw(); +use Data::HAL::Link qw(); +use HTTP::Headers qw(); +use HTTP::Status qw(:constants); +use MooseX::ClassAttribute qw(class_has); +use NGCP::Panel::Utils::DateTime; +BEGIN { extends 'Catalyst::Controller::ActionRole'; } +require Catalyst::ActionRole::ACL; +require Catalyst::ActionRole::CheckTrailingSlash; +require Catalyst::ActionRole::HTTPMethods; +require Catalyst::ActionRole::RequireSSL; + +class_has 'api_description' => ( + is => 'ro', + isa => 'Str', + default => + 'TODO', +); + +class_has 'query_params' => ( + is => 'ro', + isa => 'ArrayRef', + default => sub {[ + ]}, +); + + +with 'NGCP::Panel::Role::API::PbxDeviceProfiles'; + +class_has('resource_name', is => 'ro', default => 'pbxdeviceprofiles'); +class_has('dispatch_path', is => 'ro', default => '/api/pbxdeviceprofiles/'); +class_has('relation', is => 'ro', default => 'http://purl.org/sipwise/ngcp-api/#rel-pbxdeviceprofiles'); + +__PACKAGE__->config( + action => { + map { $_ => { + ACLDetachTo => '/api/root/invalid_user', + AllowedRole => [qw/admin reseller/], + Args => 0, + Does => [qw(ACL CheckTrailingSlash RequireSSL)], + Method => $_, + Path => __PACKAGE__->dispatch_path, + } } @{ __PACKAGE__->allowed_methods }, + }, + action_roles => [qw(HTTPMethods)], +); + +sub auto :Private { + my ($self, $c) = @_; + + $self->set_body($c); + $self->log_request($c); + return 1; +} + +sub GET :Allow { + my ($self, $c) = @_; + my $page = $c->request->params->{page} // 1; + my $rows = $c->request->params->{rows} // 10; + { + my $field_devs = $self->item_rs($c); + + my $total_count = int($field_devs->count); + $field_devs = $field_devs->search(undef, { + page => $page, + rows => $rows, + }); + my (@embedded, @links); + for my $dev ($field_devs->search({}, {order_by => {-asc => 'me.id'}})->all) { + push @embedded, $self->hal_from_item($c, $dev); + push @links, Data::HAL::Link->new( + relation => 'ngcp:'.$self->resource_name, + href => sprintf('%s%d', $self->dispatch_path, $dev->id), + ); + } + push @links, + Data::HAL::Link->new( + relation => 'curies', + href => 'http://purl.org/sipwise/ngcp-api/#rel-{rel}', + name => 'ngcp', + templated => true, + ), + Data::HAL::Link->new(relation => 'profile', href => 'http://purl.org/sipwise/ngcp-api/'), + Data::HAL::Link->new(relation => 'self', href => sprintf('%s?page=%s&rows=%s', $self->dispatch_path, $page, $rows)); + if(($total_count / $rows) > $page ) { + push @links, Data::HAL::Link->new(relation => 'next', href => sprintf('%s?page=%d&rows=%d', $self->dispatch_path, $page + 1, $rows)); + } + if($page > 1) { + push @links, Data::HAL::Link->new(relation => 'prev', href => sprintf('%s?page=%d&rows=%d', $self->dispatch_path, $page - 1, $rows)); + } + + my $hal = Data::HAL->new( + embedded => [@embedded], + links => [@links], + ); + $hal->resource({ + total_count => $total_count, + }); + my $response = HTTP::Response->new(HTTP_OK, undef, + HTTP::Headers->new($hal->http_headers(skip_links => 1)), $hal->as_json); + $c->response->headers($response->headers); + $c->response->body($response->content); + return; + } + return; +} + +sub HEAD :Allow { + my ($self, $c) = @_; + $c->forward(qw(GET)); + $c->response->body(q()); + return; +} + +sub OPTIONS :Allow { + my ($self, $c) = @_; + my $allowed_methods = $self->allowed_methods; + $c->response->headers(HTTP::Headers->new( + Allow => $allowed_methods->join(', '), + Accept_Post => 'application/hal+json; profile=http://purl.org/sipwise/ngcp-api/#rel-'.$self->resource_name, + )); + $c->response->content_type('application/json'); + $c->response->body(JSON::to_json({ methods => $allowed_methods })."\n"); + return; +} + +sub end : Private { + my ($self, $c) = @_; + + $self->log_response($c); + return 1; +} + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm new file mode 100644 index 0000000000..00fa76ca4a --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/PbxDeviceProfilesItem.pm @@ -0,0 +1,95 @@ +package NGCP::Panel::Controller::API::PbxDeviceProfilesItem; +use Sipwise::Base; +use namespace::sweep; +use boolean qw(true); +use Data::HAL qw(); +use Data::HAL::Link qw(); +use HTTP::Headers qw(); +use HTTP::Status qw(:constants); +use MooseX::ClassAttribute qw(class_has); +use NGCP::Panel::Utils::ValidateJSON qw(); +use NGCP::Panel::Utils::DateTime; +use Path::Tiny qw(path); +use Safe::Isa qw($_isa); +BEGIN { extends 'Catalyst::Controller::ActionRole'; } +require Catalyst::ActionRole::ACL; +require Catalyst::ActionRole::HTTPMethods; +require Catalyst::ActionRole::RequireSSL; + +with 'NGCP::Panel::Role::API::PbxDeviceProfiles'; + +class_has('resource_name', is => 'ro', default => 'pbxdeviceprofiles'); +class_has('dispatch_path', is => 'ro', default => '/api/pbxdeviceprofiles/'); +class_has('relation', is => 'ro', default => 'http://purl.org/sipwise/ngcp-api/#rel-pbxdeviceprofiles'); + +__PACKAGE__->config( + action => { + map { $_ => { + ACLDetachTo => '/api/root/invalid_user', + AllowedRole => [qw/admin reseller/], + Args => 1, + Does => [qw(ACL RequireSSL)], + Method => $_, + Path => __PACKAGE__->dispatch_path, + } } @{ __PACKAGE__->allowed_methods }, + }, + action_roles => [qw(HTTPMethods)], +); + +sub auto :Private { + my ($self, $c) = @_; + + $self->set_body($c); + $self->log_request($c); + return 1; +} + +sub GET :Allow { + my ($self, $c, $id) = @_; + { + last unless $self->valid_id($c, $id); + my $field_dev = $self->item_by_id($c, $id); + last unless $self->resource_exists($c, deviceprofile => $field_dev); + + my $hal = $self->hal_from_item($c, $field_dev); + + my $response = HTTP::Response->new(HTTP_OK, undef, HTTP::Headers->new( + (map { # XXX Data::HAL must be able to generate links with multiple relations + s|rel="(http://purl.org/sipwise/ngcp-api/#rel-resellers)"|rel="item $1"|r + =~ s/rel=self/rel="item self"/r; + } $hal->http_headers), + ), $hal->as_json); + $c->response->headers($response->headers); + $c->response->body($response->content); + return; + } + return; +} + +sub HEAD :Allow { + my ($self, $c, $id) = @_; + $c->forward(qw(GET)); + $c->response->body(q()); + return; +} + +sub OPTIONS :Allow { + my ($self, $c, $id) = @_; + my $allowed_methods = $self->allowed_methods; + $c->response->headers(HTTP::Headers->new( + Allow => $allowed_methods->join(', '), + Accept_Patch => 'application/json-patch+json', + )); + $c->response->content_type('application/json'); + $c->response->body(JSON::to_json({ methods => $allowed_methods })."\n"); + return; +} + +sub end : Private { + my ($self, $c) = @_; + + $self->log_response($c); + return 1; +} + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Role/API/PbxDeviceProfiles.pm b/lib/NGCP/Panel/Role/API/PbxDeviceProfiles.pm new file mode 100644 index 0000000000..8326f110cd --- /dev/null +++ b/lib/NGCP/Panel/Role/API/PbxDeviceProfiles.pm @@ -0,0 +1,82 @@ +package NGCP::Panel::Role::API::PbxDeviceProfiles; +use Moose::Role; +use Sipwise::Base; +with 'NGCP::Panel::Role::API' => { + -alias =>{ item_rs => '_item_rs', }, + -excludes => [ 'item_rs' ], +}; + +use boolean qw(true); +use TryCatch; +use Data::HAL qw(); +use Data::HAL::Link qw(); +use HTTP::Status qw(:constants); +use JSON::Types; +use NGCP::Panel::Form::Device::Profile; + +sub get_form { + my ($self, $c) = @_; + return NGCP::Panel::Form::Device::Profile->new; +} + +sub hal_from_item { + my ($self, $c, $item) = @_; + my $form; + my $type = 'pbxdeviceprofiles'; + + my $hal = Data::HAL->new( + links => [ + Data::HAL::Link->new( + relation => 'curies', + href => 'http://purl.org/sipwise/ngcp-api/#rel-{rel}', + name => 'ngcp', + templated => true, + ), + Data::HAL::Link->new(relation => 'collection', href => sprintf("%s", $self->dispatch_path)), + Data::HAL::Link->new(relation => 'profile', href => 'http://purl.org/sipwise/ngcp-api/'), + Data::HAL::Link->new(relation => 'self', href => sprintf("%s%d", $self->dispatch_path, $item->id)), + Data::HAL::Link->new(relation => "ngcp:$type", href => sprintf("/api/%s/%d", $type, $item->id)), + Data::HAL::Link->new(relation => 'ngcp:pbxdeviceconfigs', href => sprintf("/api/pbxdeviceconfigs/%d", $item->config_id)), + ], + relation => 'ngcp:'.$self->resource_name, + ); + + my $resource = $self->resource_from_item($c, $item); + $hal->resource($resource); + return $hal; +} + +sub resource_from_item { + my ($self, $c, $item) = @_; + + my %resource = $item->get_inflated_columns; + delete $resource{config_id}; + + my $form = $self->get_form($c); +# return unless $self->validate_form( +# c => $c, +# form => $form, +# resource => \%resource, +# run => 0, +# ); + $resource{id} += 0; + + return \%resource; +} + +sub item_rs { + my ($self, $c) = @_; + my $item_rs = $c->model('DB')->resultset('autoprov_profiles'); + + return $item_rs; +} + +sub item_by_id { + my ($self, $c, $id) = @_; + + my $item_rs = $self->item_rs($c); + return $item_rs->find($id); +} + +1; +# vim: set tabstop=4 expandtab: diff --git a/t/api-root.t b/t/api-root.t index a7d22581f2..4e09dce385 100644 --- a/t/api-root.t +++ b/t/api-root.t @@ -66,6 +66,8 @@ $ua->ssl_opts( cfdestinationsets => 1, cftimesets => 1, cfmappings => 1, + pbxdevices => 1, + pbxdeviceprofiles => 1, }; foreach my $link(@links) { my $rex = qr/^<\/api\/[a-z]+\/>; rel=\"collection http:\/\/purl\.org\/sipwise\/ngcp-api\/#rel-([a-z]+s)\"$/;