diff --git a/lib/NGCP/Panel/Controller/API/RtcSessions.pm b/lib/NGCP/Panel/Controller/API/RtcSessions.pm new file mode 100644 index 0000000000..01d7e4e990 --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/RtcSessions.pm @@ -0,0 +1,195 @@ +package NGCP::Panel::Controller::API::RtcSessions; +use NGCP::Panel::Utils::Generic qw(:all); + +use boolean qw(true); +use Data::HAL qw(); +use Data::HAL::Link qw(); +use HTTP::Headers qw(); +use HTTP::Status qw(:constants); + +require Catalyst::ActionRole::ACL; +require Catalyst::ActionRole::CheckTrailingSlash; +require Catalyst::ActionRole::HTTPMethods; +require Catalyst::ActionRole::RequireSSL; + + +sub api_description { + return 'Show a collection of RTC sessions, belonging to a specific subscriber.'; +} + +sub allowed_methods{ + return [qw/GET POST OPTIONS HEAD/]; +} + +sub query_params { + return []; +} + +use base qw/Catalyst::Controller NGCP::Panel::Role::API::RtcSessions/; + +sub resource_name{ + return 'rtcsessions'; +} +sub dispatch_path{ + return '/api/rtcsessions/'; +} +sub relation{ + return 'http://purl.org/sipwise/ngcp-api/#rel-rtcsessions'; +} + +__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 $subscribers = $self->item_rs($c); + (my $total_count, $subscribers) = $self->paginate_order_collection($c, $subscribers); + my (@embedded, @links); + for my $subscriber ($subscribers->all) { + my $hal = $self->hal_from_item($c, $subscriber); + next unless $hal; + push @embedded, $hal; + push @links, Data::HAL::Link->new( + relation => 'ngcp:'.$self->resource_name, + href => sprintf('%s%d', $self->dispatch_path, $subscriber->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', $c->request->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_filtered($c); + $c->response->headers(HTTP::Headers->new( + Allow => join(', ', @{ $allowed_methods }), + 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 POST :Allow { + my ($self, $c) = @_; + + my $guard = $c->model('DB')->txn_scope_guard; + { + my $schema = $c->model('DB'); + my $resource = $self->get_valid_post_data( + c => $c, + media_type => 'application/json', + ); + last unless $resource; + + if($c->user->roles eq "admin") { + } elsif($c->user->roles eq "reseller") { + $resource->{reseller_id} = $c->user->reseller_id; # TODO: ? + } else { + $resource->{subscriber_id} = $c->user->id; + } + + my $subscriber_item = $c->model('DB')->resultset('voip_subscribers')->search_rs({ + id => $resource->{subscriber_id}, + })->first; + + unless ($subscriber_item) { + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, "Subscriber invalid or not found."); + last; + } + + # my $form = $self->get_form(); + # $resource->{reseller_id} //= undef; + # last unless $self->validate_form( + # c => $c, + # resource => $resource, + # form => $form, + # ); + + my $session_item = NGCP::Panel::Utils::Rtc::create_rtc_session( + config => $c->config, + subscriber_item => $subscriber_item, + resource => $resource, + err_code => sub { + my ($err) = @_; + $self->error($c, HTTP_UNPROCESSABLE_ENTITY, $err); + }); + last unless $session_item; + + $guard->commit; + + $c->response->status(HTTP_CREATED); + $c->response->header(Location => sprintf('%s%d', $self->dispatch_path, $session_item->id)); + $c->response->body(q()); + } + return; +} + +sub end : Private { + my ($self, $c) = @_; + + $self->log_response($c); + return 1; +} + +no Moose; +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/RtcSessionsItem.pm b/lib/NGCP/Panel/Controller/API/RtcSessionsItem.pm new file mode 100644 index 0000000000..aff8a02c03 --- /dev/null +++ b/lib/NGCP/Panel/Controller/API/RtcSessionsItem.pm @@ -0,0 +1,122 @@ +package NGCP::Panel::Controller::API::RtcSessionsItem; +use NGCP::Panel::Utils::Generic qw(:all); + +use Data::HAL qw(); +use Data::HAL::Link qw(); +use HTTP::Headers qw(); +use HTTP::Status qw(:constants); + +require Catalyst::ActionRole::ACL; +require Catalyst::ActionRole::HTTPMethods; +require Catalyst::ActionRole::RequireSSL; + +use base qw/Catalyst::Controller NGCP::Panel::Role::API::RtcSessions/; + +sub resource_name{ + return 'rtcsessions'; +} +sub dispatch_path{ + return '/api/rtcsessions/'; +} +sub relation{ + return 'http://purl.org/sipwise/ngcp-api/#rel-rtcsessions'; +} + +sub allowed_methods{ + return [qw/GET OPTIONS HEAD/]; +} + +sub journal_query_params { + my($self,$query_params) = @_; + return $self->get_journal_query_params($query_params); +} + +sub get_journal_methods{ + return [qw/handle_item_base_journal handle_journals_get handle_journalsitem_get handle_journals_options handle_journalsitem_options handle_journals_head handle_journalsitem_head/]; +} + +__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 }), + @{ __PACKAGE__->get_journal_action_config(__PACKAGE__->resource_name,{ + ACLDetachTo => '/api/root/invalid_user', + AllowedRole => [qw/admin reseller/], + Does => [qw(ACL RequireSSL)], + }) }, + }, + 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 $item = $self->item_by_id($c, $id); + last unless $self->resource_exists($c, rtc_session => $item); + + my $hal = $self->hal_from_item($c, $item); + + unless ($hal) { + $c->log->error("Session not found. It may have expired."); + $self->error($c, HTTP_NOT_FOUND, "Session not found. It may have expired."); + last; + } + + 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_filtered($c); + $c->response->headers(HTTP::Headers->new( + Allow => join(', ', @{ $allowed_methods }), + 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; +} + +no Moose; +1; + +# vim: set tabstop=4 expandtab: diff --git a/lib/NGCP/Panel/Controller/API/Subscribers.pm b/lib/NGCP/Panel/Controller/API/Subscribers.pm index 19eb14eebb..75453fbf34 100644 --- a/lib/NGCP/Panel/Controller/API/Subscribers.pm +++ b/lib/NGCP/Panel/Controller/API/Subscribers.pm @@ -252,22 +252,22 @@ sub GET :Allow { my $rows = $c->request->params->{rows} // 10; my $schema = $c->model('DB'); $schema->set_transaction_isolation('READ COMMITTED'); - my $guard = $schema->txn_scope_guard; + my $guard = $schema->txn_scope_guard; { my $subscribers_rs = $self->item_rs($c); (my $total_count, $subscribers_rs) = $self->paginate_order_collection($c, $subscribers_rs); my $subscribers = NGCP::Panel::Utils::ProfilePackages::lock_contracts(c => $c, rs => $subscribers_rs, - contract_id_field => 'contract_id'); - my $now = NGCP::Panel::Utils::DateTime::current_local; + contract_id_field => 'contract_id'); + my $now = NGCP::Panel::Utils::DateTime::current_local; my (@embedded, @links, %contract_map); my $form = $self->get_form($c); for my $subscriber (@$subscribers) { my $contract = $subscriber->contract; - my $balance = NGCP::Panel::Utils::ProfilePackages::get_contract_balance(c => $c, + NGCP::Panel::Utils::ProfilePackages::get_contract_balance(c => $c, contract => $contract, now => $now) if !exists $contract_map{$contract->id}; #apply underrun lock level - $contract_map{$contract->id} = 1; + $contract_map{$contract->id} = 1; my $resource = $self->resource_from_item($c, $subscriber, $form); push @embedded, $self->hal_from_item($c, $subscriber, $resource, $form); push @links, Data::HAL::Link->new( diff --git a/lib/NGCP/Panel/Role/API/RtcSessions.pm b/lib/NGCP/Panel/Role/API/RtcSessions.pm new file mode 100644 index 0000000000..0cc3e99f18 --- /dev/null +++ b/lib/NGCP/Panel/Role/API/RtcSessions.pm @@ -0,0 +1,91 @@ +package NGCP::Panel::Role::API::RtcSessions; +use NGCP::Panel::Utils::Generic qw(:all); + +use base 'NGCP::Panel::Role::API'; + +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::Utils::Subscriber; +use NGCP::Panel::Utils::Rtc; + +sub get_form { + my ($self) = @_; + + #return NGCP::Panel::Form::Rtc::NetworksAdmin->new; + return; +} + +sub hal_from_item { + my ($self, $c, $item) = @_; + + my $resource = { + subscriber_id => $item->subscriber->voip_subscriber->id, # this may be confusing but we store the provisioning-subscriber-id but show the billing one + rtc_network_tag => $item->rtc_network_tag, + }; + + my $rtc_session = NGCP::Panel::Utils::Rtc::get_rtc_session( + config => $c->config, + item => $item, + err_code => sub { + $c->log->warn(shift); return; + }); + if ($rtc_session) { + $resource->{rtc_browser_token} = $rtc_session->{data}{token}; + } else { + # here either delete our DB entry, or recreate it accordingly + $item->delete; + return; + } + + 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("/api/%s/", $self->resource_name)), + 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:subscribers', href => sprintf("/api/subscribers/%d", $item->subscriber->voip_subscriber->id)), + $self->get_journal_relation_link($item->id), + ], + relation => 'ngcp:'.$self->resource_name, + ); + + $hal->resource($resource); + return $hal; +} + +sub item_rs { + my ($self, $c) = @_; + + my $item_rs; + $item_rs = $c->model('DB')->resultset('rtc_session'); + if($c->user->roles eq "admin") { + } elsif($c->user->roles eq "reseller") { + $item_rs = $item_rs->search({ + 'contact.reseller_id' => $c->user->reseller_id, + },{ + join => {subscriber => { voip_subscriber => { contract => 'contact' }}}, + }); + } + + 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/lib/NGCP/Panel/Utils/ComxAPIClient.pm b/lib/NGCP/Panel/Utils/ComxAPIClient.pm index aabd122fb2..ccb0a870fb 100644 --- a/lib/NGCP/Panel/Utils/ComxAPIClient.pm +++ b/lib/NGCP/Panel/Utils/ComxAPIClient.pm @@ -38,7 +38,7 @@ sub login { } sub create_session_and_account { - my ($self, $appid, $network, $identifier, $accessToken, $owner) = @_; + my ($self, $appid, $network, $identifier, $accessToken, $owner, $account_config) = @_; my $ua = $self->ua; my $session_content = encode_json({ app => $appid, @@ -53,6 +53,7 @@ sub create_session_and_account { identifier => $identifier, accessToken => $accessToken, owner => $owner, + $account_config ? (config => encode_json($account_config)) : (), }); #p $account_content; my $account = $self->_create_response( @@ -62,6 +63,19 @@ sub create_session_and_account { return $account; } +sub create_session { + my ($self, $appid, $owner) = @_; + my $ua = $self->ua; + my $session_content = encode_json({ + app => $appid, + owner => $owner, + }); + my $session = $self->_create_response( + $ua->post($self->host . '/sessions', 'Content-Type' => 'application/json', Content => $session_content), + ); + return $session; +} + sub create_network { my ($self, $tag, $connector, $config, $owner) = @_; my $ua = $self->ua; @@ -169,6 +183,12 @@ sub get_users { return $users; } +sub get_apps_by_user_id { + my ($self, $user_id) = @_; + my $apps = $self->_resolve_collection_fast( "/users/id/$user_id/apps" ); + return $apps; +} + sub get_networks { my ($self) = @_; my $networks = $self->_resolve_collection_fast( '/networks' ); diff --git a/lib/NGCP/Panel/Utils/Rtc.pm b/lib/NGCP/Panel/Utils/Rtc.pm index dba856f1ae..9e8dded8f5 100644 --- a/lib/NGCP/Panel/Utils/Rtc.pm +++ b/lib/NGCP/Panel/Utils/Rtc.pm @@ -281,6 +281,305 @@ sub modify_rtc_networks { return; } +# returns enable_rtc (true|false) and rtc_browser_token (string) +sub get_rtc_subscriber_data { + my %params = @_; + my ($prov_subs, $config, $err_code) = + @params{qw/prov_subs config err_code/}; + + if (!defined $err_code || ref $err_code ne 'CODE') { + $err_code = sub { return 0; }; + } + + unless ($prov_subs) { + return unless &{$err_code}( + "Couldn't get rtc_subscriber_data. No provisioning subscriber."); + } + + my $rtc_session = $prov_subs->rtc_session; + unless ($rtc_session) { + return {enable_rtc => 0}; # JSON::false ? + } + return {enable_rtc => 1, rtc_browser_token => 'abcde TODO'}; +} + +sub modify_subscriber_rtc { + my %params = @_; + my ($old_resource, $resource, $config, $prov_subs, $err_code) = + @params{qw/old_resource resource config prov_subs err_code/}; + + if (!defined $err_code || ref $err_code ne 'CODE') { + $err_code = sub { return 0; }; + } + + if ((!defined $old_resource) && (defined $resource)) { # newly created reseller + + # 1. enable_rtc is off -> do nothing + if (!$resource->{enable_rtc}) { + return; + } + + _create_subscriber_rtc( + resource => $resource, + config => $config, + prov_subs => $prov_subs, + err_code => $err_code); + + } elsif ((defined $old_resource) && (defined $resource)) { + + if($old_resource->{status} ne 'terminated' && + $resource->{status} eq 'terminated' && + $old_resource->{enable_rtc}) { # just terminated + + $resource->{enable_rtc} = JSON::false; + _delete_subscriber_rtc( + config => $config, + prov_subs => $prov_subs, + err_code => $err_code); + + } elsif ($old_resource->{enable_rtc} && + !$resource->{enable_rtc}) { # disable rtc + + _delete_subscriber_rtc( + config => $config, + prov_subs => $prov_subs, + err_code => $err_code); + } elsif (!$old_resource->{enable_rtc} && + $resource->{enable_rtc} && + $resource->{status} ne 'terminated') { # enable rtc + + _create_rtc_user( + resource => $resource, + config => $config, + prov_subs => $prov_subs, + err_code => $err_code); + } + } + return; +} + +sub _create_subscriber_rtc { + my %params = @_; + my ($resource, $config, $prov_subs, $err_code) = + @params{qw/resource config prov_subs err_code/}; + + my $reseller = $prov_subs->voip_subscriber->contract->contact->reseller; + unless ($reseller) { + return unless &{err_code}( + 'Creating subscriber rtc data failed. Reseller not found.'); + } + my $rtc_user = $reseller->rtc_user; + unless ($rtc_user) { + return unless &{err_code}( + 'Creating subscriber rtc data failed. Reseller has not enabled rtc.'); + } + + my $comx = NGCP::Panel::Utils::ComxAPIClient->new( + host => $config->{rtc}{schema}.'://'. + $config->{rtc}{host}.':'.$config->{rtc}{port}. + $config->{rtc}{path}, + ); + $comx->login( + $config->{rtc}{user}, + $config->{rtc}{pass}, + $config->{rtc}{host}.':'.$config->{rtc}{port}); + if ($comx->login_status->{code} != 200) { + return unless &{$err_code}( + 'Rtc Login failed. Check config settings.'); + } + + my $comx_apps = $comx->get_apps_by_user_id($rtc_user->rtc_user_id); + my $comx_app; + if ($comx_apps->{data} && @{ $comx_apps->{data} }){ + $comx_app = $comx_apps->{data}[0]; + } else { + return unless &{$err_code}( + '_create_subscriber_rtc: Could not find app.'); + } + + my $session = $comx->create_session( + $comx_app->{id}, + $rtc_user->rtc_user_id, + ); + if ($session->{code} != 201) { + return unless &{$err_code}( + 'Creating rtc session failed. Error code: ' . $session->{code}); + } + + # # 3. create relation in our db + # $prov_subs->create_related('rtc_session', { + # rtc_session_id => $session->{data}{id}, + # }); + + # # 4. create related app + # my $app = $comx->create_app( + # $reseller_name . '_app', + # $reseller_name . 'www.sipwise.com', + # $user->{data}{id}, + # ); + # if ($app->{code} != 201) { + # return unless &{$err_code}( + # 'Creating rtc app failed. Error code: ' . $app->{code}); + # } + + # # 5. create related networks + # for my $n (@{ $rtc_networks }) { + # my $n_response = $comx->create_network( + # $reseller_name . "_$n", + # $n . '-connector', + # {xms => JSON::false}, + # $user->{data}{id}, + # ); + # if ($n_response->{code} != 201) { + # return unless &{$err_code}( + # 'Creating rtc network failed. Error code: ' . $n_response->{code}); + # } + # } + # return; +} + +sub _delete_subscriber_rtc { + # my %params = @_; + # my ($config, $prov_subs, $err_code) = + # @params{qw/config prov_subs err_code/}; + + # my $comx = NGCP::Panel::Utils::ComxAPIClient->new( + # host => $config->{rtc}{schema}.'://'. + # $config->{rtc}{host}.':'.$config->{rtc}{port}. + # $config->{rtc}{path}, + # ); + # $comx->login( + # $config->{rtc}{user}, + # $config->{rtc}{pass}, + # $config->{rtc}{host}.':'.$config->{rtc}{port}); + # if ($comx->login_status->{code} != 200) { + # return unless &{$err_code}( + # 'Rtc Login failed. Check config settings.'); + # } + + # my $rtc_user = $reseller_item->rtc_user; + # if (!defined $rtc_user) { + # return unless &{$err_code}( + # 'No rtc user found in db for this reseller.'); + # } + # # app and networks are deleted automatically + # my $delete_resp = $comx->delete_user( + # $rtc_user->rtc_user_id, + # ); + # if ($delete_resp->{code} == 200) { + # $rtc_user->delete; + # } else { + # return unless &{$err_code}( + # 'Deleting rtc user failed. Error code: ' . $delete_resp->{code}); + # } + # return; +} + +sub create_rtc_session { + my %params = @_; + my ($config, $err_code, $resource, $subscriber_item) = + @params{qw/config err_code resource subscriber_item/}; + + if (!defined $err_code || ref $err_code ne 'CODE') { + $err_code = sub { return 0; }; + } + + my $reseller = $subscriber_item->contract->contact->reseller; + unless ($reseller) { + return unless &{$err_code}( + 'Creating subscriber rtc data failed. Reseller not found.'); + } + + my $rtc_user = $reseller->rtc_user; + unless ($rtc_user) { + return unless &{$err_code}( + 'Creating subscriber rtc data failed. Reseller has not enabled rtc.'); + } + + my $comx = NGCP::Panel::Utils::ComxAPIClient->new( + host => $config->{rtc}{schema}.'://'. + $config->{rtc}{host}.':'.$config->{rtc}{port}. + $config->{rtc}{path}, + ); + $comx->login( + $config->{rtc}{user}, + $config->{rtc}{pass}, + $config->{rtc}{host}.':'.$config->{rtc}{port}); + if ($comx->login_status->{code} != 200) { + return unless &{$err_code}( + 'Rtc Login failed. Check config settings.'); + } + + my $comx_apps = $comx->get_apps_by_user_id($rtc_user->rtc_user_id); + my $comx_app; + if ($comx_apps->{data} && @{ $comx_apps->{data} }){ + $comx_app = $comx_apps->{data}[0]; + } else { + return unless &{$err_code}( + 'create_rtc_session: Could not find app.'); + } + + my $comx_networks = $comx->get_networks_by_user_id($rtc_user->rtc_user_id); + my $comx_network; + if ($comx_networks->{data} && @{ $comx_networks->{data} }){ + ($comx_network) = grep { $_->{tag} eq $resource->{rtc_network_tag} } @{ $comx_networks->{data} }; + } + unless ($comx_network) { + return unless &{$err_code}( + 'create_rtc_session: Could not find network with specified tag.'); + } + + my $account = $comx->create_session_and_account( + $comx_app->{id}, + $resource->{rtc_network_tag}, + 'sip:' . $subscriber_item->username . '@' . $subscriber_item->domain->domain, + $subscriber_item->provisioning_voip_subscriber->password, + $rtc_user->rtc_user_id, + {xms => JSON::false}, + ); + if ($account->{code} != 201) { + return unless &{$err_code}( + 'Creating rtc session and account failed. Error code: ' . $account->{code}); + } + + my $rtc_session_item = $subscriber_item->provisioning_voip_subscriber->create_related('rtc_session', { + rtc_network_tag => $resource->{rtc_network_tag}, + rtc_session_id => $account->{data}{session}{id}, + }); + return $rtc_session_item; +} + +sub get_rtc_session { + my %params = @_; + my ($config, $item, $err_code) = + @params{qw/config item err_code/}; + + if (!defined $err_code || ref $err_code ne 'CODE') { + $err_code = sub { return 0; }; + } + + my $comx = NGCP::Panel::Utils::ComxAPIClient->new( + host => $config->{rtc}{schema}.'://'. + $config->{rtc}{host}.':'.$config->{rtc}{port}. + $config->{rtc}{path}, + ); + $comx->login( + $config->{rtc}{user}, + $config->{rtc}{pass}, + $config->{rtc}{host}.':'.$config->{rtc}{port}); + if ($comx->login_status->{code} != 200) { + return unless &{$err_code}( + 'Rtc Login failed. Check config settings.'); + } + + my $session = $comx->get_session($item->rtc_session_id); + if ($session->{code} != 200) { + return unless &{$err_code}( + "Couldn't find session. Error code: " . $session->{code}); + } + return $session; +} + 1; # vim: set tabstop=4 expandtab: